1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkXYPlotActor.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 #include "vtkXYPlotActor.h"
15
16 #include "vtkAlgorithm.h"
17 #include "vtkAlgorithmOutput.h"
18 #include "vtkAppendPolyData.h"
19 #include "vtkAxisActor2D.h"
20 #include "vtkCellArray.h"
21 #include "vtkDataObjectCollection.h"
22 #include "vtkDataSetCollection.h"
23 #include "vtkFieldData.h"
24 #include "vtkDoubleArray.h"
25 #include "vtkGlyph2D.h"
26 #include "vtkGlyphSource2D.h"
27 #include "vtkIntArray.h"
28 #include "vtkLegendBoxActor.h"
29 #include "vtkMath.h"
30 #include "vtkObjectFactory.h"
31 #include "vtkPlane.h"
32 #include "vtkPlanes.h"
33 #include "vtkPointData.h"
34 #include "vtkPolyData.h"
35 #include "vtkPolyDataMapper2D.h"
36 #include "vtkProperty2D.h"
37 #include "vtkTextActor.h"
38 #include "vtkTextMapper.h"
39 #include "vtkTextProperty.h"
40 #include "vtkTrivialProducer.h"
41 #include "vtkViewport.h"
42
43 struct _xmlNode;
44 #define VTK_MAX_PLOTS 50
45
46 vtkStandardNewMacro(vtkXYPlotActor);
47
48 vtkCxxSetObjectMacro(vtkXYPlotActor,TitleTextProperty,vtkTextProperty);
49 vtkCxxSetObjectMacro(vtkXYPlotActor,AxisLabelTextProperty,vtkTextProperty);
50
51 class vtkXYPlotActorConnections: public vtkAlgorithm
52 {
53 public:
54 static vtkXYPlotActorConnections *New();
55 vtkTypeMacro(vtkXYPlotActorConnections,vtkAlgorithm);
56
vtkXYPlotActorConnections()57 vtkXYPlotActorConnections()
58 {
59 this->SetNumberOfInputPorts( 1 );
60 }
61 };
62
63 vtkStandardNewMacro(vtkXYPlotActorConnections);
64
65 //----------------------------------------------------------------------------
66 // Instantiate object
vtkXYPlotActor()67 vtkXYPlotActor::vtkXYPlotActor()
68 {
69 this->PositionCoordinate->SetCoordinateSystemToNormalizedViewport();
70 this->PositionCoordinate->SetValue( .25, .25 );
71 this->Position2Coordinate->SetValue( .5, .5 );
72
73 this->InputConnectionHolder = vtkXYPlotActorConnections::New();
74 this->SelectedInputScalars = nullptr;
75 this->SelectedInputScalarsComponent = vtkIntArray::New();
76
77 this->DataObjectInputConnectionHolder = vtkXYPlotActorConnections::New();
78
79 this->Title = nullptr;
80 this->XTitle = new char[7];
81 snprintf( this->XTitle,7,"%s","X Axis");
82
83 this->YTitleActor = vtkTextActor::New();
84 this->YTitleActor->SetInput( "Y Axis" );
85 this->YTitleActor->GetPositionCoordinate()->SetCoordinateSystemToViewport();
86 this->YTitleActor->GetPosition2Coordinate()->SetCoordinateSystemToViewport();
87
88 this->YTitlePosition = VTK_XYPLOT_Y_AXIS_HCENTER;
89 this->YTitleDelta = 0;
90
91 this->XValues = VTK_XYPLOT_INDEX;
92
93 this->NumberOfXLabels = 5;
94 this->NumberOfYLabels = 5;
95
96 this->TitleTextProperty = vtkTextProperty::New();
97 this->TitleTextProperty->SetBold( 1 );
98 this->TitleTextProperty->SetItalic( 1 );
99 this->TitleTextProperty->SetShadow( 1 );
100 this->TitleTextProperty->SetFontFamilyToArial();
101
102 this->AxisLabelTextProperty = vtkTextProperty::New();
103 this->AxisLabelTextProperty->SetBold( 0 );
104 this->AxisLabelTextProperty->SetItalic( 1 );
105 this->AxisLabelTextProperty->SetShadow( 1 );
106 this->AxisLabelTextProperty->SetFontFamilyToArial();
107
108 this->AxisTitleTextProperty = vtkTextProperty::New();
109 this->AxisTitleTextProperty->SetBold( 0 );
110 this->AxisTitleTextProperty->SetItalic( 1 );
111 this->AxisTitleTextProperty->SetShadow( 1 );
112 this->AxisTitleTextProperty->SetFontFamilyToArial();
113
114 this->XLabelFormat = new char[8];
115 snprintf( this->XLabelFormat,8,"%s","%-#6.3g");
116
117 this->YLabelFormat = new char[8];
118 snprintf( this->YLabelFormat,8,"%s","%-#6.3g");
119
120 this->Logx = 0;
121
122 this->XRange[0] = 0.;
123 this->XRange[1] = 0.;
124 this->YRange[0] = 0.;
125 this->YRange[1] = 0.;
126
127 this->Border = 5;
128 this->PlotLines = 1;
129 this->PlotPoints = 0;
130 this->PlotCurveLines = 0;
131 this->PlotCurvePoints = 0;
132 this->ExchangeAxes = 0;
133 this->ReverseXAxis = 0;
134 this->ReverseYAxis = 0;
135
136 this->TitleMapper = vtkTextMapper::New();
137 this->TitleActor = vtkActor2D::New();
138 this->TitleActor->SetMapper( this->TitleMapper );
139 this->TitleActor->GetPositionCoordinate()->SetCoordinateSystemToViewport();
140
141 this->XAxis = vtkAxisActor2D::New();
142 this->XAxis->GetPositionCoordinate()->SetCoordinateSystemToViewport();
143 this->XAxis->GetPosition2Coordinate()->SetCoordinateSystemToViewport();
144 this->XAxis->SetProperty( this->GetProperty() );
145
146 this->YAxis = vtkAxisActor2D::New();
147 this->YAxis->GetPositionCoordinate()->SetCoordinateSystemToViewport();
148 this->YAxis->GetPosition2Coordinate()->SetCoordinateSystemToViewport();
149 this->YAxis->SetProperty( this->GetProperty() );
150
151 this->NumberOfInputs = 0;
152 this->PlotData = nullptr;
153 this->PlotGlyph = nullptr;
154 this->PlotAppend = nullptr;
155 this->PlotMapper = nullptr;
156 this->PlotActor = nullptr;
157
158 this->ViewportCoordinate[0] = 0.;
159 this->ViewportCoordinate[1] = 0.;
160 this->PlotCoordinate[0] = 0.;
161 this->PlotCoordinate[1] = 0.;
162
163 this->DataObjectPlotMode = VTK_XYPLOT_COLUMN;
164 this->XComponent = vtkIntArray::New();
165 this->XComponent->SetNumberOfValues( VTK_MAX_PLOTS );
166 this->YComponent = vtkIntArray::New();
167 this->YComponent->SetNumberOfValues( VTK_MAX_PLOTS );
168
169 this->LinesOn = vtkIntArray::New();
170 this->LinesOn->SetNumberOfValues( VTK_MAX_PLOTS );
171 this->PointsOn = vtkIntArray::New();
172 this->PointsOn->SetNumberOfValues( VTK_MAX_PLOTS );
173 for ( int i=0; i<VTK_MAX_PLOTS; i++)
174 {
175 this->XComponent->SetValue( i, 0 );
176 this->YComponent->SetValue( i, 0 );
177 this->LinesOn->SetValue( i,this->PlotLines );
178 this->PointsOn->SetValue( i,this->PlotPoints );
179 }
180
181 this->Legend = 0;
182 this->LegendPosition[0] = .85;
183 this->LegendPosition[1] = .75;
184 this->LegendPosition2[0] = .15;
185 this->LegendPosition2[1] = .20;
186 this->LegendActor = vtkLegendBoxActor::New();
187 this->LegendActor->GetPositionCoordinate()->SetCoordinateSystemToViewport();
188 this->LegendActor->GetPosition2Coordinate()->SetCoordinateSystemToViewport();
189 this->LegendActor->GetPosition2Coordinate()->SetReferenceCoordinate( nullptr );
190 this->LegendActor->BorderOff();
191 this->LegendActor->SetNumberOfEntries( VTK_MAX_PLOTS ); //initial allocation
192 this->GlyphSource = vtkGlyphSource2D::New();
193 this->GlyphSource->SetGlyphTypeToNone();
194 this->GlyphSource->DashOn();
195 this->GlyphSource->FilledOff();
196 this->GlyphSource->Update();
197 this->GlyphSize = 0.020;
198
199 this->ClipPlanes = vtkPlanes::New();
200 vtkPoints* pts = vtkPoints::New();
201 pts->SetNumberOfPoints( 4 );
202 this->ClipPlanes->SetPoints( pts );
203 pts->Delete();
204 vtkDoubleArray* n = vtkDoubleArray::New();
205 n->SetNumberOfComponents( 3 );
206 n->SetNumberOfTuples( 4 );
207 this->ClipPlanes->SetNormals( n );
208 n->Delete();
209
210 // Construct the box
211 this->ChartBox = 0;
212 this->ChartBoxPolyData = vtkPolyData::New();
213 vtkPoints* points = vtkPoints::New();
214 points->SetNumberOfPoints( 4 );
215 this->ChartBoxPolyData->SetPoints( points );
216 points->Delete();
217 vtkCellArray* polys = vtkCellArray::New();
218 polys->InsertNextCell( 4 );
219 polys->InsertCellPoint( 0 );
220 polys->InsertCellPoint( 1 );
221 polys->InsertCellPoint( 2 );
222 polys->InsertCellPoint( 3 );
223 this->ChartBoxPolyData->SetPolys( polys );
224 polys->Delete();
225 this->ChartBoxMapper = vtkPolyDataMapper2D::New();
226 this->ChartBoxMapper->SetInputData( this->ChartBoxPolyData );
227 this->ChartBoxActor = vtkActor2D::New();
228 this->ChartBoxActor->SetMapper( this->ChartBoxMapper );
229
230 // Box border
231 this->ChartBorder = 0;
232 this->ChartBorderPolyData = vtkPolyData::New();
233 this->ChartBorderPolyData->SetPoints( points );
234 vtkCellArray* lines = vtkCellArray::New();
235 lines->InsertNextCell( 5 );
236 lines->InsertCellPoint( 0 );
237 lines->InsertCellPoint( 1 );
238 lines->InsertCellPoint( 2 );
239 lines->InsertCellPoint( 3 );
240 lines->InsertCellPoint( 0 );
241 this->ChartBorderPolyData->SetLines( lines );
242 lines->Delete();
243 this->ChartBorderMapper = vtkPolyDataMapper2D::New();
244 this->ChartBorderMapper->SetInputData( this->ChartBorderPolyData );
245 this->ChartBorderActor = vtkActor2D::New();
246 this->ChartBorderActor->SetMapper( this->ChartBorderMapper );
247
248 // Reference lines
249 this->ShowReferenceXLine = 0;
250 this->ShowReferenceYLine = 0;
251 this->ReferenceXValue = 0.;
252 this->ReferenceYValue = 0.;
253 points = vtkPoints::New();
254 points->SetNumberOfPoints( 4 );
255 lines = vtkCellArray::New();
256 lines->InsertNextCell( 2 );
257 lines->InsertCellPoint( 0 );
258 lines->InsertCellPoint( 1 );
259 lines->InsertNextCell( 2 );
260 lines->InsertCellPoint( 2 );
261 lines->InsertCellPoint( 3 );
262 this->ReferenceLinesPolyData = vtkPolyData::New();
263 this->ReferenceLinesPolyData->SetPoints( points );
264 this->ReferenceLinesPolyData->SetLines( lines );
265 points->Delete();
266 lines->Delete();
267 this->ReferenceLinesMapper = vtkPolyDataMapper2D::New();
268 this->ReferenceLinesMapper->SetInputData( this->ReferenceLinesPolyData );
269 this->ReferenceLinesActor = vtkActor2D::New();
270 this->ReferenceLinesActor->SetMapper( this->ReferenceLinesMapper );
271
272 this->CachedSize[0] = 0;
273 this->CachedSize[1] = 0;
274
275 this->AdjustXLabels = 1;
276 this->AdjustYLabels = 1;
277 this->AdjustTitlePosition = 1;
278 this->TitlePosition[0] = .5;
279 this->TitlePosition[1] = .9;
280 this->AdjustTitlePositionMode =
281 vtkXYPlotActor::AlignHCenter
282 | vtkXYPlotActor::AlignTop
283 | vtkXYPlotActor::AlignAxisHCenter
284 | vtkXYPlotActor::AlignAxisVCenter;
285 }
286
287 //----------------------------------------------------------------------------
~vtkXYPlotActor()288 vtkXYPlotActor::~vtkXYPlotActor()
289 {
290 // Get rid of the list of array names.
291 int num = this->InputConnectionHolder->GetNumberOfInputConnections( 0 );
292 if ( this->SelectedInputScalars )
293 {
294 for ( int i = 0; i < num; ++i )
295 {
296 delete [] this->SelectedInputScalars[i];
297 this->SelectedInputScalars[i] = nullptr;
298 }
299 delete [] this->SelectedInputScalars;
300 this->SelectedInputScalars = nullptr;
301 }
302 this->SelectedInputScalarsComponent->Delete();
303 this->SelectedInputScalarsComponent = nullptr;
304
305 // Now we can get rid of the inputs.
306 this->InputConnectionHolder->Delete();
307 this->InputConnectionHolder = nullptr;
308
309 this->DataObjectInputConnectionHolder->Delete();
310
311 this->TitleMapper->Delete();
312 this->TitleMapper = nullptr;
313 this->TitleActor->Delete();
314 this->TitleActor = nullptr;
315
316 this->SetTitle( nullptr );
317 this->SetXTitle( nullptr );
318 this->SetXLabelFormat( nullptr );
319 this->SetYLabelFormat( nullptr );
320
321 this->XAxis->Delete();
322 this->YAxis->Delete();
323
324 this->InitializeEntries();
325
326 this->LegendActor->Delete();
327 this->GlyphSource->Delete();
328 this->ClipPlanes->Delete();
329
330 this->ChartBoxActor->Delete();
331 this->ChartBoxMapper->Delete();
332 this->ChartBoxPolyData->Delete();
333
334 this->ChartBorderActor->Delete();
335 this->ChartBorderMapper->Delete();
336 this->ChartBorderPolyData->Delete();
337
338 this->ReferenceLinesActor->Delete();
339 this->ReferenceLinesMapper->Delete();
340 this->ReferenceLinesPolyData->Delete();
341
342 this->XComponent->Delete();
343 this->YComponent->Delete();
344
345 this->LinesOn->Delete();
346 this->PointsOn->Delete();
347
348 this->TitleTextProperty->Delete();
349 this->TitleTextProperty = nullptr;
350 this->AxisLabelTextProperty->Delete();
351 this->AxisLabelTextProperty = nullptr;
352 this->AxisTitleTextProperty->Delete();
353 this->AxisTitleTextProperty = nullptr;
354
355 this->YTitleActor->Delete();
356 this->YTitleActor = nullptr;
357 }
358
359 //----------------------------------------------------------------------------
InitializeEntries()360 void vtkXYPlotActor::InitializeEntries()
361 {
362 if ( this->NumberOfInputs > 0 )
363 {
364 for ( int i=0; i<this->NumberOfInputs; i++)
365 {
366 this->PlotData[i]->Delete();
367 this->PlotGlyph[i]->Delete();
368 this->PlotAppend[i]->Delete();
369 this->PlotMapper[i]->Delete();
370 this->PlotActor[i]->Delete();
371 }//for all entries
372
373 delete [] this->PlotData;
374 this->PlotData = nullptr;
375
376 delete [] this->PlotGlyph;
377 this->PlotGlyph = nullptr;
378
379 delete [] this->PlotAppend;
380 this->PlotAppend = nullptr;
381
382 delete [] this->PlotMapper;
383 this->PlotMapper = nullptr;
384
385 delete [] this->PlotActor; this->PlotActor = nullptr;
386 this->NumberOfInputs = 0;
387 }//if entries have been defined
388 }
389
390 //----------------------------------------------------------------------------
DoesConnectionMatch(int i,vtkAlgorithmOutput * in)391 bool vtkXYPlotActor::DoesConnectionMatch( int i, vtkAlgorithmOutput* in )
392 {
393 vtkAlgorithmOutput* conn =
394 this->InputConnectionHolder->GetInputConnection( 0, i );
395 if ( conn->GetProducer() == in->GetProducer() &&
396 conn->GetIndex() == in->GetIndex() )
397 {
398 return true;
399 }
400 return false;
401 }
402
403 //----------------------------------------------------------------------------
IsInputPresent(vtkAlgorithmOutput * in,const char * arrayName,int component)404 int vtkXYPlotActor::IsInputPresent( vtkAlgorithmOutput* in,
405 const char* arrayName,
406 int component )
407 {
408 int numConns = this->InputConnectionHolder->GetNumberOfInputConnections( 0 );
409 for ( int idx=0; idx<numConns; idx++)
410 {
411 if ( this->DoesConnectionMatch( idx, in ) )
412 {
413 if ( arrayName == nullptr && this->SelectedInputScalars[idx] == nullptr &&
414 component == this->SelectedInputScalarsComponent->GetValue( idx ) )
415 {
416 return idx + 1;
417 }
418 if ( arrayName != nullptr && this->SelectedInputScalars[idx] != nullptr &&
419 strcmp( arrayName, this->SelectedInputScalars[idx] ) == 0 &&
420 component == this->SelectedInputScalarsComponent->GetValue( idx ) )
421 {
422 return idx + 1;
423 }
424 }
425 }
426 return 0;
427 }
428
429 //----------------------------------------------------------------------------
AddDataSetInput(vtkDataSet * ds,const char * arrayName,int component)430 void vtkXYPlotActor::AddDataSetInput( vtkDataSet *ds,
431 const char *arrayName,
432 int component )
433 {
434 vtkTrivialProducer* tp = vtkTrivialProducer::New();
435 tp->SetOutput( ds );
436 this->AddDataSetInputConnection( tp->GetOutputPort(), arrayName, component );
437 tp->Delete();
438 }
439
440 //----------------------------------------------------------------------------
441 // Add a dataset and array to the list of data to plot.
AddDataSetInputConnection(vtkAlgorithmOutput * in,const char * arrayName,int component)442 void vtkXYPlotActor::AddDataSetInputConnection( vtkAlgorithmOutput *in,
443 const char *arrayName,
444 int component )
445 {
446 int idx, num;
447 char** newNames;
448
449 // I cannot change the input list, because the user has direct
450 // access to the collection. I cannot store the index of the array,
451 // because the index might change from render to render ...
452 // I have to store the list of string array names.
453
454 idx = this->IsInputPresent( in, arrayName, component );
455 // idx starts at 1 and goes to "NumberOfItems".
456 if ( idx != 0 )
457 {
458 return;
459 }
460
461 // The input/array/component must be a unique combination. Add it to our input list.
462
463 // Now reallocate the list of strings and add the new value.
464 num = this->InputConnectionHolder->GetNumberOfInputConnections( 0 );
465 newNames = new char*[num+1];
466 for ( idx = 0; idx < num; ++idx )
467 {
468 newNames[idx] = this->SelectedInputScalars[idx];
469 }
470 if ( arrayName == nullptr )
471 {
472 newNames[num] = nullptr;
473 }
474 else
475 {
476 newNames[num] = new char[strlen( arrayName )+1];
477 strcpy( newNames[num],arrayName );
478 }
479 delete [] this->SelectedInputScalars;
480 this->SelectedInputScalars = newNames;
481
482 // Save the component in the int array.
483 this->SelectedInputScalarsComponent->InsertValue( num, component );
484
485 // Add the data set to the collection
486 this->InputConnectionHolder->AddInputConnection( 0, in );
487
488 // In case of multiple use of a XYPlotActor the NumberOfEntries could be set
489 // to n. Then when a call to SetEntryString( n+1, bla ) was done the string was lost
490 // Need to update the number of entries for the legend actor
491 this->LegendActor->SetNumberOfEntries( this->LegendActor->GetNumberOfEntries()+1 );
492
493 this->Modified();
494 }
495
496 //----------------------------------------------------------------------------
RemoveAllDataSetInputConnections()497 void vtkXYPlotActor::RemoveAllDataSetInputConnections()
498 {
499 int idx, num;
500
501 num = this->InputConnectionHolder->GetNumberOfInputConnections( 0 );
502 this->InputConnectionHolder->RemoveAllInputs();
503
504 for ( idx = 0; idx < num; ++idx )
505 {
506 delete [] this->SelectedInputScalars[idx];
507 this->SelectedInputScalars[idx] = nullptr;
508 }
509 this->SelectedInputScalarsComponent->Reset();
510
511 this->DataObjectInputConnectionHolder->RemoveAllInputs();
512 }
513
514 //----------------------------------------------------------------------------
RemoveDataSetInput(vtkDataSet * ds,const char * arrayName,int component)515 void vtkXYPlotActor::RemoveDataSetInput( vtkDataSet *ds,
516 const char *arrayName,
517 int component )
518 {
519 int numConns = this->InputConnectionHolder->GetNumberOfInputConnections( 0 );
520 for ( int idx=0; idx<numConns; idx++)
521 {
522 vtkAlgorithmOutput* aout =
523 this->InputConnectionHolder->GetInputConnection( 0, idx );
524 vtkAlgorithm* alg = aout ? aout->GetProducer() : nullptr;
525 if ( alg )
526 {
527 if ( ds == alg->GetOutputDataObject( aout->GetIndex() ) )
528 {
529 this->RemoveDataSetInputConnection( aout, arrayName, component );
530 return;
531 }
532 }
533 }
534 }
535
536 //----------------------------------------------------------------------------
537 // Remove a dataset from the list of data to plot.
RemoveDataSetInputConnection(vtkAlgorithmOutput * in,const char * arrayName,int component)538 void vtkXYPlotActor::RemoveDataSetInputConnection( vtkAlgorithmOutput *in,
539 const char *arrayName,
540 int component )
541 {
542 // IsInputPresent returns 0 on failure, index+1 on success.
543 // Subtract 1 for the actual index.
544 int found = this->IsInputPresent( in, arrayName, component ) - 1;
545 if ( found == -1 )
546 {
547 return;
548 }
549
550 this->Modified();
551
552 int num = this->InputConnectionHolder->GetNumberOfInputConnections( 0 );
553
554 this->InputConnectionHolder->RemoveInputConnection( 0, found );
555
556 // Do not bother reallocating the SelectedInputScalars
557 // string array to make it smaller.
558 delete [] this->SelectedInputScalars[found];
559 this->SelectedInputScalars[found] = nullptr;
560 for ( int idx = found+1; idx < num; ++idx )
561 {
562 this->SelectedInputScalars[idx-1] = this->SelectedInputScalars[idx];
563 this->SelectedInputScalarsComponent->SetValue( idx-1,
564 this->SelectedInputScalarsComponent->GetValue( idx ) );
565 }
566 // Resetting the last item is not really necessary,
567 // but to be clean we do it anyway.
568 this->SelectedInputScalarsComponent->SetValue( num-1, -1 );
569 this->SelectedInputScalars[num-1] = nullptr;
570 }
571
572 //----------------------------------------------------------------------------
AddDataObjectInputConnection(vtkAlgorithmOutput * aout)573 void vtkXYPlotActor::AddDataObjectInputConnection( vtkAlgorithmOutput *aout )
574 {
575 // Return if the connection already exists
576 int numDO =
577 this->DataObjectInputConnectionHolder->GetNumberOfInputConnections( 0 );
578 for ( int i=0 ; i<numDO; i++)
579 {
580 vtkAlgorithmOutput* port =
581 this->DataObjectInputConnectionHolder->GetInputConnection( 0, i );
582 if ( port == aout )
583 {
584 return;
585 }
586 }
587
588 this->DataObjectInputConnectionHolder->AddInputConnection( aout );
589 }
590
591 //----------------------------------------------------------------------------
592 // Add a data object to the list of data to plot.
AddDataObjectInput(vtkDataObject * in)593 void vtkXYPlotActor::AddDataObjectInput( vtkDataObject *in )
594 {
595 vtkTrivialProducer* tp = vtkTrivialProducer::New();
596 tp->SetOutput( in );
597 this->AddDataObjectInputConnection( tp->GetOutputPort() );
598 tp->Delete();
599 }
600
601 //----------------------------------------------------------------------------
602 // Remove a data object from the list of data to plot.
RemoveDataObjectInputConnection(vtkAlgorithmOutput * aout)603 void vtkXYPlotActor::RemoveDataObjectInputConnection( vtkAlgorithmOutput *aout )
604 {
605 int numDO =
606 this->DataObjectInputConnectionHolder->GetNumberOfInputConnections( 0 );
607 for ( int i=0 ; i<numDO; i++)
608 {
609 vtkAlgorithmOutput* port =
610 this->DataObjectInputConnectionHolder->GetInputConnection( 0, i );
611 if ( port == aout )
612 {
613 this->DataObjectInputConnectionHolder->RemoveInputConnection( 0, i );
614 break;
615 }
616 }
617 }
618
619 //----------------------------------------------------------------------------
620 // Remove a data object from the list of data to plot.
RemoveDataObjectInput(vtkDataObject * in)621 void vtkXYPlotActor::RemoveDataObjectInput( vtkDataObject *in )
622 {
623 int numDO =
624 this->DataObjectInputConnectionHolder->GetNumberOfInputConnections( 0 );
625 for ( int i=0 ; i<numDO; i++)
626 {
627 vtkAlgorithmOutput* port =
628 this->DataObjectInputConnectionHolder->GetInputConnection( 0, i );
629 vtkAlgorithm* alg = port->GetProducer();
630 int portIdx = port->GetIndex();
631 if ( alg->GetOutputDataObject( portIdx ) == in )
632 {
633 this->DataObjectInputConnectionHolder->RemoveInputConnection( 0, i );
634 break;
635 }
636 }
637 }
638
639 //----------------------------------------------------------------------------
640 // Plot scalar data for each input dataset.
RenderOverlay(vtkViewport * viewport)641 int vtkXYPlotActor::RenderOverlay( vtkViewport *viewport )
642 {
643 int renderedSomething = 0;
644
645 // Make sure input is up to date.
646 if ( this->InputConnectionHolder->GetNumberOfInputConnections( 0 ) < 1 &&
647 this->DataObjectInputConnectionHolder->GetNumberOfInputConnections( 0 ) < 1 )
648 {
649 vtkErrorMacro(<< "Nothing to plot!");
650 return 0;
651 }
652
653 if ( this->ChartBox )
654 {
655 renderedSomething += this->ChartBoxActor->RenderOverlay( viewport );
656 }
657 if ( this->ChartBorder )
658 {
659 renderedSomething += this->ChartBorderActor->RenderOverlay( viewport );
660 }
661
662 renderedSomething += this->XAxis->RenderOverlay( viewport );
663 renderedSomething += this->YAxis->RenderOverlay( viewport );
664 if ( this->Title )
665 {
666 renderedSomething += this->TitleActor->RenderOverlay( viewport );
667 }
668 for ( int i=0; i < this->NumberOfInputs; i++)
669 {
670 renderedSomething += this->PlotActor[i]->RenderOverlay( viewport );
671 }
672 if ( this->ShowReferenceXLine || this->ShowReferenceYLine )
673 {
674 renderedSomething += this->ReferenceLinesActor->RenderOverlay( viewport );
675 }
676 if ( this->Legend )
677 {
678 renderedSomething += this->LegendActor->RenderOverlay( viewport );
679 }
680 if( this->YTitleActor )
681 {
682 renderedSomething+= this->YTitleActor->RenderOverlay( viewport );
683 }
684
685
686 return renderedSomething;
687 }
688
689 //----------------------------------------------------------------------------
690 // Plot scalar data for each input dataset.
RenderOpaqueGeometry(vtkViewport * viewport)691 int vtkXYPlotActor::RenderOpaqueGeometry( vtkViewport* viewport )
692 {
693 vtkMTimeType mtime, dsMtime;
694 vtkDataObject* dobj;
695 int numDS, numDO, renderedSomething=0;
696
697 // Initialize
698 // Make sure input is up to date.
699 numDS = this->InputConnectionHolder->GetNumberOfInputConnections( 0 );
700 numDO = this->DataObjectInputConnectionHolder->GetNumberOfInputConnections( 0 );
701 if ( numDS > 0 )
702 {
703 vtkDebugMacro(<<"Plotting input data sets");
704 mtime = 0;
705 for ( int i = 0; i < numDS; i++)
706 {
707 vtkAlgorithmOutput* port =
708 this->InputConnectionHolder->GetInputConnection( 0, i );
709 vtkAlgorithm* alg = port->GetProducer();
710 int portIdx = port->GetIndex();
711 alg->Update( portIdx );
712 dobj = alg->GetOutputDataObject( portIdx );
713 dsMtime = dobj->GetMTime();
714 if ( dsMtime > mtime )
715 {
716 mtime = dsMtime;
717 }
718 }
719 }
720 else if ( numDO > 0 )
721 {
722 vtkDebugMacro(<<"Plotting input data objects");
723 mtime = 0;
724 for ( int i=0 ; i<numDO; i++)
725 {
726 vtkAlgorithmOutput* port =
727 this->DataObjectInputConnectionHolder->GetInputConnection( 0, i );
728 vtkAlgorithm* alg = port->GetProducer();
729 int portIdx = port->GetIndex();
730 alg->Update( portIdx );
731 dobj = alg->GetOutputDataObject( portIdx );
732 dsMtime = dobj->GetMTime();
733 if ( dsMtime > mtime )
734 {
735 mtime = dsMtime;
736 }
737 }
738 }
739 else
740 {
741 vtkErrorMacro(<< "Nothing to plot!");
742 return 0;
743 }
744
745 if ( this->Title && this->Title[0] && !this->TitleTextProperty )
746 {
747 vtkErrorMacro(<< "Need a title text property to render plot title");
748 return 0;
749 }
750
751 // Check modified time to see whether we have to rebuild.
752 // Pay attention that GetMTime() has been redefined ( see below )
753
754 int *size=viewport->GetSize();
755 if ( mtime > this->BuildTime ||
756 size[0] != this->CachedSize[0] || size[1] != this->CachedSize[1] ||
757 this->GetMTime() > this->BuildTime ||
758 ( this->Title && this->Title[0] &&
759 this->TitleTextProperty->GetMTime() > this->BuildTime ) ||
760 ( this->AxisLabelTextProperty &&
761 this->AxisLabelTextProperty->GetMTime() > this->BuildTime ) ||
762 ( this->AxisTitleTextProperty &&
763 this->AxisTitleTextProperty->GetMTime() > this->BuildTime ) )
764 {
765 double range[2], yrange[2], xRange[2], yRange[2], interval, *lengths=nullptr;
766 int pos[2], pos2[2], numTicks;
767 int stringSize[2];
768 int num = ( numDS > 0 ? numDS : numDO );
769
770 vtkDebugMacro(<<"Rebuilding plot");
771 this->CachedSize[0] = size[0];
772 this->CachedSize[1] = size[1];
773
774 // manage legend
775 vtkDebugMacro(<<"Rebuilding legend");
776 if ( this->Legend )
777 {
778 int legPos[2], legPos2[2];
779 int *p1 = this->PositionCoordinate->GetComputedViewportValue( viewport );
780 int *p2 = this->Position2Coordinate->GetComputedViewportValue( viewport );
781 legPos[0] = ( int )( p1[0] + this->LegendPosition[0]*( p2[0]-p1[0] ) );
782 legPos2[0] = ( int )( legPos[0] + this->LegendPosition2[0]*( p2[0]-p1[0] ) );
783 legPos[1] = ( int )( p1[1] + this->LegendPosition[1]*( p2[1]-p1[1] ) );
784 legPos2[1] = ( int )( legPos[1] + this->LegendPosition2[1]*( p2[1]-p1[1] ) );
785
786 this->LegendActor->GetPositionCoordinate()->SetValue(
787 ( double )legPos[0], ( double )legPos[1] );
788 this->LegendActor->GetPosition2Coordinate()->SetValue(
789 ( double )legPos2[0], ( double )legPos2[1] );
790 this->LegendActor->SetNumberOfEntries( num );
791 for ( int i=0; i<num; i++)
792 {
793 if ( ! this->LegendActor->GetEntrySymbol( i ) )
794 {
795 this->LegendActor->SetEntrySymbol( i,this->GlyphSource->GetOutput() );
796 }
797 if ( ! this->LegendActor->GetEntryString( i ) )
798 {
799 char legendString[18];
800 snprintf( legendString, sizeof(legendString), "%s%d", "Curve ", i );
801 this->LegendActor->SetEntryString( i,legendString );
802 }
803 }
804
805 this->LegendActor->SetPadding( 2 );
806 this->LegendActor->GetProperty()->DeepCopy( this->GetProperty() );
807 this->LegendActor->ScalarVisibilityOff();
808 }
809
810 // Rebuid text props
811 // Perform shallow copy here since each individual axis can be
812 // accessed through the class API ( i.e. each individual axis text prop
813 // can be changed ). Therefore, we can not just assign pointers otherwise
814 // each individual axis text prop would point to the same text prop.
815
816 if ( this->AxisLabelTextProperty &&
817 this->AxisLabelTextProperty->GetMTime() > this->BuildTime )
818 {
819 if ( this->XAxis->GetLabelTextProperty() )
820 {
821 this->XAxis->GetLabelTextProperty()
822 ->ShallowCopy( this->AxisLabelTextProperty );
823 }
824 if ( this->YAxis->GetLabelTextProperty() )
825 {
826 this->YAxis->GetLabelTextProperty()
827 ->ShallowCopy( this->AxisLabelTextProperty );
828 }
829 }
830
831 if ( this->AxisTitleTextProperty &&
832 this->AxisTitleTextProperty->GetMTime() > this->BuildTime )
833 {
834 if ( this->XAxis->GetTitleTextProperty() )
835 {
836 this->XAxis->GetTitleTextProperty()
837 ->ShallowCopy( this->AxisTitleTextProperty );
838 }
839 if ( this->YAxis->GetTitleTextProperty() )
840 {
841 this->YAxis->GetTitleTextProperty()
842 ->ShallowCopy( this->AxisTitleTextProperty );
843 }
844 if ( this->YTitleActor->GetTextProperty() )
845 {
846 this->YTitleActor->GetTextProperty()
847 ->ShallowCopy( this->AxisTitleTextProperty );
848 }
849 }
850
851 // setup x-axis
852 vtkDebugMacro(<<"Rebuilding x-axis");
853
854 this->XAxis->SetTitle( this->XTitle );
855 this->XAxis->SetNumberOfLabels( this->NumberOfXLabels );
856 this->XAxis->SetProperty( this->GetProperty() );
857
858 lengths = new double[num];
859 if ( numDS > 0 ) //plotting data sets
860 {
861 this->ComputeXRange( range, lengths );
862 }
863 else
864 {
865 this->ComputeDORange( range, yrange, lengths );
866 }
867 if ( this->XRange[0] < this->XRange[1] )
868 {
869 range[0] = this->XRange[0];
870 range[1] = this->XRange[1];
871 }
872
873 if ( this->AdjustXLabels )
874 {
875 vtkAxisActor2D::ComputeRange( range, xRange, this->NumberOfXLabels,
876 numTicks, interval );
877 }
878 else
879 {
880 xRange[0] = range[0];
881 xRange[1] = range[1];
882 }
883
884 if ( !this->ExchangeAxes )
885 {
886 this->XComputedRange[0] = xRange[0];
887 this->XComputedRange[1] = xRange[1];
888 if ( this->ReverseXAxis )
889 {
890 this->XAxis->SetRange( range[1], range[0] );
891 }
892 else
893 {
894 this->XAxis->SetRange( range[0], range[1] );
895 }
896 }
897 else
898 {
899 this->XComputedRange[1] = xRange[0];
900 this->XComputedRange[0] = xRange[1];
901 if ( this->ReverseYAxis )
902 {
903 this->XAxis->SetRange( range[0], range[1] );
904 }
905 else
906 {
907 this->XAxis->SetRange( range[1], range[0] );
908 }
909 }
910
911 // setup y-axis
912 vtkDebugMacro(<<"Rebuilding y-axis");
913 this->YAxis->SetNumberOfLabels( this->NumberOfYLabels );
914
915 if ( this->YRange[0] >= this->YRange[1] )
916 {
917 if ( numDS > 0 ) //plotting data sets
918 {
919 this->ComputeYRange( yrange );
920 }
921 }
922 else
923 {
924 yrange[0] = this->YRange[0];
925 yrange[1] = this->YRange[1];
926 }
927
928 if ( this->AdjustYLabels )
929 {
930 vtkAxisActor2D::ComputeRange( yrange, yRange, this->NumberOfYLabels,
931 numTicks, interval );
932 }
933 else
934 {
935 yRange[0] = yrange[0];
936 yRange[1] = yrange[1];
937 }
938
939 if ( !this->ExchangeAxes )
940 {
941 this->YComputedRange[0] = yRange[0];
942 this->YComputedRange[1] = yRange[1];
943 if ( this->ReverseYAxis )
944 {
945 this->YAxis->SetRange( yrange[0], yrange[1] );
946 }
947 else
948 {
949 this->YAxis->SetRange( yrange[1], yrange[0] );
950 }
951 }
952 else
953 {
954 this->YComputedRange[1] = yRange[0];
955 this->YComputedRange[0] = yRange[1];
956 if ( this->ReverseXAxis )
957 {
958 this->YAxis->SetRange( yrange[1], yrange[0] );
959 }
960 else
961 {
962 this->YAxis->SetRange( yrange[0], yrange[1] );
963 }
964 }
965
966 this->PlaceAxes( viewport, size, pos, pos2 );
967
968 // Update y axis title position
969 // NB: Must be done after call to PlaceAxes() which calculates YTitleSize and YAxisTitleSize
970 if( strcmp( this->YTitleActor->GetInput(), "" ) )
971 {
972 this->YTitleActor->GetTextProperty()->SetFontSize( this->YAxisTitleSize );
973
974 int* p1 = this->PositionCoordinate->GetComputedViewportValue( viewport );
975
976 // Retrieve lower endpoint of Y axis
977 int* yaxis_p1 = this->YAxis->GetPositionCoordinate()->GetComputedViewportValue( viewport );
978
979 // Retrieve upper endpoint of Y axis
980 int* yaxis_p2 = this->YAxis->GetPosition2Coordinate()->GetComputedViewportValue( viewport );
981
982 int yaxis = yaxis_p1[1] - yaxis_p2[1];
983 int yaxis_ymiddle = ( int )( yaxis * .5 );
984 int ytitle_half_height = ( int )( this->YTitleSize[1] * .5 );
985 int ytitle_width = this->YTitleSize[0];
986 int ytitlePos[2];
987 ytitlePos[0] = 0;
988 ytitlePos[1] = 0;
989 switch( this->YTitlePosition )
990 {
991 case VTK_XYPLOT_Y_AXIS_TOP:
992 {
993 this->YTitleActor->SetOrientation( 0. );
994 // Make sure that title does not exceed actor bounds
995 int val = yaxis_p1[0] - this->YTitleDelta - ytitle_width;
996 ytitlePos[0] = val < p1[0] ? p1[0] : val;
997 ytitlePos[1] = yaxis_p1[1] + 10;
998 break;
999 }
1000 case VTK_XYPLOT_Y_AXIS_HCENTER:
1001 {
1002 this->YTitleActor->SetOrientation( 0. );
1003 // YTitleActor might exceed actor bounds
1004 ytitlePos[0] = yaxis_p1[0] - this->YTitleDelta - this->YTitleSize[0];
1005 ytitlePos[1] = ( int )( yaxis_p2[1] + yaxis_ymiddle - ytitle_half_height );
1006 break;
1007 }
1008 case VTK_XYPLOT_Y_AXIS_VCENTER:
1009 {
1010 this->YTitleActor->SetOrientation( 90. );
1011 int val = ( int )( ( yaxis - ytitle_width ) * .4 );
1012 ytitlePos[0] = yaxis_p1[0] - this->YTitleDelta;
1013 ytitlePos[1] = ytitle_width > yaxis ? yaxis_p2[1] : yaxis_p2[1] + val;
1014 break;
1015 }
1016 }
1017 this->YTitleActor->GetPositionCoordinate()->SetValue( ( double ) ytitlePos[0], ( double ) ytitlePos[1] );
1018 }
1019
1020 // manage title
1021 if ( this->Title != nullptr && this->Title[0] )
1022 {
1023 this->TitleMapper->SetInput( this->Title );
1024 if ( this->TitleTextProperty->GetMTime() > this->BuildTime )
1025 {
1026 this->TitleMapper->GetTextProperty()->ShallowCopy(
1027 this->TitleTextProperty );
1028 }
1029
1030 vtkTextMapper::SetRelativeFontSize( this->TitleMapper, viewport,
1031 size, stringSize, 0.015 );
1032
1033 if ( this->AdjustTitlePosition )
1034 {
1035 this->TitleActor->GetPositionCoordinate()->SetCoordinateSystemToViewport();
1036 double titlePos[2];
1037 switch ( this->AdjustTitlePositionMode & ( AlignLeft | AlignRight | AlignHCenter ) )
1038 {
1039 default:
1040 case AlignLeft:
1041 titlePos[0] = pos[0];
1042 break;
1043 case AlignRight:
1044 titlePos[0] = pos2[0];
1045 break;
1046 case AlignHCenter:
1047 titlePos[0] = pos[0] + .5 * ( pos2[0] - pos[0] );
1048 break;
1049 };
1050 switch ( this->AdjustTitlePositionMode & ( AlignAxisLeft | AlignAxisRight | AlignAxisHCenter ) )
1051 {
1052 case AlignAxisLeft:
1053 titlePos[0] -= stringSize[0];
1054 break;
1055 case AlignAxisRight:
1056 break;
1057 case AlignAxisHCenter:
1058 titlePos[0] -= stringSize[0] / 2;
1059 break;
1060 default:
1061 titlePos[0] -= ( this->AdjustTitlePositionMode & AlignLeft ) ? stringSize[0] : 0;
1062 break;
1063 };
1064 switch ( this->AdjustTitlePositionMode & ( AlignTop | AlignBottom | AlignVCenter ) )
1065 {
1066 default:
1067 case AlignTop:
1068 titlePos[1] = pos2[1];
1069 break;
1070 case AlignBottom:
1071 titlePos[1] = pos[1];
1072 break;
1073 case AlignVCenter:
1074 titlePos[1] = pos[1] + .5 * ( pos2[1] - pos[1] );
1075 };
1076
1077 switch ( this->AdjustTitlePositionMode & ( AlignAxisTop | AlignAxisBottom | AlignAxisVCenter ) )
1078 {
1079 case AlignAxisTop:
1080 titlePos[1] += (this->AdjustTitlePositionMode & AlignTop) ? this->Border : -this->Border;
1081 break;
1082 case AlignAxisBottom:
1083 titlePos[1] -= stringSize[1];
1084 break;
1085 case AlignAxisVCenter:
1086 titlePos[1] -= stringSize[1] / 2;
1087 break;
1088 default:
1089 titlePos[1] += ( this->AdjustTitlePositionMode & AlignTop ) ? stringSize[1] : 0;
1090 break;
1091 };
1092 this->TitleActor->GetPositionCoordinate()->SetValue( titlePos[0], titlePos[1] );
1093 //this->TitleActor->GetPositionCoordinate()->SetValue(
1094 // pos[0] + .5 * ( pos2[0] - pos[0] ) - stringSize[0] / 2.0,
1095 // pos2[1] - stringSize[1] / 2.0 );
1096 }
1097 else
1098 {
1099 this->TitleActor->GetPositionCoordinate()->SetCoordinateSystemToNormalizedViewport();
1100 this->TitleActor->GetPositionCoordinate()
1101 ->SetValue( this->TitlePosition[0], this->TitlePosition[1] );
1102 }
1103 }
1104
1105 //Border and box - may adjust spacing based on font size relationship
1106 //to the proportions relative to the border
1107 //
1108 if ( this->ChartBox || this->ChartBorder )
1109 {
1110 double doubleP1[3], doubleP2[3];
1111
1112 doubleP1[0] = static_cast<double>( pos[0] );
1113 doubleP1[1] = static_cast<double>( pos[1] );
1114 doubleP1[2] = 0.;
1115 doubleP2[0] = static_cast<double>( pos2[0] );
1116 doubleP2[1] = static_cast<double>( pos2[1] );
1117 doubleP2[2] = 0.;
1118
1119 vtkPoints *pts = this->ChartBoxPolyData->GetPoints();
1120 pts->SetPoint( 0, doubleP1 );
1121 pts->SetPoint( 1, doubleP2[0],doubleP1[1], 0.0 );
1122 pts->SetPoint( 2, doubleP2 );
1123 pts->SetPoint( 3, doubleP1[0],doubleP2[1], 0.0 );
1124
1125 this->ChartBorderActor->SetProperty( this->GetProperty() );
1126 }
1127 // Reference lines
1128 if ( this->ShowReferenceXLine || this->ShowReferenceYLine )
1129 {
1130 double doubleP1[3], doubleP2[3];
1131
1132 doubleP1[0] = static_cast<double>( pos[0] );
1133 doubleP1[1] = static_cast<double>( pos[1] );
1134 doubleP1[2] = 0.;
1135 doubleP2[0] = static_cast<double>( pos2[0] );
1136 doubleP2[1] = static_cast<double>( pos2[1] );
1137 doubleP2[2] = 0.;
1138
1139 vtkPoints *pts = this->ReferenceLinesPolyData->GetPoints();
1140 if ( this->ShowReferenceXLine &&
1141 this->ReferenceXValue >= xRange[0] &&
1142 this->ReferenceXValue < xRange[1] )
1143 {
1144 double xRefPos = doubleP1[0] + ( this->ReferenceXValue - xRange[0] ) / ( xRange[1] - xRange[0] ) * ( doubleP2[0] - doubleP1[0] );
1145 pts->SetPoint( 0, xRefPos, doubleP1[1], 0.0 );
1146 pts->SetPoint( 1, xRefPos, doubleP2[1], 0.0 );
1147 }
1148 else
1149 {
1150 pts->SetPoint( 0, doubleP1 );
1151 pts->SetPoint( 1, doubleP1 );
1152 }
1153 if ( this->ShowReferenceYLine &&
1154 this->ReferenceYValue >= yRange[0] &&
1155 this->ReferenceYValue < yRange[1] )
1156 {
1157 double yRefPos = doubleP1[1] + ( this->ReferenceYValue - yRange[0] ) / ( yRange[1] - yRange[0] )* ( doubleP2[1] - doubleP1[1] );
1158 pts->SetPoint( 2, doubleP1[0], yRefPos, 0.);
1159 pts->SetPoint( 3, doubleP2[0], yRefPos, 0.);
1160 }
1161 else
1162 {
1163 pts->SetPoint( 2, doubleP1 );
1164 pts->SetPoint( 3, doubleP1 );
1165 }
1166 // copy the color/linewidth/opacity...
1167 this->ReferenceLinesActor->SetProperty( this->GetProperty() );
1168 }
1169 vtkDebugMacro(<<"Creating Plot Data");
1170 // Okay, now create the plot data and set up the pipeline
1171 this->CreatePlotData( pos, pos2, xRange, yRange, lengths, numDS, numDO );
1172 delete [] lengths;
1173
1174 this->BuildTime.Modified();
1175
1176 }//if need to rebuild the plot
1177
1178 vtkDebugMacro(<<"Rendering Box");
1179 if ( this->ChartBox )
1180 {
1181 renderedSomething += this->ChartBoxActor->RenderOpaqueGeometry( viewport );
1182 }
1183 if ( this->ChartBorder )
1184 {
1185 renderedSomething += this->ChartBorderActor->RenderOpaqueGeometry( viewport );
1186 }
1187 if ( this->ShowReferenceXLine || this->ShowReferenceYLine )
1188 {
1189 renderedSomething += this->ReferenceLinesActor->RenderOpaqueGeometry( viewport );
1190 }
1191 vtkDebugMacro(<<"Rendering Axes");
1192 renderedSomething += this->XAxis->RenderOpaqueGeometry( viewport );
1193 renderedSomething += this->YAxis->RenderOpaqueGeometry( viewport );
1194 if( this->YTitleActor )
1195 {
1196 vtkDebugMacro(<<"Rendering ytitleactor");
1197 renderedSomething += this->YTitleActor->RenderOpaqueGeometry( viewport );
1198 }
1199 for ( int i = 0; i < this->NumberOfInputs; ++ i )
1200 {
1201 vtkDebugMacro(<<"Rendering plotactors");
1202 renderedSomething += this->PlotActor[i]->RenderOpaqueGeometry( viewport );
1203 }
1204 if ( this->Title )
1205 {
1206 vtkDebugMacro(<<"Rendering titleactors");
1207 renderedSomething += this->TitleActor->RenderOpaqueGeometry( viewport );
1208 }
1209 if ( this->Legend )
1210 {
1211 vtkDebugMacro(<<"Rendering legendeactors");
1212 renderedSomething += this->LegendActor->RenderOpaqueGeometry( viewport );
1213 }
1214
1215 return renderedSomething;
1216 }
1217
1218 //-----------------------------------------------------------------------------
1219 // Description:
1220 // Does this prop have some translucent polygonal geometry?
HasTranslucentPolygonalGeometry()1221 vtkTypeBool vtkXYPlotActor::HasTranslucentPolygonalGeometry()
1222 {
1223 return 0;
1224 }
1225
1226 //----------------------------------------------------------------------------
GetXValuesAsString()1227 const char *vtkXYPlotActor::GetXValuesAsString()
1228 {
1229 switch ( this->XValues )
1230 {
1231 case VTK_XYPLOT_INDEX:
1232 return "Index";
1233 case VTK_XYPLOT_ARC_LENGTH:
1234 return "ArcLength";
1235 case VTK_XYPLOT_NORMALIZED_ARC_LENGTH:
1236 return "NormalizedArcLength";
1237 default:
1238 return "Value";
1239 }
1240 }
1241
1242 //----------------------------------------------------------------------------
GetDataObjectPlotModeAsString()1243 const char *vtkXYPlotActor::GetDataObjectPlotModeAsString()
1244 {
1245 if ( this->DataObjectPlotMode == VTK_XYPLOT_ROW )
1246 {
1247 return "Plot Rows";
1248 }
1249 else
1250 {
1251 return "Plot Columns";
1252 }
1253 }
1254
1255 //----------------------------------------------------------------------------
1256 // Release any graphics resources that are being consumed by this actor.
1257 // The parameter window could be used to determine which graphic
1258 // resources to release.
ReleaseGraphicsResources(vtkWindow * win)1259 void vtkXYPlotActor::ReleaseGraphicsResources( vtkWindow *win )
1260 {
1261 this->TitleActor->ReleaseGraphicsResources( win );
1262 this->XAxis->ReleaseGraphicsResources( win );
1263 this->YAxis->ReleaseGraphicsResources( win );
1264 for ( int i=0; i < this->NumberOfInputs; i++)
1265 {
1266 this->PlotActor[i]->ReleaseGraphicsResources( win );
1267 }
1268 this->LegendActor->ReleaseGraphicsResources( win );
1269 if ( this->ChartBoxActor )
1270 {
1271 this->ChartBoxActor->ReleaseGraphicsResources( win );
1272 }
1273 if ( this->ChartBorderActor )
1274 {
1275 this->ChartBorderActor->ReleaseGraphicsResources( win );
1276 }
1277 if ( this->ReferenceLinesActor )
1278 {
1279 this->ReferenceLinesActor->ReleaseGraphicsResources( win );
1280 }
1281 if( this->YTitleActor )
1282 {
1283 this->YTitleActor->ReleaseGraphicsResources( win );
1284 }
1285 }
1286
1287 //----------------------------------------------------------------------------
GetMTime()1288 vtkMTimeType vtkXYPlotActor::GetMTime()
1289 {
1290 vtkMTimeType mtime, mtime2;
1291 mtime = this->vtkActor2D::GetMTime();
1292
1293 if ( this->Legend )
1294 {
1295 mtime2 = this->LegendActor->GetMTime();
1296 if ( mtime2 > mtime )
1297 {
1298 mtime = mtime2;
1299 }
1300 }
1301
1302 return mtime;
1303 }
1304
1305 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)1306 void vtkXYPlotActor::PrintSelf( ostream& os, vtkIndent indent )
1307 {
1308 vtkIndent i2 = indent.GetNextIndent();
1309 vtkAlgorithmOutput *input;
1310 char *array;
1311 int component;
1312 int idx, num;
1313
1314 this->Superclass::PrintSelf( os,indent );
1315
1316 num = this->InputConnectionHolder->GetNumberOfInputConnections( 0 );
1317 os << indent << "DataSetInputs: " << endl;
1318 for ( idx = 0; idx < num; ++idx )
1319 {
1320 input = this->InputConnectionHolder->GetInputConnection( 0, idx );
1321 array = this->SelectedInputScalars[idx];
1322 component = this->SelectedInputScalarsComponent->GetValue( ( vtkIdType )idx );
1323 if ( array == nullptr )
1324 {
1325 os << i2 << "(" << input << ") Default Scalars, Component = " << component << endl;
1326 }
1327 else
1328 {
1329 os << i2 << "(" << input << ") " << array << ", Component = " << component << endl;
1330 }
1331 }
1332
1333 os << indent << "Input DataObjects:\n";
1334 num = this->DataObjectInputConnectionHolder->GetNumberOfInputConnections( 0 );
1335 for ( idx = 0; idx < num; ++idx )
1336 {
1337 input = this->DataObjectInputConnectionHolder->GetInputConnection( 0, idx );
1338 os << i2 << input << endl;
1339 }
1340
1341 if ( this->TitleTextProperty )
1342 {
1343 os << indent << "Title Text Property:\n";
1344 this->TitleTextProperty->PrintSelf( os,indent.GetNextIndent() );
1345 }
1346 else
1347 {
1348 os << indent << "Title Text Property: ( none )\n";
1349 }
1350
1351 if ( this->AxisTitleTextProperty )
1352 {
1353 os << indent << "Axis Title Text Property:\n";
1354 this->AxisTitleTextProperty->PrintSelf( os,indent.GetNextIndent() );
1355 }
1356 else
1357 {
1358 os << indent << "Axis Title Text Property: ( none )\n";
1359 }
1360
1361 if ( this->AxisLabelTextProperty )
1362 {
1363 os << indent << "Axis Label Text Property:\n";
1364 this->AxisLabelTextProperty->PrintSelf( os,indent.GetNextIndent() );
1365 }
1366 else
1367 {
1368 os << indent << "Axis Label Text Property: ( none )\n";
1369 }
1370
1371 os << indent << "Data Object Plot Mode: " << this->GetDataObjectPlotModeAsString() << endl;
1372
1373 os << indent << "Title: " << ( this->Title ? this->Title : "( none )") << "\n";
1374 os << indent << "X Title: "
1375 << ( this->XTitle ? this->XTitle : "( none )") << "\n";
1376
1377 os << indent << "X Values: " << this->GetXValuesAsString() << endl;
1378 os << indent << "Log X Values: " << ( this->Logx ? "On\n" : "Off\n");
1379
1380 os << indent << "Plot global-points: " << ( this->PlotPoints ? "On\n" : "Off\n");
1381 os << indent << "Plot global-lines: " << ( this->PlotLines ? "On\n" : "Off\n");
1382 os << indent << "Plot per-curve points: " << ( this->PlotCurvePoints ? "On\n" : "Off\n");
1383 os << indent << "Plot per-curve lines: " << ( this->PlotCurveLines ? "On\n" : "Off\n");
1384 os << indent << "Exchange Axes: " << ( this->ExchangeAxes ? "On\n" : "Off\n");
1385 os << indent << "Reverse X Axis: " << ( this->ReverseXAxis ? "On\n" : "Off\n");
1386 os << indent << "Reverse Y Axis: " << ( this->ReverseYAxis ? "On\n" : "Off\n");
1387
1388 os << indent << "Number Of X Labels: " << this->NumberOfXLabels << "\n";
1389 os << indent << "Number Of Y Labels: " << this->NumberOfYLabels << "\n";
1390
1391 os << indent << "X Label Format: " << this->XLabelFormat << "\n";
1392 os << indent << "Y Label Format: " << this->YLabelFormat << "\n";
1393 os << indent << "Border: " << this->Border << "\n";
1394
1395 os << indent << "X Range: ";
1396 if ( this->XRange[0] >= this->XRange[1] )
1397 {
1398 os << indent << "( Automatically Computed )\n";
1399 }
1400 else
1401 {
1402 os << "(" << this->XRange[0] << ", " << this->XRange[1] << ")\n";
1403 }
1404
1405 os << indent << "Y Range: ";
1406 if ( this->XRange[0] >= this->YRange[1] )
1407 {
1408 os << indent << "( Automatically Computed )\n";
1409 }
1410 else
1411 {
1412 os << "(" << this->YRange[0] << ", " << this->YRange[1] << ")\n";
1413 }
1414
1415 os << indent << "Viewport Coordinate: ("
1416 << this->ViewportCoordinate[0] << ", "
1417 << this->ViewportCoordinate[1] << ")\n";
1418
1419 os << indent << "Plot Coordinate: ("
1420 << this->PlotCoordinate[0] << ", "
1421 << this->PlotCoordinate[1] << ")\n";
1422
1423 os << indent << "Legend: " << ( this->Legend ? "On\n" : "Off\n");
1424 os << indent << "Legend Position: ("
1425 << this->LegendPosition[0] << ", "
1426 << this->LegendPosition[1] << ")\n";
1427 os << indent << "Legend Position2: ("
1428 << this->LegendPosition2[0] << ", "
1429 << this->LegendPosition2[1] << ")\n";
1430
1431 os << indent << "Glyph Size: " << this->GlyphSize << endl;
1432
1433 os << indent << "Legend Actor:";
1434 this->LegendActor->PrintSelf( os << endl, i2 );
1435 os << indent << "Glyph Source:";
1436 this->GlyphSource->PrintSelf( os << endl, i2 );
1437
1438 os << indent << "AdjustXLabels: "
1439 << this->AdjustXLabels << endl;
1440 os << indent << "AdjustYLabels: "
1441 << this->AdjustYLabels << endl;
1442 os << indent << "AdjustTitlePosition: "
1443 << this->AdjustTitlePosition << endl;
1444 os << indent << "TitlePosition: "
1445 << this->TitlePosition[0] << " "
1446 << this->TitlePosition[1] << " "
1447 << endl;
1448 os << indent << "AdjustTitlePositionMode: "
1449 << this->AdjustTitlePositionMode << endl;
1450 os << indent << "ChartBox: " << ( this->ChartBox ? "On\n" : "Off\n");
1451 os << indent << "ChartBorder: " << ( this->ChartBorder ? "On\n" : "Off\n");
1452 os << indent << "ShowReferenceXLine: "
1453 << ( this->ShowReferenceXLine ? "On\n" : "Off\n");
1454 os << indent << "ReferenceXValue: " << this->ReferenceXValue << endl;
1455 os << indent << "ShowReferenceYLine: "
1456 << ( this->ShowReferenceYLine ? "On\n" : "Off\n");
1457 os << indent << "ReferenceYValue: " << this->ReferenceYValue << endl;
1458 }
1459
1460 //----------------------------------------------------------------------------
ComputeXRange(double range[2],double * lengths)1461 void vtkXYPlotActor::ComputeXRange( double range[2], double *lengths )
1462 {
1463 int dsNum;
1464 vtkIdType numPts, ptId, maxNum;
1465 double maxLength=0.0, xPrev[3], x[3];
1466 vtkDataSet *ds;
1467
1468 range[0] = VTK_DOUBLE_MAX;
1469 range[1] = VTK_DOUBLE_MIN;
1470
1471 int numDS = this->InputConnectionHolder->GetNumberOfInputConnections( 0 );
1472 for ( dsNum=0, maxNum=0; dsNum<numDS; dsNum++)
1473 {
1474 vtkAlgorithmOutput* port =
1475 this->InputConnectionHolder->GetInputConnection( 0, dsNum );
1476 vtkAlgorithm* alg = port->GetProducer();
1477 int portIndex = port->GetIndex();
1478 ds = vtkDataSet::SafeDownCast( alg->GetOutputDataObject( portIndex ) );
1479 numPts = ds->GetNumberOfPoints();
1480 if ( numPts == 0 )
1481 {
1482 vtkErrorMacro(<<"No scalar data to plot!");
1483 continue;
1484 }
1485
1486 if ( this->XValues != VTK_XYPLOT_INDEX )
1487 {
1488 ds->GetPoint( 0, xPrev );
1489 for ( lengths[dsNum]=0.0, ptId=0; ptId < numPts; ptId++ )
1490 {
1491 ds->GetPoint( ptId, x );
1492 switch ( this->XValues )
1493 {
1494 case VTK_XYPLOT_VALUE:
1495 if ( this->GetLogx() == 0 )
1496 {
1497 if ( x[this->XComponent->GetValue( dsNum )] < range[0] )
1498 {
1499 range[0] = x[this->XComponent->GetValue( dsNum )];
1500 }
1501 if ( x[this->XComponent->GetValue( dsNum )] > range[1] )
1502 {
1503 range[1] = x[this->XComponent->GetValue( dsNum )];
1504 }
1505 }
1506 else
1507 {
1508 //ensure range strictly > 0 for log
1509 if ( ( x[this->XComponent->GetValue( dsNum )] ) < range[0] &&
1510 ( x[this->XComponent->GetValue( dsNum )] > 0 ) )
1511 {
1512 range[0] = x[this->XComponent->GetValue( dsNum )];
1513 }
1514 if ( ( x[this->XComponent->GetValue( dsNum )] > range[1] ) &&
1515 ( x[this->XComponent->GetValue( dsNum )] > 0 ) )
1516 {
1517 range[1] = x[this->XComponent->GetValue( dsNum )];
1518 }
1519 }
1520 break;
1521 default:
1522 lengths[dsNum] += sqrt( vtkMath::Distance2BetweenPoints( x,xPrev ) );
1523 xPrev[0] = x[0]; xPrev[1] = x[1]; xPrev[2] = x[2];
1524 }
1525 }//for all points
1526 if ( lengths[dsNum] > maxLength )
1527 {
1528 maxLength = lengths[dsNum];
1529 }
1530 }//if need to visit all points
1531
1532 else //if ( this->XValues == VTK_XYPLOT_INDEX )
1533 {
1534 if ( numPts > maxNum )
1535 {
1536 maxNum = numPts;
1537 }
1538 }
1539 }//over all datasets
1540
1541 // determine the range
1542 switch ( this->XValues )
1543 {
1544 case VTK_XYPLOT_ARC_LENGTH:
1545 range[0] = 0.;
1546 range[1] = maxLength;
1547 break;
1548 case VTK_XYPLOT_NORMALIZED_ARC_LENGTH:
1549 range[0] = 0.;
1550 range[1] = 1.;
1551 break;
1552 case VTK_XYPLOT_INDEX:
1553 range[0] = 0.;
1554 range[1] = ( double )( maxNum - 1 );
1555 break;
1556 case VTK_XYPLOT_VALUE:
1557 if ( this->GetLogx() == 1 )
1558 {
1559 if ( range[0] > range[1] )
1560 {
1561 range[0] = 0;
1562 range[1] = 0;
1563 }
1564 else
1565 {
1566 range[0] = log10( range[0] );
1567 range[1] = log10( range[1] );
1568 }
1569 }
1570 break; //range computed in for loop above
1571 default:
1572 vtkErrorMacro(<< "Unknown X-Value option.");
1573 return;
1574 }
1575 }
1576
1577 //----------------------------------------------------------------------------
ComputeYRange(double range[2])1578 void vtkXYPlotActor::ComputeYRange( double range[2] )
1579 {
1580 vtkDataSet *ds;
1581 vtkDataArray *scalars;
1582 double sRange[2];
1583 int component;
1584
1585 range[0] = VTK_DOUBLE_MAX;
1586 range[1] = VTK_DOUBLE_MIN;
1587
1588 int numDS = this->InputConnectionHolder->GetNumberOfInputConnections( 0 );
1589 for ( int dsNum=0, count = 0; dsNum<numDS; dsNum++, count++)
1590 {
1591 vtkAlgorithmOutput* port =
1592 this->InputConnectionHolder->GetInputConnection( 0, dsNum );
1593 vtkAlgorithm* alg = port->GetProducer();
1594 int portIndex = port->GetIndex();
1595 ds = vtkDataSet::SafeDownCast( alg->GetOutputDataObject( portIndex ) );
1596 scalars = ds->GetPointData()->GetScalars( this->SelectedInputScalars[count] );
1597 component = this->SelectedInputScalarsComponent->GetValue( count );
1598 if ( !scalars )
1599 {
1600 vtkErrorMacro(<<"No scalar data to plot!");
1601 continue;
1602 }
1603 if ( component < 0 || component >= scalars->GetNumberOfComponents() )
1604 {
1605 vtkErrorMacro(<<"Bad component!");
1606 continue;
1607 }
1608
1609 scalars->GetRange( sRange, component );
1610 if ( sRange[0] < range[0] )
1611 {
1612 range[0] = sRange[0];
1613 }
1614
1615 if ( sRange[1] > range[1] )
1616 {
1617 range[1] = sRange[1];
1618 }
1619 }//over all datasets
1620 }
1621
1622 //----------------------------------------------------------------------------
vtkXYPlotActorGetComponent(vtkFieldData * field,vtkIdType tuple,int component,double * val)1623 static inline int vtkXYPlotActorGetComponent( vtkFieldData* field,
1624 vtkIdType tuple, int component, double* val )
1625 {
1626 int array_comp;
1627 int array_index = field->GetArrayContainingComponent( component, array_comp );
1628 if ( array_index < 0 )
1629 {
1630 return 0;
1631 }
1632 vtkDataArray* da = field->GetArray( array_index );
1633 if (!da )
1634 {
1635 // non-numeric array.
1636 return 0;
1637 }
1638 *val = da->GetComponent( tuple, array_comp );
1639 return 1;
1640 }
1641
1642 //----------------------------------------------------------------------------
ComputeDORange(double xrange[2],double yrange[2],double * lengths)1643 void vtkXYPlotActor::ComputeDORange( double xrange[2], double yrange[2],
1644 double *lengths )
1645 {
1646 int i;
1647 vtkDataObject *dobj;
1648 vtkFieldData *field;
1649 int doNum, numColumns;
1650 vtkIdType numTuples, numRows, num, ptId, maxNum;
1651 double maxLength=0.;
1652 double x = 0.;
1653 double y = 0.;
1654 double xPrev = 0.;
1655 vtkDataArray *array;
1656
1657 // NOTE: FieldData can have non-numeric arrays. However, XY plot can only
1658 // work on numeric arrays ( or vtkDataArray subclasses ).
1659
1660 xrange[0] = yrange[0] = VTK_DOUBLE_MAX;
1661 xrange[1] = yrange[1] = -VTK_DOUBLE_MAX;
1662 maxNum = 0;
1663 int numDOs =
1664 this->DataObjectInputConnectionHolder->GetNumberOfInputConnections( 0 );
1665 for ( doNum = 0; doNum < numDOs; doNum++ )
1666 {
1667 vtkAlgorithmOutput* port =
1668 this->DataObjectInputConnectionHolder->GetInputConnection( 0, doNum );
1669 vtkAlgorithm* alg = port->GetProducer();
1670 int portIdx = port->GetIndex();
1671 dobj = alg->GetOutputDataObject( portIdx );
1672
1673 lengths[doNum] = 0.;
1674 field = dobj->GetFieldData();
1675 numColumns = field->GetNumberOfComponents(); //number of "columns"
1676 // numColumns includes the components for non-numeric arrays as well.
1677 for ( numRows = VTK_ID_MAX, i=0; i<field->GetNumberOfArrays(); i++)
1678 {
1679 array = field->GetArray( i );
1680 if (!array )
1681 {
1682 // non-numeric array, skip.
1683 continue;
1684 }
1685 numTuples = array->GetNumberOfTuples();
1686 if ( numTuples < numRows )
1687 {
1688 numRows = numTuples;
1689 }
1690 }
1691
1692 num = ( this->DataObjectPlotMode == VTK_XYPLOT_ROW ?
1693 numColumns : numRows );
1694
1695 if ( this->XValues != VTK_XYPLOT_INDEX )
1696 {
1697 // gather the information to form a plot
1698 for ( ptId=0; ptId < num; ptId++ )
1699 {
1700 int status = 0;
1701
1702 if ( this->DataObjectPlotMode == VTK_XYPLOT_ROW )
1703 {
1704 // x = field->GetComponent( this->XComponent->GetValue( doNum ), ptId );
1705 status = ::vtkXYPlotActorGetComponent( field,
1706 this->XComponent->GetValue( doNum ), ptId, &x );
1707 }
1708 else //if ( this->DataObjectPlotMode == VTK_XYPLOT_COLUMN )
1709 {
1710 // x = field->GetComponent( ptId, this->XComponent->GetValue( doNum ) );
1711 status = ::vtkXYPlotActorGetComponent( field,
1712 ptId, this->XComponent->GetValue( doNum ), &x );
1713 }
1714 if (!status )
1715 {
1716 // requested component falls in a non-numeric array, skip it.
1717 continue;
1718 }
1719 if ( ptId == 0 )
1720 {
1721 xPrev = x;
1722 }
1723
1724 switch ( this->XValues )
1725 {
1726 case VTK_XYPLOT_VALUE:
1727 if ( this->GetLogx() == 0 )
1728 {
1729 if ( x < xrange[0] )
1730 {
1731 xrange[0] = x;
1732 }
1733 if ( x > xrange[1] )
1734 {
1735 xrange[1] = x;
1736 }
1737 }
1738 else //ensure positive values
1739 {
1740 if ( ( x < xrange[0] ) && ( x > 0 ) )
1741 {
1742 xrange[0] = x;
1743 }
1744 if ( x > xrange[1] && ( x > 0 ) )
1745 {
1746 xrange[1] = x;
1747 }
1748 }
1749 break;
1750 default:
1751 lengths[doNum] += fabs( x-xPrev );
1752 xPrev = x;
1753 }
1754 }//for all points
1755 if ( lengths[doNum] > maxLength )
1756 {
1757 maxLength = lengths[doNum];
1758 }
1759 }//if all data has to be visited
1760
1761 else //if ( this->XValues == VTK_XYPLOT_INDEX )
1762 {
1763 if ( num > maxNum )
1764 {
1765 maxNum = num;
1766 }
1767 }
1768
1769 // Get the y-values
1770 for ( ptId=0; ptId < num; ptId++ )
1771 {
1772 int status = 0;
1773 if ( this->DataObjectPlotMode == VTK_XYPLOT_ROW )
1774 {
1775 //y = field->GetComponent( this->YComponent->GetValue( doNum ), ptId );
1776 status = ::vtkXYPlotActorGetComponent( field,
1777 this->YComponent->GetValue( doNum ), ptId, &y );
1778 }
1779 else //if ( this->DataObjectPlotMode == VTK_XYPLOT_COLUMN )
1780 {
1781 //y = field->GetComponent( ptId, this->YComponent->GetValue( doNum ) );
1782 status = ::vtkXYPlotActorGetComponent( field,
1783 ptId, this->YComponent->GetValue( doNum ), &y );
1784 }
1785 if (!status )
1786 {
1787 // requested component falls in non-numeric array.
1788 // skip.
1789 continue;
1790 }
1791 if ( y < yrange[0] )
1792 {
1793 yrange[0] = y;
1794 }
1795 if ( y > yrange[1] )
1796 {
1797 yrange[1] = y;
1798 }
1799 }//over all y values
1800 }//over all dataobjects
1801
1802 // determine the range
1803 switch ( this->XValues )
1804 {
1805 case VTK_XYPLOT_ARC_LENGTH:
1806 xrange[0] = 0.;
1807 xrange[1] = maxLength;
1808 break;
1809 case VTK_XYPLOT_NORMALIZED_ARC_LENGTH:
1810 xrange[0] = 0.;
1811 xrange[1] = 1.;
1812 break;
1813 case VTK_XYPLOT_INDEX:
1814 xrange[0] = 0.;
1815 xrange[1] = ( double )( maxNum - 1 );
1816 break;
1817 case VTK_XYPLOT_VALUE:
1818 if ( this->GetLogx() == 1 )
1819 {
1820 xrange[0] = log10( xrange[0] );
1821 xrange[1] = log10( xrange[1] );
1822 }
1823 break;
1824 default:
1825 vtkErrorMacro(<< "Unknown X-Value option");
1826 return;
1827 }
1828 }
1829
1830 //----------------------------------------------------------------------------
CreatePlotData(int * pos,int * pos2,double xRange[2],double yRange[2],double * lengths,int numDS,int numDO)1831 void vtkXYPlotActor::CreatePlotData( int *pos, int *pos2, double xRange[2],
1832 double yRange[2], double *lengths,
1833 int numDS, int numDO )
1834 {
1835 double xyz[3]; xyz[2] = 0.;
1836 int i, numLinePts, doNum, num;
1837 vtkIdType numPts, ptId, id;
1838 double length, x[3], xPrev[3];
1839 vtkDataArray *scalars;
1840 int component;
1841 vtkDataSet *ds;
1842 vtkCellArray *lines;
1843 vtkPoints *pts;
1844 int clippingRequired = 0;
1845
1846 // Allocate resources for the polygonal plots
1847 //
1848 num = ( numDS > numDO ? numDS : numDO );
1849 this->InitializeEntries();
1850 this->NumberOfInputs = num;
1851 this->PlotData = new vtkPolyData* [num];
1852 this->PlotGlyph = new vtkGlyph2D* [num];
1853 this->PlotAppend = new vtkAppendPolyData* [num];
1854 this->PlotMapper = new vtkPolyDataMapper2D* [num];
1855 this->PlotActor = new vtkActor2D* [num];
1856 for ( i=0; i<num; i++)
1857 {
1858 this->PlotData[i] = vtkPolyData::New();
1859 this->PlotGlyph[i] = vtkGlyph2D::New();
1860 this->PlotGlyph[i]->SetInputData( this->PlotData[i] );
1861 this->PlotGlyph[i]->SetScaleModeToDataScalingOff();
1862 this->PlotAppend[i] = vtkAppendPolyData::New();
1863 this->PlotAppend[i]->AddInputData( this->PlotData[i] );
1864 if ( this->LegendActor->GetEntrySymbol( i ) != nullptr &&
1865 this->LegendActor->GetEntrySymbol( i ) != this->GlyphSource->GetOutput() )
1866 {
1867 this->PlotGlyph[i]->SetSourceData( this->LegendActor->GetEntrySymbol( i ) );
1868 this->PlotGlyph[i]->SetScaleFactor( this->ComputeGlyphScale( i,pos,pos2 ) );
1869 this->PlotAppend[i]->AddInputConnection( this->PlotGlyph[i]->GetOutputPort() );
1870 }
1871 this->PlotMapper[i] = vtkPolyDataMapper2D::New();
1872 this->PlotMapper[i]->SetInputConnection( this->PlotAppend[i]->GetOutputPort() );
1873 this->PlotMapper[i]->ScalarVisibilityOff();
1874 this->PlotActor[i] = vtkActor2D::New();
1875 this->PlotActor[i]->SetMapper( this->PlotMapper[i] );
1876 this->PlotActor[i]->GetProperty()->DeepCopy( this->GetProperty() );
1877 if ( this->LegendActor->GetEntryColor( i )[0] < 0.0 )
1878 {
1879 this->PlotActor[i]->GetProperty()->SetColor(
1880 this->GetProperty()->GetColor() );
1881 }
1882 else
1883 {
1884 this->PlotActor[i]->GetProperty()->SetColor(
1885 this->LegendActor->GetEntryColor( i ) );
1886 }
1887 }
1888
1889 // Prepare to receive data
1890 this->GenerateClipPlanes( pos,pos2 );
1891 for ( i=0; i<this->NumberOfInputs; i++)
1892 {
1893 lines = vtkCellArray::New();
1894 pts = vtkPoints::New();
1895
1896 lines->Allocate( 10,10 );
1897 pts->Allocate( 10,10 );
1898 this->PlotData[i]->SetPoints( pts );
1899 this->PlotData[i]->SetVerts( lines );
1900 this->PlotData[i]->SetLines( lines );
1901
1902 pts->Delete();
1903 lines->Delete();
1904 }
1905
1906 // Okay, for each input generate plot data. Depending on the input
1907 // we use either dataset or data object.
1908 //
1909 if ( numDS > 0 )
1910 {
1911 for ( int dsNum=0; dsNum<numDS; dsNum++)
1912 {
1913 vtkAlgorithmOutput* port =
1914 this->InputConnectionHolder->GetInputConnection( 0, dsNum );
1915 vtkAlgorithm* alg = port->GetProducer();
1916 int portIndex = port->GetIndex();
1917 ds = vtkDataSet::SafeDownCast( alg->GetOutputDataObject( portIndex ) );
1918 clippingRequired = 0;
1919 numPts = ds->GetNumberOfPoints();
1920 scalars = ds->GetPointData()->GetScalars( this->SelectedInputScalars[dsNum] );
1921 if ( !scalars )
1922 {
1923 continue;
1924 }
1925 if (scalars->GetNumberOfTuples() < numPts)
1926 {
1927 vtkErrorMacro("Number of points: " << numPts
1928 << " exceeds number of scalar tuples: "
1929 << scalars->GetNumberOfTuples());
1930 continue;
1931 }
1932 component = this->SelectedInputScalarsComponent->GetValue( dsNum );
1933 if ( component < 0 || component >= scalars->GetNumberOfComponents() )
1934 {
1935 continue;
1936 }
1937
1938 pts = this->PlotData[dsNum]->GetPoints();
1939 lines = this->PlotData[dsNum]->GetLines();
1940 lines->InsertNextCell( 0 ); //update the count later
1941
1942 ds->GetPoint( 0, xPrev );
1943 for ( numLinePts=0, length=0.0, ptId=0; ptId < numPts; ptId++ )
1944 {
1945 xyz[1] = scalars->GetComponent( ptId, component );
1946 ds->GetPoint( ptId, x );
1947 switch ( this->XValues )
1948 {
1949 case VTK_XYPLOT_NORMALIZED_ARC_LENGTH:
1950 length += sqrt( vtkMath::Distance2BetweenPoints( x,xPrev ) );
1951 xyz[0] = length / lengths[dsNum];
1952 xPrev[0] = x[0]; xPrev[1] = x[1]; xPrev[2] = x[2];
1953 break;
1954 case VTK_XYPLOT_INDEX:
1955 xyz[0] = ( double )ptId;
1956 break;
1957 case VTK_XYPLOT_ARC_LENGTH:
1958 length += sqrt( vtkMath::Distance2BetweenPoints( x,xPrev ) );
1959 xyz[0] = length;
1960 xPrev[0] = x[0]; xPrev[1] = x[1]; xPrev[2] = x[2];
1961 break;
1962 case VTK_XYPLOT_VALUE:
1963 xyz[0] = x[this->XComponent->GetValue( dsNum )];
1964 break;
1965 default:
1966 vtkErrorMacro(<< "Unknown X-Component option");
1967 }
1968
1969 if ( this->GetLogx() == 1 )
1970 {
1971 if ( xyz[0] > 0 )
1972 {
1973 xyz[0] = log10( xyz[0] );
1974 // normalize and position
1975 if ( xyz[0] < xRange[0] || xyz[0] > xRange[1] ||
1976 xyz[1] < yRange[0] || xyz[1] > yRange[1] )
1977 {
1978 clippingRequired = 1;
1979 }
1980
1981 numLinePts++;
1982 xyz[0] = pos[0] +
1983 ( xyz[0]-xRange[0] )/( xRange[1]-xRange[0] )*( pos2[0]-pos[0] );
1984 xyz[1] = pos[1] +
1985 ( xyz[1]-yRange[0] )/( yRange[1]-yRange[0] )*( pos2[1]-pos[1] );
1986 id = pts->InsertNextPoint( xyz );
1987 lines->InsertCellPoint( id );
1988 }
1989 }
1990 else
1991 {
1992 // normalize and position
1993 if ( xyz[0] < xRange[0] || xyz[0] > xRange[1] ||
1994 xyz[1] < yRange[0] || xyz[1] > yRange[1] )
1995 {
1996 clippingRequired = 1;
1997 }
1998
1999 numLinePts++;
2000 xyz[0] = pos[0] +
2001 ( xyz[0]-xRange[0] )/( xRange[1]-xRange[0] )*( pos2[0]-pos[0] );
2002 xyz[1] = pos[1] +
2003 ( xyz[1]-yRange[0] )/( yRange[1]-yRange[0] )*( pos2[1]-pos[1] );
2004 id = pts->InsertNextPoint( xyz );
2005 lines->InsertCellPoint( id );
2006 }
2007 }//for all input points
2008
2009 lines->UpdateCellCount( numLinePts );
2010 if ( clippingRequired )
2011 {
2012 this->ClipPlotData( pos,pos2,this->PlotData[dsNum] );
2013 }
2014 }//loop over all input data sets
2015 }//if plotting datasets
2016
2017 else //plot data from data objects
2018 {
2019 vtkDataObject *dobj;
2020 int numColumns;
2021 vtkIdType numRows, numTuples;
2022 vtkDataArray *array;
2023 vtkFieldData *field;
2024 int numDOs =
2025 this->DataObjectInputConnectionHolder->GetNumberOfInputConnections( 0 );
2026 for ( doNum = 0; doNum < numDOs; doNum++ )
2027 {
2028 vtkAlgorithmOutput* port =
2029 this->DataObjectInputConnectionHolder->GetInputConnection( 0, doNum );
2030 vtkAlgorithm* alg = port->GetProducer();
2031 int portIdx = port->GetIndex();
2032 dobj = alg->GetOutputDataObject( portIdx );
2033
2034 // determine the shape of the field
2035 field = dobj->GetFieldData();
2036 numColumns = field->GetNumberOfComponents(); //number of "columns"
2037 // numColumns also includes non-numeric array components.
2038 for ( numRows = VTK_ID_MAX, i=0; i<field->GetNumberOfArrays(); i++)
2039 {
2040 array = field->GetArray( i );
2041 if (!array )
2042 {
2043 // skip non-numeric arrays.
2044 continue;
2045 }
2046 numTuples = array->GetNumberOfTuples();
2047 if ( numTuples < numRows )
2048 {
2049 numRows = numTuples;
2050 }
2051 }
2052
2053 pts = this->PlotData[doNum]->GetPoints();
2054 lines = this->PlotData[doNum]->GetLines();
2055 lines->InsertNextCell( 0 ); //update the count later
2056
2057 numPts = ( this->DataObjectPlotMode == VTK_XYPLOT_ROW ?
2058 numColumns : numRows );
2059
2060 // gather the information to form a plot
2061 for ( numLinePts=0, length=0.0, ptId=0; ptId < numPts; ptId++ )
2062 {
2063 int status1, status2;
2064 if ( this->DataObjectPlotMode == VTK_XYPLOT_ROW )
2065 {
2066 //x[0] = field->GetComponent( this->XComponent->GetValue( doNum ),ptId );
2067 //xyz[1] = field->GetComponent( this->YComponent->GetValue( doNum ),ptId );
2068 status1 = ::vtkXYPlotActorGetComponent( field,
2069 this->XComponent->GetValue( doNum ), ptId, &x[0] );
2070 status2 = ::vtkXYPlotActorGetComponent( field,
2071 this->YComponent->GetValue( doNum ), ptId, &xyz[1] );
2072 }
2073 else //if ( this->DataObjectPlotMode == VTK_XYPLOT_COLUMN )
2074 {
2075 //x[0] = field->GetComponent( ptId, this->XComponent->GetValue( doNum ) );
2076 //xyz[1] = field->GetComponent( ptId, this->YComponent->GetValue( doNum ) );
2077
2078 status1 = ::vtkXYPlotActorGetComponent( field,
2079 ptId, this->XComponent->GetValue( doNum ), &x[0] );
2080
2081 if (!status1 )
2082 {
2083 vtkWarningMacro(<< this->XComponent->GetValue( doNum ) << " is a non-numeric component.");
2084 }
2085
2086 status2 = ::vtkXYPlotActorGetComponent( field,
2087 ptId, this->YComponent->GetValue( doNum ), &xyz[1] );
2088
2089 if (!status2 )
2090 {
2091 vtkWarningMacro(<< this->YComponent->GetValue( doNum ) << " is a non-numeric component.");
2092 }
2093 }
2094 if (!status1 || !status2 )
2095 {
2096 // component is non-numeric.
2097 // Skip it.
2098 continue;
2099 }
2100
2101 switch ( this->XValues )
2102 {
2103 case VTK_XYPLOT_NORMALIZED_ARC_LENGTH:
2104 length += fabs( x[0]-xPrev[0] );
2105 xyz[0] = length / lengths[doNum];
2106 xPrev[0] = x[0];
2107 break;
2108 case VTK_XYPLOT_INDEX:
2109 xyz[0] = ( double )ptId;
2110 break;
2111 case VTK_XYPLOT_ARC_LENGTH:
2112 length += fabs( x[0]-xPrev[0] );
2113 xyz[0] = length;
2114 xPrev[0] = x[0];
2115 break;
2116 case VTK_XYPLOT_VALUE:
2117 xyz[0] = x[0];
2118 break;
2119 default:
2120 vtkErrorMacro(<< "Unknown X-Value option");
2121 }
2122
2123 if ( this->GetLogx() == 1 )
2124 {
2125 if ( xyz[0] > 0 )
2126 {
2127 xyz[0] = log10( xyz[0] );
2128 // normalize and position
2129 if ( xyz[0] < xRange[0] || xyz[0] > xRange[1] ||
2130 xyz[1] < yRange[0] || xyz[1] > yRange[1] )
2131 {
2132 clippingRequired = 1;
2133 }
2134 numLinePts++;
2135 xyz[0] = pos[0] +
2136 ( xyz[0]-xRange[0] )/( xRange[1]-xRange[0] )*( pos2[0]-pos[0] );
2137 xyz[1] = pos[1] +
2138 ( xyz[1]-yRange[0] )/( yRange[1]-yRange[0] )*( pos2[1]-pos[1] );
2139 id = pts->InsertNextPoint( xyz );
2140 lines->InsertCellPoint( id );
2141 }
2142 }
2143 else
2144 {
2145 // normalize and position
2146 if ( xyz[0] < xRange[0] || xyz[0] > xRange[1] ||
2147 xyz[1] < yRange[0] || xyz[1] > yRange[1] )
2148 {
2149 clippingRequired = 1;
2150 }
2151 numLinePts++;
2152 xyz[0] = pos[0] +
2153 ( xyz[0]-xRange[0] )/( xRange[1]-xRange[0] )*( pos2[0]-pos[0] );
2154 xyz[1] = pos[1] +
2155 ( xyz[1]-yRange[0] )/( yRange[1]-yRange[0] )*( pos2[1]-pos[1] );
2156 id = pts->InsertNextPoint( xyz );
2157 lines->InsertCellPoint( id );
2158 }
2159 }//for all input points
2160
2161 lines->UpdateCellCount( numLinePts );
2162 if ( clippingRequired )
2163 {
2164 this->ClipPlotData( pos,pos2,this->PlotData[doNum] );
2165 }
2166 }//loop over all input data sets
2167 }
2168
2169 // Remove points/lines as directed by the user
2170 for ( i = 0; i < num; i++)
2171 {
2172 if (!this->PlotCurveLines )
2173 {
2174 if ( !this->PlotLines )
2175 {
2176 this->PlotData[i]->SetLines( nullptr );
2177 }
2178 }
2179 else
2180 {
2181 if ( this->GetPlotLines( i ) == 0 )
2182 {
2183 this->PlotData[i]->SetLines( nullptr );
2184 }
2185 }
2186
2187 if (!this->PlotCurvePoints )
2188 {
2189 if ( !this->PlotPoints || ( this->LegendActor->GetEntrySymbol( i ) &&
2190 this->LegendActor->GetEntrySymbol( i ) !=
2191 this->GlyphSource->GetOutput() ) )
2192 {
2193 this->PlotData[i]->SetVerts( nullptr );
2194 }
2195 }
2196 else
2197 {
2198 if ( this->GetPlotPoints( i ) == 0 ||
2199 ( this->LegendActor->GetEntrySymbol( i ) &&
2200 this->LegendActor->GetEntrySymbol( i ) !=
2201 this->GlyphSource->GetOutput() ) )
2202 {
2203 this->PlotData[i]->SetVerts( nullptr );
2204 }
2205 }
2206 }
2207 }
2208
2209 //----------------------------------------------------------------------------
2210 // Position the axes taking into account the expected padding due to labels
2211 // and titles. We want the result to fit in the box specified. This method
2212 // knows something about how the vtkAxisActor2D functions, so it may have
2213 // to change if that class changes dramatically.
2214 //
PlaceAxes(vtkViewport * viewport,int * size,int pos[2],int pos2[2])2215 void vtkXYPlotActor::PlaceAxes( vtkViewport *viewport, int *size,
2216 int pos[2], int pos2[2] )
2217 {
2218 int titleSizeX[2], titleSizeY[2], labelSizeX[2], labelSizeY[2];
2219 double labelFactorX, labelFactorY;
2220 double fontFactorX, fontFactorY;
2221 double tickOffsetX, tickOffsetY;
2222 double tickLengthX, tickLengthY;
2223
2224 vtkAxisActor2D *axisX;
2225 vtkAxisActor2D *axisY;
2226
2227 char str1[512], str2[512];
2228
2229 if ( this->ExchangeAxes )
2230 {
2231 axisX = this->YAxis;
2232 axisY = this->XAxis;
2233 }
2234 else
2235 {
2236 axisX = this->XAxis;
2237 axisY = this->YAxis;
2238 }
2239
2240 fontFactorY = axisY->GetFontFactor();
2241 fontFactorX = axisX->GetFontFactor();
2242
2243 labelFactorY = axisY->GetLabelFactor();
2244 labelFactorX = axisX->GetLabelFactor();
2245
2246 // Create a dummy text mapper for getting font sizes
2247 vtkTextMapper *textMapper = vtkTextMapper::New();
2248 vtkTextProperty *tprop = textMapper->GetTextProperty();
2249
2250 // Get the location of the corners of the box
2251 int *p1 = this->PositionCoordinate->GetComputedViewportValue( viewport );
2252 int *p2 = this->Position2Coordinate->GetComputedViewportValue( viewport );
2253
2254 // Estimate the padding around the X and Y axes
2255 tprop->ShallowCopy( axisX->GetTitleTextProperty() );
2256 textMapper->SetInput( axisX->GetTitle() );
2257 vtkTextMapper::SetRelativeFontSize( textMapper, viewport, size, titleSizeX, 0.015*fontFactorX );
2258
2259 tprop->ShallowCopy( axisY->GetTitleTextProperty() );
2260 textMapper->SetInput( axisY->GetTitle() );
2261 vtkTextMapper::SetRelativeFontSize( textMapper, viewport, size, titleSizeY, 0.015*fontFactorY );
2262
2263 // Retrieve X axis title font
2264 tprop->ShallowCopy( axisX->GetTitleTextProperty() );
2265 // Calculate string length from YTitleActor,
2266 // + 1 for the case where there is only one character
2267 // + 1 for the final \0
2268 int len = int( ( strlen( YTitleActor->GetInput() ) + 1 ) * .5 ) + 1;
2269 char* tmp = new char[len];
2270 switch( this->YTitlePosition )
2271 {
2272 case VTK_XYPLOT_Y_AXIS_TOP:
2273 snprintf( tmp, len, "%s", YTitleActor->GetInput() );
2274 textMapper->SetInput( tmp );
2275 break;
2276 case VTK_XYPLOT_Y_AXIS_HCENTER:
2277 textMapper->SetInput( YTitleActor->GetInput() );
2278 break;
2279 case VTK_XYPLOT_Y_AXIS_VCENTER:
2280 // Create a dummy title to ensure that the added YTitleActor is visible
2281 textMapper->SetInput("AABB");
2282 break;
2283 }
2284 delete [] tmp;
2285 this->YAxisTitleSize = vtkTextMapper::SetRelativeFontSize( textMapper, viewport, size, titleSizeY, 0.015*fontFactorY );
2286
2287 this->YTitleSize[0] = titleSizeY[0];
2288 this->YTitleSize[1] = titleSizeY[1];
2289
2290 // At this point the thing to do would be to actually ask the Y axis
2291 // actor to return the largest label.
2292 // In the meantime, let's try with the min and max
2293 snprintf( str1, sizeof(str1), axisY->GetLabelFormat(), axisY->GetAdjustedRange()[0] );
2294 snprintf( str2, sizeof(str2), axisY->GetLabelFormat(), axisY->GetAdjustedRange()[1] );
2295 tprop->ShallowCopy( axisY->GetLabelTextProperty() );
2296 textMapper->SetInput( strlen( str1 ) > strlen( str2 ) ? str1 : str2 );
2297 vtkTextMapper::SetRelativeFontSize( textMapper, viewport, size, labelSizeY, 0.015*labelFactorY*fontFactorY );
2298
2299 // We do only care of the height of the label in the X axis, so let's
2300 // use the min for example
2301 snprintf( str1, sizeof(str1), axisX->GetLabelFormat(), axisX->GetAdjustedRange()[0] );
2302 tprop->ShallowCopy( axisX->GetLabelTextProperty() );
2303 textMapper->SetInput( str1 );
2304 vtkTextMapper::SetRelativeFontSize( textMapper, viewport, size, labelSizeX, 0.015*labelFactorX*fontFactorX );
2305
2306 tickOffsetX = axisX->GetTickOffset();
2307 tickOffsetY = axisY->GetTickOffset();
2308 tickLengthX = axisX->GetTickLength();
2309 tickLengthY = axisY->GetTickLength();
2310
2311 // Okay, estimate the size
2312 pos[0] = ( int ) ( p1[0] + titleSizeY[0] + 2.0 * tickOffsetY + tickLengthY +
2313 labelSizeY[0] + this->Border );
2314
2315 pos[1] = ( int ) ( p1[1] + titleSizeX[1] + 2.0 * tickOffsetX + tickLengthX +
2316 labelSizeX[1] + this->Border );
2317
2318 pos2[0] = ( int ) ( p2[0] - labelSizeY[0] / 2 - tickOffsetY - this->Border );
2319
2320 pos2[1] = ( int ) ( p2[1] - labelSizeX[1] / 2 - tickOffsetX - this->Border );
2321
2322 // Save estimated axis size to avoid recomputing of YTitleActor displacement
2323 if( this->YTitlePosition == VTK_XYPLOT_Y_AXIS_TOP )
2324 {
2325 this->YTitleDelta = ( int ) ( 2 * tickOffsetY + tickLengthY + this->Border );
2326 }
2327 else
2328 {
2329 this->YTitleDelta = ( int ) ( 2 * tickOffsetY + tickLengthY + .75 * labelSizeY[0] + this->Border );
2330 }
2331
2332 // Now specify the location of the axes
2333 axisX->GetPositionCoordinate()->SetValue( ( double ) pos[0], ( double ) pos[1] );
2334 axisX->GetPosition2Coordinate()->SetValue( ( double ) pos2[0], ( double ) pos[1] );
2335 axisY->GetPositionCoordinate()->SetValue( ( double ) pos[0], ( double ) pos2[1] );
2336 axisY->GetPosition2Coordinate()->SetValue( ( double ) pos[0], ( double ) pos[1] );
2337
2338 textMapper->Delete();
2339 }
2340
2341 //----------------------------------------------------------------------------
ViewportToPlotCoordinate(vtkViewport * viewport,double & u,double & v)2342 void vtkXYPlotActor::ViewportToPlotCoordinate( vtkViewport *viewport, double &u, double &v )
2343 {
2344 int *p0, *p1, *p2;
2345
2346 // XAxis, YAxis are in viewport coordinates already
2347 p0 = this->XAxis->GetPositionCoordinate()->GetComputedViewportValue( viewport );
2348 p1 = this->XAxis->GetPosition2Coordinate()->GetComputedViewportValue( viewport );
2349 p2 = this->YAxis->GetPositionCoordinate()->GetComputedViewportValue( viewport );
2350
2351 u = ( ( u - p0[0] ) / ( double )( p1[0] - p0[0] ) )
2352 *( this->XComputedRange[1] - this->XComputedRange[0] )
2353 + this->XComputedRange[0];
2354 v = ( ( v - p0[1] ) / ( double )( p2[1] - p0[1] ) )
2355 *( this->YComputedRange[1] - this->YComputedRange[0] )
2356 + this->YComputedRange[0];
2357 }
2358
2359 //----------------------------------------------------------------------------
PlotToViewportCoordinate(vtkViewport * viewport,double & u,double & v)2360 void vtkXYPlotActor::PlotToViewportCoordinate( vtkViewport *viewport,
2361 double &u, double &v )
2362 {
2363 int *p0, *p1, *p2;
2364
2365 // XAxis, YAxis are in viewport coordinates already
2366 p0 = this->XAxis->GetPositionCoordinate()->GetComputedViewportValue( viewport );
2367 p1 = this->XAxis->GetPosition2Coordinate()->GetComputedViewportValue( viewport );
2368 p2 = this->YAxis->GetPositionCoordinate()->GetComputedViewportValue( viewport );
2369
2370 u = ( ( ( u - this->XComputedRange[0] )
2371 / ( this->XComputedRange[1] - this->XComputedRange[0] ) )
2372 * ( double )( p1[0] - p0[0] ) ) + p0[0];
2373 v = ( ( ( v - this->YComputedRange[0] )
2374 / ( this->YComputedRange[1] - this->YComputedRange[0] ) )
2375 * ( double )( p2[1] - p0[1] ) ) + p0[1];
2376 }
2377
2378 //----------------------------------------------------------------------------
ViewportToPlotCoordinate(vtkViewport * viewport)2379 void vtkXYPlotActor::ViewportToPlotCoordinate( vtkViewport *viewport )
2380 {
2381 this->ViewportToPlotCoordinate( viewport,
2382 this->ViewportCoordinate[0],
2383 this->ViewportCoordinate[1] );
2384 }
2385
2386 //----------------------------------------------------------------------------
PlotToViewportCoordinate(vtkViewport * viewport)2387 void vtkXYPlotActor::PlotToViewportCoordinate( vtkViewport *viewport )
2388 {
2389 this->PlotToViewportCoordinate( viewport,
2390 this->PlotCoordinate[0],
2391 this->PlotCoordinate[1] );
2392 }
2393
2394 //----------------------------------------------------------------------------
IsInPlot(vtkViewport * viewport,double u,double v)2395 int vtkXYPlotActor::IsInPlot( vtkViewport *viewport, double u, double v )
2396 {
2397 int *p0, *p1, *p2;
2398
2399 // Bounds of the plot are based on the axes...
2400 p0 = this->XAxis->GetPositionCoordinate()->GetComputedViewportValue( viewport );
2401 p1 = this->XAxis->GetPosition2Coordinate()->GetComputedViewportValue( viewport );
2402 p2 = this->YAxis->GetPositionCoordinate()->GetComputedViewportValue( viewport );
2403
2404 if ( u >= p0[0] && u <= p1[0] && v >= p0[1] && v <= p2[1] )
2405 {
2406 return 1;
2407 }
2408
2409 return 0;
2410 }
2411
2412 //----------------------------------------------------------------------------
SetPlotLines(int i,int isOn)2413 void vtkXYPlotActor::SetPlotLines( int i, int isOn )
2414 {
2415 i = ( i < 0 ? 0 : ( i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i ) );
2416 int val = this->LinesOn->GetValue( i );
2417 if ( val != isOn )
2418 {
2419 this->Modified();
2420 this->LinesOn->SetValue( i, isOn );
2421 }
2422 }
2423
2424 //----------------------------------------------------------------------------
GetPlotLines(int i)2425 int vtkXYPlotActor::GetPlotLines( int i )
2426 {
2427 i = ( i < 0 ? 0 : ( i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i ) );
2428 return this->LinesOn->GetValue( i );
2429 }
2430
2431 //----------------------------------------------------------------------------
SetPlotPoints(int i,int isOn)2432 void vtkXYPlotActor::SetPlotPoints( int i, int isOn )
2433 {
2434 i = ( i < 0 ? 0 : ( i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i ) );
2435 int val = this->PointsOn->GetValue( i );
2436 if ( val != isOn )
2437 {
2438 this->Modified();
2439 this->PointsOn->SetValue( i, isOn );
2440 }
2441 }
2442
2443 //----------------------------------------------------------------------------
GetPlotPoints(int i)2444 int vtkXYPlotActor::GetPlotPoints( int i )
2445 {
2446 i = ( i < 0 ? 0 : ( i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i ) );
2447 return this->PointsOn->GetValue( i );
2448 }
2449
2450 //----------------------------------------------------------------------------
SetPlotColor(int i,double r,double g,double b)2451 void vtkXYPlotActor::SetPlotColor( int i, double r, double g, double b )
2452 {
2453 this->LegendActor->SetEntryColor( i, r, g, b );
2454 }
2455
2456 //----------------------------------------------------------------------------
GetPlotColor(int i)2457 double *vtkXYPlotActor::GetPlotColor( int i )
2458 {
2459 return this->LegendActor->GetEntryColor( i );
2460 }
2461
2462 //----------------------------------------------------------------------------
SetPlotSymbol(int i,vtkPolyData * input)2463 void vtkXYPlotActor::SetPlotSymbol( int i,vtkPolyData *input )
2464 {
2465 this->LegendActor->SetEntrySymbol( i, input );
2466 }
2467
2468 //----------------------------------------------------------------------------
GetPlotSymbol(int i)2469 vtkPolyData *vtkXYPlotActor::GetPlotSymbol( int i )
2470 {
2471 return this->LegendActor->GetEntrySymbol( i );
2472 }
2473
2474 //----------------------------------------------------------------------------
SetPlotLabel(int i,const char * label)2475 void vtkXYPlotActor::SetPlotLabel( int i, const char *label )
2476 {
2477 this->LegendActor->SetEntryString( i, label );
2478 }
2479
2480 //----------------------------------------------------------------------------
GetPlotLabel(int i)2481 const char *vtkXYPlotActor::GetPlotLabel( int i )
2482 {
2483 return this->LegendActor->GetEntryString( i );
2484 }
2485
2486 //----------------------------------------------------------------------------
GenerateClipPlanes(int * pos,int * pos2)2487 void vtkXYPlotActor::GenerateClipPlanes( int *pos, int *pos2 )
2488 {
2489 double n[3], x[3];
2490 vtkPoints *pts=this->ClipPlanes->GetPoints();
2491 vtkDataArray *normals=this->ClipPlanes->GetNormals();
2492
2493 n[2] = x[2] = 0.;
2494
2495 //first
2496 n[0] = 0.;
2497 n[1] = -1.;
2498 normals->SetTuple( 0,n );
2499 x[0] = ( double ) .5 * ( pos[0]+pos2[0] );
2500 x[1] = ( double )pos[1];
2501 pts->SetPoint( 0,x );
2502
2503 //second
2504 n[0] = 1.;
2505 n[1] = 0.;
2506 normals->SetTuple( 1,n );
2507 x[0] = ( double )pos2[0];
2508 x[1] = ( double ) .5 * ( pos[1]+pos2[1] );
2509 pts->SetPoint( 1,x );
2510
2511 //third
2512 n[0] = 0.;
2513 n[1] = 1.;
2514 normals->SetTuple( 2,n );
2515 x[0] = ( double ) .5 * ( pos[0]+pos2[0] );
2516 x[1] = ( double )pos2[1];
2517 pts->SetPoint( 2,x );
2518
2519 //fourth
2520 n[0] = -1.;
2521 n[1] = 0.;
2522 normals->SetTuple( 3,n );
2523 x[0] = ( double )pos[0];
2524 x[1] = ( double ) .5 * ( pos[1]+pos2[1] );
2525 pts->SetPoint( 3,x );
2526 }
2527
2528 //----------------------------------------------------------------------------
ComputeGlyphScale(int i,int * pos,int * pos2)2529 double vtkXYPlotActor::ComputeGlyphScale( int i, int *pos, int *pos2 )
2530 {
2531 vtkPolyData *pd=this->LegendActor->GetEntrySymbol( i );
2532 //pd->Update();
2533 double length=pd->GetLength();
2534 double sf = this->GlyphSize * sqrt( ( double )( pos[0]-pos2[0] )*( pos[0]-pos2[0] ) +
2535 ( pos[1]-pos2[1] )*( pos[1]-pos2[1] ) ) / length;
2536
2537 return sf;
2538 }
2539
2540 //----------------------------------------------------------------------------
2541 //This assumes that there are multiple polylines
ClipPlotData(int * pos,int * pos2,vtkPolyData * pd)2542 void vtkXYPlotActor::ClipPlotData( int *pos, int *pos2, vtkPolyData *pd )
2543 {
2544 vtkPoints *points=pd->GetPoints();
2545 vtkPoints *newPoints;
2546 vtkCellArray *lines=pd->GetLines();
2547 vtkCellArray *newLines, *newVerts;
2548 vtkIdType numPts=pd->GetNumberOfPoints();
2549 vtkIdType npts = 0;
2550 vtkIdType newPts[2];
2551 vtkIdType *pts=nullptr;
2552 vtkIdType i, id;
2553 int j;
2554 double x1[3], x2[3], px[3], n[3], xint[3], t;
2555 double p1[2], p2[2];
2556
2557 p1[0] = ( double )pos[0]; p1[1] = ( double )pos[1];
2558 p2[0] = ( double )pos2[0]; p2[1] = ( double )pos2[1];
2559
2560 newPoints = vtkPoints::New();
2561 newPoints->Allocate( numPts );
2562 newVerts = vtkCellArray::New();
2563 newVerts->Allocate( lines->GetSize() );
2564 newLines = vtkCellArray::New();
2565 newLines->Allocate( 2*lines->GetSize() );
2566 int *pointMap = new int [numPts];
2567 for ( i=0; i<numPts; i++)
2568 {
2569 pointMap[i] = -1;
2570 }
2571
2572 //Loop over polyverts eliminating those that are outside
2573 for ( lines->InitTraversal(); lines->GetNextCell( npts,pts ); )
2574 {
2575 //loop over verts keeping only those that are not clipped
2576 for ( i=0; i<npts; i++)
2577 {
2578 points->GetPoint( pts[i], x1 );
2579
2580 if ( x1[0] >= p1[0] && x1[0] <= p2[0] && x1[1] >= p1[1] && x1[1] <= p2[1] )
2581 {
2582 id = newPoints->InsertNextPoint( x1 );
2583 pointMap[i] = id;
2584 newPts[0] = id;
2585 newVerts->InsertNextCell( 1,newPts );
2586 }
2587 }
2588 }
2589
2590 //Loop over polylines clipping each line segment
2591 for ( lines->InitTraversal(); lines->GetNextCell( npts,pts ); )
2592 {
2593 //loop over line segment making up the polyline
2594 for ( i=0; i<( npts-1 ); i++)
2595 {
2596 points->GetPoint( pts[i], x1 );
2597 points->GetPoint( pts[i+1], x2 );
2598
2599 //intersect each segment with the four planes
2600 if ( ( x1[0] < p1[0] && x2[0] < p1[0] ) || ( x1[0] > p2[0] && x2[0] > p2[0] ) ||
2601 ( x1[1] < p1[1] && x2[1] < p1[1] ) || ( x1[1] > p2[1] && x2[1] > p2[1] ) )
2602 {
2603 ;//trivial rejection
2604 }
2605 else if ( x1[0] >= p1[0] && x2[0] >= p1[0] && x1[0] <= p2[0] && x2[0] <= p2[0] &&
2606 x1[1] >= p1[1] && x2[1] >= p1[1] && x1[1] <= p2[1] && x2[1] <= p2[1] )
2607 {//trivial acceptance
2608 newPts[0] = pointMap[pts[i]];
2609 newPts[1] = pointMap[pts[i+1]];
2610 newLines->InsertNextCell( 2,newPts );
2611 }
2612 else
2613 {
2614 newPts[0] = -1;
2615 newPts[1] = -1;
2616 if ( x1[0] >= p1[0] && x1[0] <= p2[0] && x1[1] >= p1[1] && x1[1] <= p2[1] )
2617 {//first point in
2618 newPts[0] = pointMap[pts[i]];
2619 }
2620 else if ( x2[0] >= p1[0] && x2[0] <= p2[0] && x2[1] >= p1[1] && x2[1] <= p2[1] )
2621 {//second point in
2622 newPts[0] = pointMap[pts[i+1]];
2623 }
2624
2625 //only create cell if either x1 or x2 is inside the range
2626 if ( newPts[0] >= 0 )
2627 {
2628 for ( j=0; j<4; j++)
2629 {
2630 this->ClipPlanes->GetPoints()->GetPoint( j, px );
2631 this->ClipPlanes->GetNormals()->GetTuple( j, n );
2632 if ( vtkPlane::IntersectWithLine( x1,x2,n,px,t,xint ) && t >= 0 && t <= 1.0 )
2633 {
2634 newPts[1] = newPoints->InsertNextPoint( xint );
2635 break;
2636 }
2637 }
2638 if ( newPts[1] >= 0 )
2639 {
2640 newLines->InsertNextCell( 2,newPts );
2641 }
2642 }
2643 }
2644 }
2645 }
2646 delete [] pointMap;
2647
2648 //Update the lines
2649 pd->SetPoints( newPoints );
2650 pd->SetVerts( newVerts );
2651 pd->SetLines( newLines );
2652
2653 newPoints->Delete();
2654 newVerts->Delete();
2655 newLines->Delete();
2656
2657 }
2658
2659 //----------------------------------------------------------------------------
SetDataObjectXComponent(int i,int comp)2660 void vtkXYPlotActor::SetDataObjectXComponent( int i, int comp )
2661 {
2662 i = ( i < 0 ? 0 : ( i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i ) );
2663 int val=this->XComponent->GetValue( i );
2664 if ( val != comp )
2665 {
2666 this->Modified();
2667 this->XComponent->SetValue( i,comp );
2668 }
2669 }
2670
2671 //----------------------------------------------------------------------------
GetDataObjectXComponent(int i)2672 int vtkXYPlotActor::GetDataObjectXComponent( int i )
2673 {
2674 i = ( i < 0 ? 0 : ( i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i ) );
2675 return this->XComponent->GetValue( i );
2676 }
2677
2678 //----------------------------------------------------------------------------
SetDataObjectYComponent(int i,int comp)2679 void vtkXYPlotActor::SetDataObjectYComponent( int i, int comp )
2680 {
2681 i = ( i < 0 ? 0 : ( i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i ) );
2682 int val=this->YComponent->GetValue( i );
2683 if ( val != comp )
2684 {
2685 this->Modified();
2686 this->YComponent->SetValue( i,comp );
2687 }
2688 }
2689
2690 //----------------------------------------------------------------------------
GetDataObjectYComponent(int i)2691 int vtkXYPlotActor::GetDataObjectYComponent( int i )
2692 {
2693 i = ( i < 0 ? 0 : ( i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i ) );
2694 return this->YComponent->GetValue( i );
2695 }
2696
2697 //----------------------------------------------------------------------------
SetPointComponent(int i,int comp)2698 void vtkXYPlotActor::SetPointComponent( int i, int comp )
2699 {
2700 i = ( i < 0 ? 0 : ( i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i ) );
2701 int val = this->XComponent->GetValue( i );
2702 if ( val != comp )
2703 {
2704 this->Modified();
2705 this->XComponent->SetValue( i,comp );
2706 }
2707 }
2708
2709 //----------------------------------------------------------------------------
GetPointComponent(int i)2710 int vtkXYPlotActor::GetPointComponent( int i )
2711 {
2712 i = ( i < 0 ? 0 : ( i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i ) );
2713 return this->XComponent->GetValue( i );
2714 }
2715
2716 //----------------------------------------------------------------------------
TransformPoint(int pos[2],int pos2[2],double x[3],double xNew[3])2717 double *vtkXYPlotActor::TransformPoint( int pos[2], int pos2[2],
2718 double x[3], double xNew[3] )
2719 {
2720 // First worry about exchanging axes
2721 if ( this->ExchangeAxes )
2722 {
2723 double sx = ( x[0]-pos[0] ) / ( pos2[0]-pos[0] );
2724 double sy = ( x[1]-pos[1] ) / ( pos2[1]-pos[1] );
2725 xNew[0] = sy*( pos2[0]-pos[0] ) + pos[0];
2726 xNew[1] = sx*( pos2[1]-pos[1] ) + pos[1];
2727 xNew[2] = x[2];
2728 }
2729 else
2730 {
2731 xNew[0] = x[0];
2732 xNew[1] = x[1];
2733 xNew[2] = x[2];
2734 }
2735
2736 // Okay, now swap the axes around if reverse is on
2737 if ( this->ReverseXAxis )
2738 {
2739 xNew[0] = pos[0] + ( pos2[0]-xNew[0] );
2740 }
2741 if ( this->ReverseYAxis )
2742 {
2743 xNew[1] = pos[1] + ( pos2[1]-xNew[1] );
2744 }
2745
2746 return xNew;
2747 }
2748
2749 //----------------------------------------------------------------------------
SetYTitle(const char * ytitle)2750 void vtkXYPlotActor::SetYTitle( const char* ytitle )
2751 {
2752 this->YTitleActor->SetInput( ytitle );
2753 this->Modified();
2754 }
2755
2756 //----------------------------------------------------------------------------
GetYTitle()2757 char* vtkXYPlotActor::GetYTitle()
2758 {
2759 return this->YTitleActor->GetInput();
2760 }
2761
2762 //----------------------------------------------------------------------------
SetXTitlePosition(double position)2763 void vtkXYPlotActor::SetXTitlePosition( double position )
2764 {
2765 this->XAxis->SetTitlePosition( position );
2766 this->Modified();
2767 }
2768
2769 //----------------------------------------------------------------------------
GetXTitlePosition()2770 double vtkXYPlotActor::GetXTitlePosition()
2771 {
2772 return this->XAxis->GetTitlePosition();
2773 }
2774
2775 //----------------------------------------------------------------------------
SetAdjustXLabels(int adjust)2776 void vtkXYPlotActor::SetAdjustXLabels( int adjust )
2777 {
2778 this->AdjustXLabels = adjust;
2779 this->XAxis->SetAdjustLabels( adjust );
2780 }
2781
2782 //----------------------------------------------------------------------------
SetAdjustYLabels(int adjust)2783 void vtkXYPlotActor::SetAdjustYLabels( int adjust )
2784 {
2785 this->AdjustYLabels = adjust;
2786 this->YAxis->SetAdjustLabels( adjust );
2787 }
2788
2789 //----------------------------------------------------------------------------
SetLabelFormat(const char * _arg)2790 void vtkXYPlotActor::SetLabelFormat( const char* _arg )
2791 {
2792 this->SetXLabelFormat(_arg );
2793 this->SetYLabelFormat(_arg );
2794 }
2795
2796 //----------------------------------------------------------------------------
SetXLabelFormat(const char * _arg)2797 void vtkXYPlotActor::SetXLabelFormat( const char* _arg )
2798 {
2799 if ( this->XLabelFormat == nullptr && _arg == nullptr )
2800 {
2801 return;
2802 }
2803
2804 if ( this->XLabelFormat && _arg && (!strcmp( this->XLabelFormat,_arg ) ) )
2805 {
2806 return;
2807 }
2808
2809 delete [] this->XLabelFormat;
2810
2811 if (_arg )
2812 {
2813 this->XLabelFormat = new char[strlen(_arg )+1];
2814 strcpy( this->XLabelFormat,_arg );
2815 }
2816 else
2817 {
2818 this->XLabelFormat = nullptr;
2819 }
2820
2821 this->XAxis->SetLabelFormat( this->XLabelFormat );
2822
2823 this->Modified();
2824 }
2825
2826 //----------------------------------------------------------------------------
SetYLabelFormat(const char * _arg)2827 void vtkXYPlotActor::SetYLabelFormat( const char* _arg )
2828 {
2829 if ( this->YLabelFormat == nullptr && _arg == nullptr )
2830 {
2831 return;
2832 }
2833
2834 if ( this->YLabelFormat && _arg && (!strcmp( this->YLabelFormat,_arg ) ) )
2835 {
2836 return;
2837 }
2838
2839 delete [] this->YLabelFormat;
2840
2841 if (_arg )
2842 {
2843 this->YLabelFormat = new char[strlen(_arg )+1];
2844 strcpy( this->YLabelFormat,_arg );
2845 }
2846 else
2847 {
2848 this->YLabelFormat = nullptr;
2849 }
2850
2851 this->YAxis->SetLabelFormat( this->YLabelFormat );
2852
2853 this->Modified();
2854 }
2855
2856 //----------------------------------------------------------------------------
SetNumberOfXMinorTicks(int num)2857 void vtkXYPlotActor::SetNumberOfXMinorTicks( int num )
2858 {
2859 this->XAxis->SetNumberOfMinorTicks( num );
2860 this->Modified();
2861 }
2862
2863 //----------------------------------------------------------------------------
GetNumberOfXMinorTicks()2864 int vtkXYPlotActor::GetNumberOfXMinorTicks()
2865 {
2866 return this->XAxis->GetNumberOfMinorTicks();
2867 }
2868
2869 //----------------------------------------------------------------------------
SetNumberOfYMinorTicks(int num)2870 void vtkXYPlotActor::SetNumberOfYMinorTicks( int num )
2871 {
2872 this->YAxis->SetNumberOfMinorTicks( num );
2873 this->Modified();
2874 }
2875
2876 //----------------------------------------------------------------------------
GetNumberOfYMinorTicks()2877 int vtkXYPlotActor::GetNumberOfYMinorTicks()
2878 {
2879 return this->YAxis->GetNumberOfMinorTicks();
2880 }
2881
2882 //----------------------------------------------------------------------------
PrintAsCSV(ostream & os)2883 void vtkXYPlotActor::PrintAsCSV( ostream &os )
2884 {
2885 vtkDataArray *scalars;
2886 vtkDataSet *ds;
2887 double s;
2888 int component;
2889 int numDS = this->InputConnectionHolder->GetNumberOfInputConnections( 0 );
2890 for ( int dsNum=0; dsNum<numDS; dsNum++)
2891 {
2892 vtkAlgorithmOutput* port =
2893 this->InputConnectionHolder->GetInputConnection( 0, dsNum );
2894 vtkAlgorithm* alg = port->GetProducer();
2895 int portIndex = port->GetIndex();
2896 ds = vtkDataSet::SafeDownCast( alg->GetOutputDataObject( portIndex ) );
2897 vtkIdType numPts = ds->GetNumberOfPoints();
2898 scalars = ds->GetPointData()->GetScalars( this->SelectedInputScalars[dsNum] );
2899 os << this->SelectedInputScalars[dsNum] << ",";
2900
2901 component = this->SelectedInputScalarsComponent->GetValue( dsNum );
2902 for ( vtkIdType ptId=0; ptId < numPts; ptId++ )
2903 {
2904 s = scalars->GetComponent( ptId, component );
2905 if( ptId == 0 )
2906 {
2907 os << s;
2908 }
2909 else
2910 {
2911 os << "," << s;
2912 }
2913 }
2914 os << endl;
2915
2916 if ( dsNum == numDS-1 )
2917 {
2918 os << "X or T,";
2919 for ( vtkIdType ptId=0; ptId < numPts; ptId++ )
2920 {
2921 double *x = ds->GetPoint( ptId );
2922 if( ptId == 0 )
2923 {
2924 os << x[0];
2925 }
2926 else
2927 {
2928 os << "," << x[0];
2929 }
2930 }
2931 os << endl;
2932 }
2933
2934 }
2935 }
2936
2937 //----------------------------------------------------------------------------
AddUserCurvesPoint(double c_dbl,double x,double y)2938 void vtkXYPlotActor::AddUserCurvesPoint( double c_dbl, double x, double y )
2939 {
2940 int c = static_cast<int>( c_dbl );
2941 if( this->ActiveCurveIndex != c )
2942 {
2943 vtkPolyData* dataObj = vtkPolyData::New();
2944 dataObj->GetFieldData()->AddArray( this->ActiveCurve );
2945 this->AddDataObjectInput( dataObj );
2946 this->SetDataObjectXComponent( this->ActiveCurveIndex, 0 );
2947 this->SetDataObjectYComponent( this->ActiveCurveIndex, 1 );
2948 dataObj->Delete();
2949 this->ActiveCurve = vtkSmartPointer<vtkDoubleArray>::New();
2950 this->ActiveCurve->SetNumberOfComponents( 2 );
2951 this->ActiveCurveIndex = c;
2952 }
2953 this->ActiveCurve->InsertNextTuple2( x, y );
2954 this->Modified();
2955 }
2956
2957 //----------------------------------------------------------------------------
RemoveAllActiveCurves()2958 void vtkXYPlotActor::RemoveAllActiveCurves()
2959 {
2960 this->ActiveCurveIndex = 0;
2961 this->ActiveCurve = vtkSmartPointer<vtkDoubleArray>::New();
2962 this->ActiveCurve->SetNumberOfComponents( 2 );
2963 this->Modified();
2964 }
2965
2966 //----------------------------------------------------------------------------
2967 // Glyph type
2968 // \li 0 : nothing
2969 // \li 1 : vertex - not visible
2970 // \li 2 : line
2971 // \li 3 : cross
2972 // \li 4 : thick cross
2973 // \li 5 : triangle
2974 // \li 6 : square
2975 // \li 7 : circle
2976 // \li 8 : diamond
2977 // \li 9 : arrow
2978 // \li 10 : thick arrow
2979 // \li 11 : curved arrow
2980 // \li 12 : arrow
2981 // \li 13 : nothing
2982 // \li 14 : nothing
2983 // \li 15 : 2 + fillOff
2984 // \li 16 : nothing
2985 // \li 17 : 4 + fillOff
2986 // \li 18 : 5 + fillOff
2987 // \li 19 : 6 + fillOff
2988 // \li 20 : 7 + fillOff
2989 // \li 21 : 8 + fillOff
2990 // \li 22 : nothing
2991 // \li 23 : 10 + fillOff
2992 // \li 24 : 11 + fillOff
2993 // \li 25 : 12 + fillOff*
SetPlotGlyphType(int curve,int i)2994 void vtkXYPlotActor::SetPlotGlyphType( int curve, int i )
2995 {
2996 static const int good_glyph_type[26] =
2997 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 2, 0, 4, 5, 6, 7, 8, 0, 10, 11, 12 };
2998 vtkSmartPointer<vtkGlyphSource2D> source = vtkSmartPointer<vtkGlyphSource2D>::New();
2999 source->SetGlyphType( good_glyph_type[i] );
3000 source->SetFilled( ( i > 12 ) ? 0 : 1 );
3001 source->Update();
3002
3003 vtkPolyData* glyph = vtkPolyData::SafeDownCast( source->GetOutputDataObject( 0 ) );
3004 this->SetPlotSymbol( curve, glyph );
3005 }
3006
3007
3008 //----------------------------------------------------------------------------
SetXAxisColor(double r,double g,double b)3009 void vtkXYPlotActor::SetXAxisColor( double r, double g, double b )
3010 {
3011 this->XAxis->GetProperty()->SetColor( r, g, b );
3012 this->Modified();
3013 }
3014
3015 //----------------------------------------------------------------------------
SetYAxisColor(double r,double g,double b)3016 void vtkXYPlotActor::SetYAxisColor( double r, double g, double b )
3017 {
3018 this->YAxis->GetProperty()->SetColor( r, g, b );
3019 this->Modified();
3020 }
3021
3022
3023 //----------------------------------------------------------------------------
SetLegendBorder(int b)3024 void vtkXYPlotActor::SetLegendBorder( int b )
3025 {
3026 this->LegendActor->SetBorder( b );
3027 this->Modified();
3028 }
3029
3030
3031 //----------------------------------------------------------------------------
SetLegendBox(int b)3032 void vtkXYPlotActor::SetLegendBox( int b )
3033 {
3034 this->LegendActor->SetBox( b );
3035 this->Modified();
3036 }
3037
3038 //----------------------------------------------------------------------------
SetLegendUseBackground(int b)3039 void vtkXYPlotActor::SetLegendUseBackground( int b )
3040 {
3041 this->LegendActor->SetUseBackground( b );
3042 this->Modified();
3043 }
3044
3045 //----------------------------------------------------------------------------
SetLegendBackgroundColor(double r,double g,double b)3046 void vtkXYPlotActor::SetLegendBackgroundColor( double r, double g, double b )
3047 {
3048 this->LegendActor->SetBackgroundColor( r, g, b );
3049 this->Modified();
3050 }
3051
3052 //----------------------------------------------------------------------------
SetLineWidth(double w)3053 void vtkXYPlotActor::SetLineWidth( double w )
3054 {
3055 this->GetProperty()->SetLineWidth( w );
3056 this->Modified();
3057 }
3058
3059 //----------------------------------------------------------------------------
SetTitleColor(double r,double g,double b)3060 void vtkXYPlotActor::SetTitleColor( double r, double g, double b )
3061 {
3062 this->GetTitleTextProperty()->SetColor( r, g, b );
3063 this->Modified();
3064 }
3065
3066 //----------------------------------------------------------------------------
SetTitleFontFamily(int x)3067 void vtkXYPlotActor::SetTitleFontFamily( int x )
3068 {
3069 this->GetTitleTextProperty()->SetFontFamily( x );
3070 this->Modified();
3071 }
3072
3073 //----------------------------------------------------------------------------
SetTitleBold(int x)3074 void vtkXYPlotActor::SetTitleBold( int x )
3075 {
3076 this->GetTitleTextProperty()->SetBold( x );
3077 this->Modified();
3078 }
3079
3080 //----------------------------------------------------------------------------
SetTitleItalic(int x)3081 void vtkXYPlotActor::SetTitleItalic( int x )
3082 {
3083 this->GetTitleTextProperty()->SetItalic( x );
3084 this->Modified();
3085 }
3086
3087 //----------------------------------------------------------------------------
SetTitleShadow(int x)3088 void vtkXYPlotActor::SetTitleShadow( int x )
3089 {
3090 this->GetTitleTextProperty()->SetShadow( x );
3091 this->Modified();
3092 }
3093
3094 //----------------------------------------------------------------------------
SetTitleFontSize(int x)3095 void vtkXYPlotActor::SetTitleFontSize( int x )
3096 {
3097 this->GetTitleTextProperty()->SetFontSize( x );
3098 this->Modified();
3099 }
3100
3101 //----------------------------------------------------------------------------
SetTitleJustification(int x)3102 void vtkXYPlotActor::SetTitleJustification( int x )
3103 {
3104 this->GetTitleTextProperty()->SetJustification( x );
3105 this->Modified();
3106 }
3107
3108 //----------------------------------------------------------------------------
SetTitleVerticalJustification(int x)3109 void vtkXYPlotActor::SetTitleVerticalJustification( int x )
3110 {
3111 this->GetTitleTextProperty()->SetVerticalJustification( x );
3112 this->Modified();
3113 }
3114
3115 //----------------------------------------------------------------------------
SetAxisTitleColor(double r,double g,double b)3116 void vtkXYPlotActor::SetAxisTitleColor( double r, double g, double b )
3117 {
3118 this->GetAxisTitleTextProperty()->SetColor( r, g, b );
3119 this->Modified();
3120 }
3121
3122 //----------------------------------------------------------------------------
SetAxisTitleFontFamily(int x)3123 void vtkXYPlotActor::SetAxisTitleFontFamily( int x )
3124 {
3125 this->GetAxisTitleTextProperty()->SetFontFamily( x );
3126 this->Modified();
3127 }
3128
3129 //----------------------------------------------------------------------------
SetAxisTitleBold(int x)3130 void vtkXYPlotActor::SetAxisTitleBold( int x )
3131 {
3132 this->GetAxisTitleTextProperty()->SetBold( x );
3133 this->Modified();
3134 }
3135
3136 //----------------------------------------------------------------------------
SetAxisTitleItalic(int x)3137 void vtkXYPlotActor::SetAxisTitleItalic( int x )
3138 {
3139 this->GetAxisTitleTextProperty()->SetItalic( x );
3140 this->Modified();
3141 }
3142
3143 //----------------------------------------------------------------------------
SetAxisTitleShadow(int x)3144 void vtkXYPlotActor::SetAxisTitleShadow( int x )
3145 {
3146 this->GetAxisTitleTextProperty()->SetShadow( x );
3147 this->Modified();
3148 }
3149
3150 //----------------------------------------------------------------------------
SetAxisTitleFontSize(int x)3151 void vtkXYPlotActor::SetAxisTitleFontSize( int x )
3152 {
3153 this->GetAxisTitleTextProperty()->SetFontSize( x );
3154 this->Modified();
3155 }
3156
3157 //----------------------------------------------------------------------------
SetAxisTitleJustification(int x)3158 void vtkXYPlotActor::SetAxisTitleJustification( int x )
3159 {
3160 this->GetAxisTitleTextProperty()->SetJustification( x );
3161 this->Modified();
3162 }
3163
3164 //----------------------------------------------------------------------------
SetAxisTitleVerticalJustification(int x)3165 void vtkXYPlotActor::SetAxisTitleVerticalJustification( int x )
3166 {
3167 this->GetAxisTitleTextProperty()->SetVerticalJustification( x );
3168 this->Modified();
3169 }
3170
3171 //----------------------------------------------------------------------------
SetAxisTitleTextProperty(vtkTextProperty * p)3172 void vtkXYPlotActor::SetAxisTitleTextProperty( vtkTextProperty* p )
3173 {
3174 // NB: Perform shallow copy here since each individual axis can be
3175 // accessed through the class API ( i.e. each individual axis text prop
3176 // can be changed ). Therefore, we can not just assign pointers otherwise
3177 // each individual axis text prop would point to the same text prop.
3178 this->AxisTitleTextProperty->ShallowCopy( p );
3179 this->YTitleActor->GetTextProperty()->ShallowCopy( p );
3180 this->Modified();
3181 }
3182
3183 //----------------------------------------------------------------------------
SetAxisLabelColor(double r,double g,double b)3184 void vtkXYPlotActor::SetAxisLabelColor( double r, double g, double b )
3185 {
3186 this->GetAxisLabelTextProperty()->SetColor( r, g, b );
3187 this->Modified();
3188 }
3189
3190 //----------------------------------------------------------------------------
SetAxisLabelFontFamily(int x)3191 void vtkXYPlotActor::SetAxisLabelFontFamily( int x )
3192 {
3193 this->GetAxisLabelTextProperty()->SetFontFamily( x );
3194 this->Modified();
3195 }
3196
3197 //----------------------------------------------------------------------------
SetAxisLabelBold(int x)3198 void vtkXYPlotActor::SetAxisLabelBold( int x )
3199 {
3200 this->GetAxisLabelTextProperty()->SetBold( x );
3201 }
3202
3203 //----------------------------------------------------------------------------
SetAxisLabelItalic(int x)3204 void vtkXYPlotActor::SetAxisLabelItalic( int x )
3205 {
3206 this->GetAxisLabelTextProperty()->SetItalic( x );
3207 this->Modified();
3208 }
3209
3210 //----------------------------------------------------------------------------
SetAxisLabelShadow(int x)3211 void vtkXYPlotActor::SetAxisLabelShadow( int x )
3212 {
3213 this->GetAxisLabelTextProperty()->SetShadow( x );
3214 this->Modified();
3215 }
3216
3217 //----------------------------------------------------------------------------
SetAxisLabelFontSize(int x)3218 void vtkXYPlotActor::SetAxisLabelFontSize( int x )
3219 {
3220 this->GetAxisLabelTextProperty()->SetFontSize( x );
3221 this->Modified();
3222 }
3223
3224 //----------------------------------------------------------------------------
SetAxisLabelJustification(int x)3225 void vtkXYPlotActor::SetAxisLabelJustification( int x )
3226 {
3227 this->GetAxisLabelTextProperty()->SetJustification( x );
3228 this->Modified();
3229 }
3230
3231 //----------------------------------------------------------------------------
SetAxisLabelVerticalJustification(int x)3232 void vtkXYPlotActor::SetAxisLabelVerticalJustification( int x )
3233 {
3234 this->GetAxisLabelTextProperty()->SetVerticalJustification( x );
3235 this->Modified();
3236 }
3237