1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkBarChartActor.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #include "vtkBarChartActor.h"
16 
17 #include "vtkAxisActor2D.h"
18 #include "vtkCellArray.h"
19 #include "vtkFieldData.h"
20 #include "vtkCellData.h"
21 #include "vtkMath.h"
22 #include "vtkObjectFactory.h"
23 #include "vtkPolyData.h"
24 #include "vtkPolyDataMapper2D.h"
25 #include "vtkTextMapper.h"
26 #include "vtkTextProperty.h"
27 #include "vtkViewport.h"
28 #include "vtkWindow.h"
29 #include "vtkLegendBoxActor.h"
30 #include "vtkGlyphSource2D.h"
31 #include "vtkProperty2D.h"
32 #include <string>
33 #include <vector>
34 
35 
36 vtkStandardNewMacro(vtkBarChartActor);
37 
38 vtkCxxSetObjectMacro(vtkBarChartActor,Input,vtkDataObject);
39 vtkCxxSetObjectMacro(vtkBarChartActor,LabelTextProperty,vtkTextProperty);
40 vtkCxxSetObjectMacro(vtkBarChartActor,TitleTextProperty,vtkTextProperty);
41 
42 // PIMPL'd list of labels
43 class vtkBarLabelArray : public std::vector<std::string> {};
44 
45 
46 //----------------------------------------------------------------------------
47 // Instantiate object
vtkBarChartActor()48 vtkBarChartActor::vtkBarChartActor()
49 {
50   // Actor2D positions
51   this->PositionCoordinate->SetCoordinateSystemToNormalizedViewport();
52   this->PositionCoordinate->SetValue(0.1,0.1);
53   this->Position2Coordinate->SetCoordinateSystemToNormalizedViewport();
54   this->Position2Coordinate->SetValue(0.9, 0.8);
55   this->Position2Coordinate->SetReferenceCoordinate(nullptr);
56 
57   this->Input = nullptr;
58   this->ArrayNumber = 0;
59   this->ComponentNumber = 0;
60   this->TitleVisibility = 1;
61   this->Title = nullptr;
62   this->Labels = new vtkBarLabelArray;
63   this->BarMappers = nullptr;
64   this->BarActors = nullptr;
65   this->LabelTextProperty = vtkTextProperty::New();
66   this->LabelTextProperty->SetFontSize(12);
67   this->LabelTextProperty->SetBold(1);
68   this->LabelTextProperty->SetItalic(1);
69   this->LabelTextProperty->SetShadow(0);
70   this->LabelTextProperty->SetFontFamilyToArial();
71   this->TitleTextProperty = vtkTextProperty::New();
72   this->TitleTextProperty->ShallowCopy(this->LabelTextProperty);
73   this->TitleTextProperty->SetFontSize(24);
74   this->TitleTextProperty->SetBold(1);
75   this->TitleTextProperty->SetItalic(0);
76   this->TitleTextProperty->SetShadow(1);
77   this->TitleTextProperty->SetFontFamilyToArial();
78   this->LabelVisibility = 1;
79 
80   this->LegendVisibility = 1;
81 
82   this->LegendActor = vtkLegendBoxActor::New();
83   this->LegendActor->GetPositionCoordinate()->SetCoordinateSystemToViewport();
84   this->LegendActor->GetPosition2Coordinate()->SetCoordinateSystemToViewport();
85   this->LegendActor->GetPosition2Coordinate()->SetReferenceCoordinate(nullptr);
86   this->LegendActor->BorderOff();
87   this->LegendActor->SetNumberOfEntries(100); //initial allocation
88   this->LegendActor->SetPadding(2);
89   this->LegendActor->ScalarVisibilityOff();
90   this->GlyphSource = vtkGlyphSource2D::New();
91   this->GlyphSource->SetGlyphTypeToNone();
92   this->GlyphSource->DashOn();
93   this->GlyphSource->FilledOff();
94   this->GlyphSource->Update();
95 
96   this->YAxis = vtkAxisActor2D::New();
97   this->YAxis->GetPositionCoordinate()->SetCoordinateSystemToViewport();
98   this->YAxis->GetPosition2Coordinate()->SetCoordinateSystemToViewport();
99   this->YAxis->SetProperty(this->GetProperty());
100   this->YAxis->SizeFontRelativeToAxisOn();
101   this->YTitle = new char[1];
102   snprintf(this->YTitle,1,"%s","");
103 
104   this->PlotData = vtkPolyData::New();
105   this->PlotMapper = vtkPolyDataMapper2D::New();
106   this->PlotMapper->SetInputData(this->PlotData);
107   this->PlotActor = vtkActor2D::New();
108   this->PlotActor->SetMapper(this->PlotMapper);
109   this->TitleMapper = vtkTextMapper::New();
110   this->TitleActor = vtkActor2D::New();
111   this->TitleActor->SetMapper(this->TitleMapper);
112   this->TitleActor->GetPositionCoordinate()->SetCoordinateSystemToViewport();
113 
114   this->N = 0;
115   this->Heights = nullptr;
116   this->MinHeight =  VTK_FLOAT_MAX;
117   this->MaxHeight = -VTK_FLOAT_MAX;
118 
119   this->LowerLeft[0] = this->LowerLeft[1] = 0.0;
120   this->UpperRight[0] = this->UpperRight[1] = 0.0;
121 
122   this->LastPosition[0] =
123     this->LastPosition[1] =
124     this->LastPosition2[0] =
125     this->LastPosition2[1] = 0;
126 
127   this->P1[0] = this->P1[1] = this->P2[0] = this->P2[1] = 0.0;
128 }
129 
130 //----------------------------------------------------------------------------
~vtkBarChartActor()131 vtkBarChartActor::~vtkBarChartActor()
132 {
133   if ( this->Input )
134   {
135     this->Input->Delete();
136     this->Input = nullptr;
137   }
138 
139   delete [] this->Title;
140   this->Title = nullptr;
141 
142   delete this->Labels;
143   this->SetLabelTextProperty(nullptr);
144   this->SetTitleTextProperty(nullptr);
145 
146   this->LegendActor->Delete();
147   this->GlyphSource->Delete();
148 
149   this->Initialize();
150 
151   this->TitleMapper->Delete();
152   this->TitleMapper = nullptr;
153   this->TitleActor->Delete();
154   this->TitleActor = nullptr;
155 
156   this->YAxis->Delete();
157   delete [] this->YTitle;
158 
159   this->PlotData->Delete();
160   this->PlotMapper->Delete();
161   this->PlotActor->Delete();
162 }
163 
164 //----------------------------------------------------------------------------
165 // Free-up axes and related stuff
Initialize()166 void vtkBarChartActor::Initialize()
167 {
168   if ( this->BarActors )
169   {
170     for (int i=0; i<this->N; i++)
171     {
172       this->BarMappers[i]->Delete();
173       this->BarActors[i]->Delete();
174     }
175     delete [] this->BarMappers;
176     this->BarMappers = nullptr;
177     delete [] this->BarActors;
178     this->BarActors = nullptr;
179   }
180 
181   this->N = 0;
182   delete [] this->Heights;
183   this->Heights = nullptr;
184 }
185 
186 //----------------------------------------------------------------------------
187 // Plot scalar data for each input dataset.
RenderOverlay(vtkViewport * viewport)188 int vtkBarChartActor::RenderOverlay(vtkViewport *viewport)
189 {
190   int renderedSomething=0;
191 
192   if ( !this->BuildPlot(viewport) )
193   {
194     return 0;
195   }
196 
197   // Done rebuilding, render as appropriate.
198   if ( this->Input == nullptr || this->N <= 0 )
199   {
200     vtkErrorMacro(<< "Nothing to plot!");
201     return 0;
202   }
203 
204   if ( this->TitleVisibility )
205   {
206     renderedSomething += this->TitleActor->RenderOverlay(viewport);
207   }
208 
209   renderedSomething += this->YAxis->RenderOverlay(viewport);
210   renderedSomething += this->PlotActor->RenderOverlay(viewport);
211 
212   if ( this->LabelVisibility )
213   {
214     for (int i=0; i<this->N; i++)
215     {
216       renderedSomething += this->BarActors[i]->RenderOverlay(viewport);
217     }
218   }
219 
220   if ( this->LegendVisibility )
221   {
222     renderedSomething += this->LegendActor->RenderOverlay(viewport);
223   }
224 
225   return renderedSomething;
226 }
227 
228 //----------------------------------------------------------------------------
229 // Plot scalar data for each input dataset.
RenderOpaqueGeometry(vtkViewport * viewport)230 int vtkBarChartActor::RenderOpaqueGeometry(vtkViewport *viewport)
231 {
232   int renderedSomething=0;
233 
234   if ( !this->BuildPlot(viewport) )
235   {
236     return 0;
237   }
238 
239   // Done rebuilding, render as appropriate.
240   if ( this->Input == nullptr || this->N <= 0 )
241   {
242     vtkErrorMacro(<< "Nothing to plot!");
243     return 0;
244   }
245 
246   if ( this->TitleVisibility )
247   {
248     renderedSomething += this->TitleActor->RenderOpaqueGeometry(viewport);
249   }
250 
251   renderedSomething += this->YAxis->RenderOpaqueGeometry(viewport);
252   renderedSomething += this->PlotActor->RenderOpaqueGeometry(viewport);
253 
254   if ( this->LabelVisibility )
255   {
256     for (int i=0; i<this->N; i++)
257     {
258       renderedSomething += this->BarActors[i]->RenderOpaqueGeometry(viewport);
259     }
260   }
261 
262   if ( this->LegendVisibility )
263   {
264     renderedSomething += this->LegendActor->RenderOpaqueGeometry(viewport);
265   }
266 
267   return renderedSomething;
268 }
269 
270 //-----------------------------------------------------------------------------
271 // Description:
272 // Does this prop have some translucent polygonal geometry?
HasTranslucentPolygonalGeometry()273 vtkTypeBool vtkBarChartActor::HasTranslucentPolygonalGeometry()
274 {
275   return 0;
276 }
277 
278 //-----------------------------------------------------------------------------
BuildPlot(vtkViewport * viewport)279 int vtkBarChartActor::BuildPlot(vtkViewport *viewport)
280 {
281   // Initialize
282   vtkDebugMacro(<<"Building pie chart plot");
283 
284   // Make sure input is up to date, and that the data is the correct shape to
285   // plot.
286   if (!this->Input)
287   {
288     vtkErrorMacro(<< "Nothing to plot!");
289     return 0;
290   }
291 
292   if (!this->TitleTextProperty)
293   {
294     vtkErrorMacro(<<"Need title text property to render plot");
295     return 0;
296   }
297   if (!this->LabelTextProperty)
298   {
299     vtkErrorMacro(<<"Need label text property to render plot");
300     return 0;
301   }
302 
303   // Viewport change may not require rebuild
304   int positionsHaveChanged = 0;
305   if (viewport->GetMTime() > this->BuildTime ||
306       (viewport->GetVTKWindow() &&
307        viewport->GetVTKWindow()->GetMTime() > this->BuildTime))
308   {
309     int *lastPosition =
310       this->PositionCoordinate->GetComputedViewportValue(viewport);
311     int *lastPosition2 =
312       this->Position2Coordinate->GetComputedViewportValue(viewport);
313     if (lastPosition[0] != this->LastPosition[0] ||
314         lastPosition[1] != this->LastPosition[1] ||
315         lastPosition2[0] != this->LastPosition2[0] ||
316         lastPosition2[1] != this->LastPosition2[1] )
317     {
318       this->LastPosition[0] = lastPosition[0];
319       this->LastPosition[1] = lastPosition[1];
320       this->LastPosition2[0] = lastPosition2[0];
321       this->LastPosition2[1] = lastPosition2[1];
322       positionsHaveChanged = 1;
323     }
324   }
325 
326   // Check modified time to see whether we have to rebuild.
327   if (positionsHaveChanged ||
328       this->GetMTime() > this->BuildTime ||
329       this->Input->GetMTime() > this->BuildTime ||
330       this->LabelTextProperty->GetMTime() > this->BuildTime ||
331       this->TitleTextProperty->GetMTime() > this->BuildTime)
332   {
333     vtkDebugMacro(<<"Rebuilding plot");
334 
335     // Build axes
336     int *size = viewport->GetSize();
337     if (!this->PlaceAxes(viewport, size))
338     {
339       return 0;
340     }
341 
342     this->BuildTime.Modified();
343   } // If need to rebuild the plot
344 
345   return 1;
346 }
347 
348 //----------------------------------------------------------------------------
PlaceAxes(vtkViewport * viewport,int * vtkNotUsed (size))349 int vtkBarChartActor::PlaceAxes(vtkViewport *viewport, int *vtkNotUsed(size))
350 {
351   vtkIdType i;
352   vtkDataObject *input = this->GetInput();
353   vtkFieldData *field = input->GetFieldData();
354   double v = 0.0;
355 
356   this->Initialize();
357 
358   if ( ! field )
359   {
360     return 0;
361   }
362 
363   // Retrieve the appropriate data array
364   vtkDataArray *da = field->GetArray(this->ArrayNumber);
365   if ( ! da )
366   {
367     return 0;
368   }
369 
370   // Determine the number of independent variables
371   this->N = da->GetNumberOfTuples();
372   if ( this->N <= 0 || this->N >= VTK_ID_MAX )
373   {
374     this->N = 0;
375     vtkErrorMacro(<<"No field data to plot");
376     return 0;
377   }
378 
379   // We need to loop over the field to determine the total
380   this->Heights = new double[this->N];
381   this->MaxHeight = -VTK_FLOAT_MAX;
382   this->MinHeight =  VTK_FLOAT_MAX;
383   for (i=0; i<this->N; i++)
384   {
385     v = fabs(da->GetComponent(i,this->ComponentNumber));
386     this->Heights[i] = v;
387     this->MinHeight = (v < this->MinHeight ? v : this->MinHeight);
388     this->MaxHeight = (v > this->MaxHeight ? v : this->MaxHeight);
389   }
390   if ( this->MaxHeight > 0.0 )
391   {
392     // compress the heights into the (0.10->1.0) range for aesthetic reasons
393     // (i.e., you always want to see the minimum bar).
394     for (i=0; i<this->N; i++)
395     {
396       this->Heights[i] = 0.10 + 0.90*(this->Heights[i] - this->MinHeight) /
397         (this->MaxHeight - this->MinHeight);
398     }
399     this->MinHeight -= 0.10*(this->MaxHeight-this->MinHeight);
400   }
401 
402   // Get the location of the corners of the box; make sure they are sane
403   double *p1 = this->PositionCoordinate->GetComputedDoubleViewportValue(viewport);
404   double *p2 = this->Position2Coordinate->GetComputedDoubleViewportValue(viewport);
405   this->P1[0] = (p1[0] < p2[0] ? p1[0] : p2[0]);
406   this->P1[1] = (p1[1] < p2[1] ? p1[1] : p2[1]);
407   this->P2[0] = (p1[0] > p2[0] ? p1[0] : p2[0]);
408   this->P2[1] = (p1[1] > p2[1] ? p1[1] : p2[1]);
409   p1 = this->P1;
410   p2 = this->P2;
411 
412   // Create the bar plot.
413   // Determine the boundaries of the plot.
414   double titleSpace=0.0, legendSpace=0.0;
415   if ( this->TitleVisibility )
416   {
417     titleSpace = 0.1;
418   }
419   if ( this->LegendVisibility )
420   {
421     legendSpace = 0.15;
422   }
423 
424   double d1 = p2[0] - legendSpace*(p2[0]-p1[0]) - p1[0];
425   double d2 = p2[1] - titleSpace*(p2[1]-p1[1]) - p1[1];
426 
427   this->LowerLeft[0] = p1[0] + 25;
428   this->LowerLeft[1] = p1[1] + 15;
429   this->UpperRight[0] = p1[0] + d1 - 15;
430   this->UpperRight[1] = p1[1] + d2 - 15;
431   // Make sue layout is sane
432   if ( this->LowerLeft[0] > this->UpperRight[0] )
433   {
434     this->LowerLeft[0] = p1[0];
435     this->UpperRight[0] = p2[0];
436   }
437   if ( this->LowerLeft[1] > this->UpperRight[1] )
438   {
439     this->LowerLeft[1] = p1[1];
440     this->UpperRight[1] = p2[1];
441   }
442 
443   // First configure the y-axis
444   this->YAxis->SetProperty(this->Property);
445   this->YAxis->GetLabelTextProperty()->ShallowCopy(this->LabelTextProperty);
446   this->YAxis->SetTitle(this->YTitle);
447   this->YAxis->SetNumberOfLabels(5);
448   this->YAxis->SetRange(this->MaxHeight,this->MinHeight);
449   this->YAxis->GetPosition2Coordinate()->SetValue(this->LowerLeft[0],this->LowerLeft[1]);
450   this->YAxis->GetPositionCoordinate()->SetValue(this->LowerLeft[0],this->UpperRight[1]);
451 
452   // Now generate the bar polygons
453   this->PlotData->Initialize(); //remove old polydata, if any
454   vtkPoints *pts = vtkPoints::New();
455   pts->Allocate(this->N*4);
456   vtkCellArray *xaxis = vtkCellArray::New();
457   xaxis->Allocate(xaxis->EstimateSize(1,2));
458   vtkCellArray *polys = vtkCellArray::New();
459   polys->Allocate(polys->EstimateSize(this->N,4));
460   vtkUnsignedCharArray *colors = vtkUnsignedCharArray::New();
461   colors->SetNumberOfComponents(3);
462   this->PlotData->SetPoints(pts);
463   this->PlotData->SetLines(xaxis);
464   this->PlotData->SetPolys(polys);
465   this->PlotData->GetCellData()->SetScalars(colors);
466   colors->Delete();
467 
468   double *color, c[4];
469   vtkIdType pIds[4];
470 
471   // Create the x-axis
472   pIds[0] = pts->InsertNextPoint(this->LowerLeft[0],this->LowerLeft[1],0.0);
473   pIds[1] = pts->InsertNextPoint(this->UpperRight[0],this->LowerLeft[1],0.0);
474   xaxis->InsertNextCell(2,pIds);
475   this->GetProperty()->GetColor(c);
476   colors->InsertNextTuple3(255*c[0],255*c[1],255*c[2]);
477 
478   // Create the bars. Make sure there is some spacing.
479   char label[1024];
480   const char *str;
481   double x[3]; x[2]=0.0;
482   double space = 0.25*(this->UpperRight[0]-this->LowerLeft[0]) / this->N;
483   double barWidth = 0.75*(this->UpperRight[0]-this->LowerLeft[0]) / this->N;
484   for (i=0; i<this->N; i++)
485   {
486     x[0] = this->LowerLeft[0] + (i+1)*space + i*barWidth;
487     x[1] = this->LowerLeft[1] + 1;
488     pIds[0] = pts->InsertNextPoint(x);
489 
490     x[0] += barWidth;
491     pIds[1] = pts->InsertNextPoint(x);
492 
493     x[1] += this->Heights[i]*(this->UpperRight[1]-this->LowerLeft[1]) - 1;
494     pIds[2] = pts->InsertNextPoint(x);
495 
496     x[0] -= barWidth;
497     pIds[3] = pts->InsertNextPoint(x);
498 
499     polys->InsertNextCell(4,pIds);
500     color = this->LegendActor->GetEntryColor(i);
501     colors->InsertNextTuple3(255*color[0],255*color[1],255*color[2]);
502     this->LegendActor->SetEntrySymbol(i,this->GlyphSource->GetOutput());
503     if ( (str=this->GetBarLabel(i)) != nullptr )
504     {
505       this->LegendActor->SetEntryString(i,str);
506     }
507     else
508     {
509       snprintf(label,sizeof(label),"%d",static_cast<int>(i));
510       this->LegendActor->SetEntryString(i,label);
511     }
512   }
513 
514   // Produce labels along the bars
515   int minFontSize=1000, fontSize, tsize[2];
516   if ( this->LabelVisibility )
517   {
518     this->BarActors = new vtkActor2D* [this->N];
519     this->BarMappers = new vtkTextMapper* [this->N];
520     for (i=0; i<this->N; i++)
521     {
522       this->BarMappers[i] = vtkTextMapper::New();
523       if ( (str=this->GetBarLabel(i)) != nullptr )
524       {
525         this->BarMappers[i]->SetInput(str);
526       }
527       else
528       {
529         snprintf(label,sizeof(label),"%d",static_cast<int>(i));
530         this->BarMappers[i]->SetInput(label);
531       }
532       this->BarMappers[i]->GetTextProperty()->ShallowCopy(this->LabelTextProperty);
533       this->BarMappers[i]->GetTextProperty()->SetJustificationToCentered();
534       this->BarMappers[i]->GetTextProperty()->SetVerticalJustificationToTop();
535       tsize[0] = static_cast<int>(barWidth);
536       tsize[1] = static_cast<int>(barWidth);
537       fontSize = this->BarMappers[i]->SetConstrainedFontSize(
538         viewport, tsize[0], tsize[1]);
539       minFontSize = (fontSize < minFontSize ? fontSize : minFontSize);
540 
541       this->BarActors[i] = vtkActor2D::New();
542       this->BarActors[i]->SetMapper(this->BarMappers[i]);
543       this->BarActors[i]->GetPositionCoordinate()->
544         SetCoordinateSystemToViewport();
545       x[0] = this->LowerLeft[0] + (i+1)*space + i*barWidth + barWidth/2.0;
546       x[1] = this->LowerLeft[1]-3;
547       this->BarActors[i]->SetPosition(x);
548     }
549     //Now reset font sizes to the same value
550     for (i=0; i<this->N; i++)
551     {
552       this->BarMappers[i]->GetTextProperty()->SetFontSize(minFontSize);
553     }
554   }
555 
556   //Display the legend
557   if ( this->LegendVisibility )
558   {
559     this->LegendActor->GetProperty()->DeepCopy(this->GetProperty());
560     this->LegendActor->GetPositionCoordinate()->SetValue(
561       p1[0] + 0.85*(p2[0]-p1[0]),p1[1] + 0.20*(p2[1]-p1[1]));
562     this->LegendActor->GetPosition2Coordinate()->SetValue(
563       p2[0], p1[1] + 0.80*(p2[1]-p1[1]));
564   }
565 
566   // Build title
567   this->TitleMapper->SetInput(this->Title);
568   if (this->TitleTextProperty->GetMTime() > this->BuildTime)
569   {
570     // Shallow copy here since the justification is changed but we still
571     // want to allow actors to share the same text property, and in that case
572     // specifically allow the title and label text prop to be the same.
573     this->TitleMapper->GetTextProperty()->ShallowCopy(
574       this->TitleTextProperty);
575     this->TitleMapper->GetTextProperty()->SetJustificationToCentered();
576   }
577 
578   // We could do some caching here, but hey, that's just the title
579   tsize[0] = static_cast<int>(0.25*d1);
580   tsize[1] = static_cast<int>(0.15*d2);
581   this->TitleMapper->SetConstrainedFontSize(viewport, tsize[0], tsize[1]);
582 
583   this->TitleActor->GetPositionCoordinate()->
584     SetValue((this->LowerLeft[0]+this->UpperRight[0])/2.0,
585              this->UpperRight[1]+tsize[1]);
586   this->TitleActor->SetProperty(this->GetProperty());
587 
588   // Clean up
589   pts->Delete();
590   xaxis->Delete();
591   polys->Delete();
592 
593   return 1;
594 }
595 
596 //----------------------------------------------------------------------------
597 // Release any graphics resources that are being consumed by this actor.
598 // The parameter window could be used to determine which graphic
599 // resources to release.
ReleaseGraphicsResources(vtkWindow * win)600 void vtkBarChartActor::ReleaseGraphicsResources(vtkWindow *win)
601 {
602   this->TitleActor->ReleaseGraphicsResources(win);
603   this->LegendActor->ReleaseGraphicsResources(win);
604   this->YAxis->ReleaseGraphicsResources(win);
605   this->PlotActor->ReleaseGraphicsResources(win);
606   for (int i=0; this->BarActors && i<this->N; i++)
607   {
608     this->BarActors[i]->ReleaseGraphicsResources(win);
609   }
610 }
611 
612 //----------------------------------------------------------------------------
SetBarLabel(const int i,const char * label)613 void vtkBarChartActor::SetBarLabel(const int i, const char *label)
614 {
615   if ( i < 0 )
616   {
617     return;
618   }
619 
620   if ( static_cast<unsigned int>(i) >= this->Labels->size() )
621   {
622     this->Labels->resize(i+1);
623   }
624   (*this->Labels)[i] = std::string(label);
625   this->Modified();
626 }
627 
628 //----------------------------------------------------------------------------
GetBarLabel(int i)629 const char* vtkBarChartActor::GetBarLabel(int i)
630 {
631   if ( i < 0 || static_cast<unsigned int>(i) >= this->Labels->size())
632   {
633     return nullptr;
634   }
635 
636   return this->Labels->at(i).c_str();
637 }
638 
639 //----------------------------------------------------------------------------
SetBarColor(int i,double r,double g,double b)640 void vtkBarChartActor::SetBarColor(int i, double r, double g, double b)
641 {
642   this->LegendActor->SetEntryColor(i, r, g, b);
643 }
644 
645 //----------------------------------------------------------------------------
GetBarColor(int i)646 double *vtkBarChartActor::GetBarColor(int i)
647 {
648   return this->LegendActor->GetEntryColor(i);
649 }
650 
651 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)652 void vtkBarChartActor::PrintSelf(ostream& os, vtkIndent indent)
653 {
654   this->Superclass::PrintSelf(os,indent);
655 
656   os << indent << "Input: " << this->Input << "\n";
657 
658   os << indent << "Title: " << (this->Title ? this->Title : "(none)") << "\n";
659 
660   os << indent << "Title Visibility: "
661      << (this->TitleVisibility ? "On\n" : "Off\n");
662 
663   if (this->TitleTextProperty)
664   {
665     os << indent << "Title Text Property:\n";
666     this->TitleTextProperty->PrintSelf(os,indent.GetNextIndent());
667   }
668   else
669   {
670     os << indent << "Title Text Property: (none)\n";
671   }
672 
673   os << indent << "Label Visibility: "
674      << (this->LabelVisibility ? "On\n" : "Off\n");
675 
676   if (this->LabelTextProperty)
677   {
678     os << indent << "Label Text Property:\n";
679     this->LabelTextProperty->PrintSelf(os,indent.GetNextIndent());
680   }
681   else
682   {
683     os << indent << "Label Text Property: (none)\n";
684   }
685 
686   os << indent << "Legend Visibility: "
687      << (this->LegendVisibility ? "On\n" : "Off\n");
688 
689   os << indent << "Legend Actor: "
690      << this->LegendActor << "\n";
691   this->LegendActor->PrintSelf(os, indent.GetNextIndent());
692 
693   os << indent << "YTitle: " << (this->YTitle ? this->YTitle : "(none)") << "\n";
694 
695 }
696