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