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