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