Salome HOME
0021711: [CEA 579] Simplify Properties dialog accordingly to dimension of mesh
[modules/visu.git] / src / PIPELINE / VISU_XYPlotActor.cxx
1 /*=========================================================================
2
3   Program:   Visualization Toolkit
4   Module:    $RCSfile$
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   *** Modified by OPEN CASCADE
15
16 =========================================================================*/
17 #include "VISU_XYPlotActor.hxx"
18
19 #include "vtkAppendPolyData.h"
20 #include "vtkAxisActor2D.h"
21 #include "vtkCellArray.h"
22 #include "vtkDataObjectCollection.h"
23 #include "vtkDataSetCollection.h"
24 #include "vtkFieldData.h"
25 #include "vtkDoubleArray.h"
26 #include "vtkGlyph2D.h"
27 #include "vtkGlyphSource2D.h"
28 #include "vtkIntArray.h"
29 #include "vtkLegendBoxActor.h"
30 #include "vtkMath.h"
31 #include "vtkObjectFactory.h"
32 #include "vtkPlane.h"
33 #include "vtkPlanes.h"
34 #include "vtkPointData.h"
35 #include "vtkPolyData.h"
36 #include "vtkPolyDataMapper2D.h"
37 #include "vtkProperty2D.h"
38 #include "vtkTextMapper.h"
39 #include "vtkTextProperty.h"
40 #include "vtkViewport.h"
41 #include "vtkTransformPolyDataFilter.h" // RKV
42 #include "vtkTransform.h" // RKV
43
44 #define VTK_MAX_PLOTS 50
45
46 #if !defined(VTK_XVERSION)
47 #define VTK_XVERSION (VTK_MAJOR_VERSION<<16)+(VTK_MINOR_VERSION<<8)+(VTK_BUILD_VERSION)
48 #endif
49
50 using namespace std;
51
52 vtkCxxRevisionMacro(VISU_XYPlotActor, "$Revision$");
53 vtkStandardNewMacro(VISU_XYPlotActor);
54
55 vtkCxxSetObjectMacro(VISU_XYPlotActor,TitleTextProperty,vtkTextProperty);
56 vtkCxxSetObjectMacro(VISU_XYPlotActor,AxisLabelTextProperty,vtkTextProperty);
57 vtkCxxSetObjectMacro(VISU_XYPlotActor,AxisTitleTextProperty,vtkTextProperty);
58
59 //----------------------------------------------------------------------------
60 // Instantiate object
61 VISU_XYPlotActor::VISU_XYPlotActor()
62 {
63   this->PositionCoordinate->SetCoordinateSystemToNormalizedViewport();
64   this->PositionCoordinate->SetValue(0.25,0.25);
65   this->Position2Coordinate->SetValue(0.5, 0.5);
66
67   this->InputList = vtkDataSetCollection::New();
68   this->SelectedInputScalars = NULL;
69   this->SelectedInputScalarsComponent = vtkIntArray::New();
70   this->DataObjectInputList = vtkDataObjectCollection::New();
71
72   this->Title = NULL;
73   this->XTitle = new char[7];
74   sprintf(this->XTitle,"%s","X Axis");
75   this->YTitle = new char[7];
76   sprintf(this->YTitle,"%s","Y Axis");
77
78   this->XValues = VTK_XYPLOT_INDEX;
79   this->PlotLocation = VISU_XYPLOT_BOTTOM; // RKV
80
81   this->NumberOfXLabels = 5;
82   this->NumberOfYLabels = 5;
83
84   this->TitleTextProperty = vtkTextProperty::New();
85   this->TitleTextProperty->SetBold(1);
86   this->TitleTextProperty->SetItalic(1);
87   this->TitleTextProperty->SetShadow(1);
88   this->TitleTextProperty->SetFontFamilyToArial();
89
90   this->AxisLabelTextProperty = vtkTextProperty::New();
91   this->AxisLabelTextProperty->ShallowCopy(this->TitleTextProperty);
92
93   this->AxisTitleTextProperty = vtkTextProperty::New();
94   this->AxisTitleTextProperty->ShallowCopy(this->AxisLabelTextProperty);
95
96   this->LabelFormat = new char[8]; 
97   sprintf(this->LabelFormat,"%s","%-#6.3g");
98
99   this->Logx = 0;
100   
101   this->XRange[0] = 0.0;
102   this->XRange[1] = 0.0;
103   this->YRange[0] = 0.0;
104   this->YRange[1] = 0.0;
105
106   this->Border = 5;
107   this->PlotLines = 1;
108   this->PlotPoints = 0;
109   this->PlotCurveLines = 0;
110   this->PlotCurvePoints = 0;
111   this->ExchangeAxes = 0;
112   this->ReverseXAxis = 0;
113   this->ReverseYAxis = 0;
114
115   this->TitleMapper = vtkTextMapper::New();
116   this->TitleActor = vtkActor2D::New();
117   this->TitleActor->SetMapper(this->TitleMapper);
118   this->TitleActor->GetPositionCoordinate()->SetCoordinateSystemToViewport();
119
120   this->XAxis = vtkAxisActor2D::New();
121   this->XAxis->GetPositionCoordinate()->SetCoordinateSystemToViewport();
122   this->XAxis->GetPosition2Coordinate()->SetCoordinateSystemToViewport();
123   this->XAxis->SetProperty(this->GetProperty());
124
125   this->YAxis = vtkAxisActor2D::New();
126   this->YAxis->GetPositionCoordinate()->SetCoordinateSystemToViewport();
127   this->YAxis->GetPosition2Coordinate()->SetCoordinateSystemToViewport();
128   this->YAxis->SetProperty(this->GetProperty());
129   
130   this->NumberOfInputs = 0;
131   this->PlotData = NULL;
132   this->PlotGlyph = NULL;
133   this->PlotAppend = NULL;
134   this->PlotTransform = NULL; // RKV
135   this->PlotMapper = NULL;
136   this->PlotActor = NULL;
137
138   this->ViewportCoordinate[0] = 0.0;
139   this->ViewportCoordinate[1] = 0.0;
140   this->PlotCoordinate[0] = 0.0;
141   this->PlotCoordinate[1] = 0.0;
142
143   this->DataObjectPlotMode = VTK_XYPLOT_COLUMN;
144   this->XComponent = vtkIntArray::New();
145   this->XComponent->SetNumberOfValues(VTK_MAX_PLOTS);
146   this->YComponent = vtkIntArray::New();
147   this->YComponent->SetNumberOfValues(VTK_MAX_PLOTS);
148
149   this->LinesOn = vtkIntArray::New();
150   this->LinesOn->SetNumberOfValues(VTK_MAX_PLOTS);
151   this->PointsOn = vtkIntArray::New();
152   this->PointsOn->SetNumberOfValues(VTK_MAX_PLOTS);
153   for (int i=0; i<VTK_MAX_PLOTS; i++)
154     {
155     this->XComponent->SetValue(i,0);
156     this->YComponent->SetValue(i,0);
157     this->LinesOn->SetValue(i,this->PlotLines);
158     this->PointsOn->SetValue(i,this->PlotPoints);
159     }
160
161   this->Legend = 0;
162   this->LegendPosition[0] = 0.85;
163   this->LegendPosition[1] = 0.75;
164   this->LegendPosition2[0] = 0.15;
165   this->LegendPosition2[1] = 0.20;
166   this->LegendActor = vtkLegendBoxActor::New();
167   this->LegendActor->GetPositionCoordinate()->SetCoordinateSystemToViewport();
168   this->LegendActor->GetPosition2Coordinate()->SetCoordinateSystemToViewport();
169   this->LegendActor->GetPosition2Coordinate()->SetReferenceCoordinate(NULL);
170   this->LegendActor->BorderOff();
171   this->LegendActor->SetNumberOfEntries(VTK_MAX_PLOTS); //initial allocation
172   this->GlyphSource = vtkGlyphSource2D::New();
173   this->GlyphSource->SetGlyphTypeToNone();
174   this->GlyphSource->DashOn();
175   this->GlyphSource->FilledOff();
176   this->GlyphSize = 0.020;
177
178   this->ClipPlanes = vtkPlanes::New();
179   vtkPoints *pts = vtkPoints::New();
180   pts->SetNumberOfPoints(4);
181   this->ClipPlanes->SetPoints(pts);
182   pts->Delete();
183   vtkDoubleArray *n = vtkDoubleArray::New();
184   n->SetNumberOfComponents(3);
185   n->SetNumberOfTuples(4);
186   this->ClipPlanes->SetNormals(n);
187   n->Delete();
188
189   this->CachedSize[0] = 0;
190   this->CachedSize[1] = 0;
191 }
192
193 //----------------------------------------------------------------------------
194 VISU_XYPlotActor::~VISU_XYPlotActor()
195 {
196   // Get rid of the list of array names.
197   int num = this->InputList->GetNumberOfItems();
198   if (this->SelectedInputScalars)
199     {
200     for (int i = 0; i < num; ++i)
201       {
202       if (this->SelectedInputScalars[i])
203         {
204         delete [] this->SelectedInputScalars[i];
205         this->SelectedInputScalars[i] = NULL;
206         }
207       }
208     delete [] this->SelectedInputScalars;
209     this->SelectedInputScalars = NULL;  
210     }
211   this->SelectedInputScalarsComponent->Delete();
212   this->SelectedInputScalarsComponent = NULL;
213
214   //  Now we can get rid of the inputs. 
215   this->InputList->Delete();
216   this->InputList = NULL;
217
218   this->DataObjectInputList->Delete();
219   this->DataObjectInputList = NULL;
220
221   this->TitleMapper->Delete();
222   this->TitleMapper = NULL;
223   this->TitleActor->Delete();
224   this->TitleActor = NULL;
225
226   this->SetTitle(0);
227   this->SetXTitle(0);
228   this->SetYTitle(0);
229   this->SetLabelFormat(0);
230
231   this->XAxis->Delete();
232   this->YAxis->Delete();
233   
234   this->InitializeEntries();
235
236   this->LegendActor->Delete();
237   this->GlyphSource->Delete();
238   this->ClipPlanes->Delete();
239   
240   this->XComponent->Delete();
241   this->YComponent->Delete();
242
243   this->LinesOn->Delete();
244   this->PointsOn->Delete();
245
246   this->SetTitleTextProperty(NULL);
247   this->SetAxisLabelTextProperty(NULL);
248   this->SetAxisTitleTextProperty(NULL);
249 }
250
251 //----------------------------------------------------------------------------
252 void VISU_XYPlotActor::InitializeEntries()
253 {
254   if ( this->NumberOfInputs > 0 )
255     {
256     for (int i=0; i<this->NumberOfInputs; i++)
257       {
258       this->PlotData[i]->Delete();
259       this->PlotGlyph[i]->Delete();
260       this->PlotAppend[i]->Delete();
261       this->PlotTransform[i]->Delete(); // RKV
262       this->PlotMapper[i]->Delete();
263       this->PlotActor[i]->Delete();
264       }//for all entries
265     delete [] this->PlotData; this->PlotData = NULL;
266     delete [] this->PlotGlyph; this->PlotGlyph = NULL;
267     delete [] this->PlotAppend; this->PlotAppend = NULL;
268     delete [] this->PlotTransform; this->PlotTransform = NULL; // RKV
269     delete [] this->PlotMapper; this->PlotMapper = NULL;
270     delete [] this->PlotActor; this->PlotActor = NULL;
271     this->NumberOfInputs = 0;
272     }//if entries have been defined
273 }
274   
275 //----------------------------------------------------------------------------
276 // Add a dataset and array to the list of data to plot.
277 void VISU_XYPlotActor::AddInput(vtkDataSet *ds, const char *arrayName, int component)
278 {
279   int idx, num;
280   char** newNames;
281
282   // I cannot change the input list, because the user has direct 
283   // access to the collection.  I cannot store the index of the array, 
284   // because the index might change from render to render ...
285   // I have to store the list of string array names.
286
287   // I believe idx starts at 1 and goes to "NumberOfItems".
288   idx = this->InputList->IsItemPresent(ds);
289   if (idx > 0)
290     { // Return if arrays are the same.
291     if (arrayName == NULL && this->SelectedInputScalars[idx-1] == NULL &&
292         component == this->SelectedInputScalarsComponent->GetValue(idx-1))
293       {
294       return;
295       }
296     if (arrayName != NULL && this->SelectedInputScalars[idx-1] != NULL &&
297         strcmp(arrayName, this->SelectedInputScalars[idx-1]) == 0 &&
298         component == this->SelectedInputScalarsComponent->GetValue(idx-1))
299       {
300       return;
301       }
302     }
303
304   // The input/array/component must be a unique combination.  Add it to our input list.
305
306   // Now reallocate the list of strings and add the new value.
307   num = this->InputList->GetNumberOfItems();
308   newNames = new char*[num+1];
309   for (idx = 0; idx < num; ++idx)
310     {
311     newNames[idx] = this->SelectedInputScalars[idx];
312     }
313   if (arrayName == NULL)
314     {
315     newNames[num] = NULL;
316     }
317   else
318     {
319     newNames[num] = new char[strlen(arrayName)+1];
320     strcpy(newNames[num],arrayName);
321     }
322   delete [] this->SelectedInputScalars;
323   this->SelectedInputScalars = newNames;
324
325   // Save the component in the int array.
326   this->SelectedInputScalarsComponent->InsertValue(num, component);
327
328   // Add the data set to the collection
329   this->InputList->AddItem(ds);
330
331   // In case of multiple use of a XYPlotActor the NumberOfEntries could be set
332   // to n. Then when a call to SetEntryString(n+1, bla) was done the string was lost
333   // Need to update the number of entries for the legend actor
334   this->LegendActor->SetNumberOfEntries(this->LegendActor->GetNumberOfEntries()+1);
335
336   this->Modified();
337 }
338
339 //----------------------------------------------------------------------------
340 void VISU_XYPlotActor::RemoveAllInputs()
341 {
342   int idx, num;
343
344   num = this->InputList->GetNumberOfItems();
345   this->InputList->RemoveAllItems();
346
347   for (idx = 0; idx < num; ++idx)
348     {
349     if (this->SelectedInputScalars[idx])
350       {
351       delete [] this->SelectedInputScalars[idx];
352       this->SelectedInputScalars[idx] = NULL;
353       }
354     }
355   this->SelectedInputScalarsComponent->Reset();
356
357   this->DataObjectInputList->RemoveAllItems();
358 }
359
360 //----------------------------------------------------------------------------
361 // Remove a dataset from the list of data to plot.
362 void VISU_XYPlotActor::RemoveInput(vtkDataSet *ds, const char *arrayName, int component)
363 {
364   int idx, num;
365   vtkDataSet *input;
366   int found = -1;
367
368   // This is my own find routine, because the array names have to match also.
369   num = this->InputList->GetNumberOfItems();
370   vtkCollectionSimpleIterator dsit;
371   this->InputList->InitTraversal(dsit);
372   for (idx = 0; idx < num && found == -1; ++idx)
373     {
374     input = this->InputList->GetNextDataSet(dsit);
375     if (input == ds)
376       {
377       if (arrayName == NULL && this->SelectedInputScalars[idx] == NULL &&
378           component == this->SelectedInputScalarsComponent->GetValue(idx))
379         {
380         found = idx;
381         }
382       if (arrayName != NULL && this->SelectedInputScalars[idx] != NULL &&
383           strcmp(arrayName, this->SelectedInputScalars[idx]) == 0 &&
384           component == this->SelectedInputScalarsComponent->GetValue(idx))
385         {
386         found = idx;
387         }
388       }
389     }
390
391   if (found == -1)
392     {
393     return;
394     }
395   
396   this->Modified();
397   // Collections index their items starting at 1.
398   this->InputList->RemoveItem(found);
399
400   // Do not bother reallocating the SelectedInputScalars 
401   // string array to make it smaller.
402   if (this->SelectedInputScalars[found])
403     {
404     delete [] this->SelectedInputScalars[found];
405     this->SelectedInputScalars[found] = NULL;
406     }
407   for (idx = found+1; idx < num; ++idx)
408     {
409     this->SelectedInputScalars[idx-1] = this->SelectedInputScalars[idx];
410     this->SelectedInputScalarsComponent->SetValue(idx-1, 
411                           this->SelectedInputScalarsComponent->GetValue(idx));
412     }
413   // Reseting the last item is not really necessary, 
414   // but to be clean we do it anyway.
415   this->SelectedInputScalarsComponent->SetValue(num-1, -1); 
416   this->SelectedInputScalars[num-1] = NULL;
417 }
418
419 //----------------------------------------------------------------------------
420 // Add a data object to the list of data to plot.
421 void VISU_XYPlotActor::AddDataObjectInput(vtkDataObject *in)
422 {
423   if ( ! this->DataObjectInputList->IsItemPresent(in) )
424     {
425     this->Modified();
426     this->DataObjectInputList->AddItem(in);
427     }
428 }
429
430 //----------------------------------------------------------------------------
431 // Remove a data object from the list of data to plot.
432 void VISU_XYPlotActor::RemoveDataObjectInput(vtkDataObject *in)
433 {
434   if ( this->DataObjectInputList->IsItemPresent(in) )
435     {
436     this->Modified();
437     this->DataObjectInputList->RemoveItem(in);
438     }
439 }
440
441 //----------------------------------------------------------------------------
442 // Plot scalar data for each input dataset.
443 int VISU_XYPlotActor::RenderOverlay(vtkViewport *viewport)
444 {
445   int renderedSomething = 0;
446
447   // Make sure input is up to date.
448   if ( this->InputList->GetNumberOfItems() < 1 && 
449        this->DataObjectInputList->GetNumberOfItems() < 1 )
450     {
451     vtkErrorMacro(<< "Nothing to plot!");
452     return 0;
453     }
454
455   renderedSomething += this->XAxis->RenderOverlay(viewport);
456   renderedSomething += this->YAxis->RenderOverlay(viewport);
457   if ( this->Title )
458     {
459     renderedSomething += this->TitleActor->RenderOverlay(viewport);
460     }
461   for (int i=0; i < this->NumberOfInputs; i++)
462     {
463     renderedSomething += this->PlotActor[i]->RenderOverlay(viewport);
464     }
465   if ( this->Legend )
466     {
467     renderedSomething += this->LegendActor->RenderOverlay(viewport);
468     }
469
470   return renderedSomething;
471 }
472
473 //----------------------------------------------------------------------------
474 // Plot scalar data for each input dataset.
475 int VISU_XYPlotActor::RenderOpaqueGeometry(vtkViewport *viewport)
476 {
477   unsigned long mtime, dsMtime;
478   vtkDataSet *ds;
479   vtkDataObject *dobj;
480   int numDS, numDO, renderedSomething=0;
481
482   // Initialize
483   // Make sure input is up to date.
484   numDS = this->InputList->GetNumberOfItems();
485   numDO = this->DataObjectInputList->GetNumberOfItems();
486   if ( numDS > 0 )
487     {
488     vtkDebugMacro(<<"Plotting input data sets");
489     vtkCollectionSimpleIterator dsit;
490     for (mtime=0, this->InputList->InitTraversal(dsit); 
491          (ds = this->InputList->GetNextDataSet(dsit)); )
492       {
493       ds->Update();
494       dsMtime = ds->GetMTime();
495       if ( dsMtime > mtime )
496         {
497         mtime = dsMtime;
498         }
499       }
500     }
501   else if ( numDO > 0 )
502     {
503     vtkDebugMacro(<<"Plotting input data objects");
504     vtkCollectionSimpleIterator doit;
505     for (mtime=0, this->DataObjectInputList->InitTraversal(doit); 
506          (dobj = this->DataObjectInputList->GetNextDataObject(doit)); )
507       {
508       dobj->Update();
509       dsMtime = dobj->GetMTime();
510       if ( dsMtime > mtime )
511         {
512         mtime = dsMtime;
513         }
514       }
515     }
516   else
517     {
518     vtkErrorMacro(<< "Nothing to plot!");
519     return 0;
520     }
521
522   if (this->Title && this->Title[0] && !this->TitleTextProperty)
523     {
524     vtkErrorMacro(<< "Need a title text property to render plot title");
525     return 0;
526     }
527
528   // Check modified time to see whether we have to rebuild.
529   // Pay attention that GetMTime() has been redefined (see below)
530
531   int *size=viewport->GetSize();
532   if (mtime > this->BuildTime || 
533       size[0] != this->CachedSize[0] || size[1] != this->CachedSize[1] ||
534       this->GetMTime() > this->BuildTime ||
535       (this->Title && this->Title[0] && 
536        this->TitleTextProperty->GetMTime() > this->BuildTime) ||
537       (this->AxisLabelTextProperty &&
538        this->AxisLabelTextProperty->GetMTime() > this->BuildTime) ||
539       (this->AxisTitleTextProperty &&
540        this->AxisTitleTextProperty->GetMTime() > this->BuildTime))
541     {
542     double range[2], yrange[2], xRange[2], yRange[2], interval, *lengths=NULL;
543     int pos[2], pos2[2], numTicks;
544     int stringSize[2];
545     int num = ( numDS > 0 ? numDS : numDO );
546
547     vtkDebugMacro(<<"Rebuilding plot");
548     this->CachedSize[0] = size[0];
549     this->CachedSize[1] = size[1];
550
551     // RKV : Begin
552     if ((this->PlotLocation == VISU_XYPLOT_RIGHT) || (this->PlotLocation == VISU_XYPLOT_LEFT))
553       this->ReverseYAxis = 1;
554     else
555       this->ReverseYAxis = 0;
556     // RKV : End
557
558     // manage legend
559     vtkDebugMacro(<<"Rebuilding legend");
560     if ( this->Legend )
561       {
562       int legPos[2], legPos2[2];
563       int *p1 = this->PositionCoordinate->GetComputedViewportValue(viewport);
564       int *p2 = this->Position2Coordinate->GetComputedViewportValue(viewport);
565       legPos[0] = (int)(p1[0] + this->LegendPosition[0]*(p2[0]-p1[0]));
566       legPos2[0] = (int)(legPos[0] + this->LegendPosition2[0]*(p2[0]-p1[0]));
567       legPos[1] = (int)(p1[1] + this->LegendPosition[1]*(p2[1]-p1[1]));
568       legPos2[1] = (int)(legPos[1] + this->LegendPosition2[1]*(p2[1]-p1[1]));
569       
570       this->LegendActor->GetPositionCoordinate()->SetValue(
571         (double)legPos[0], (double)legPos[1]);
572       this->LegendActor->GetPosition2Coordinate()->SetValue(
573         (double)legPos2[0], (double)legPos2[1]);
574       this->LegendActor->SetNumberOfEntries(num);
575       for (int i=0; i<num; i++)
576         {
577         if ( ! this->LegendActor->GetEntrySymbol(i) )
578           {
579           this->LegendActor->SetEntrySymbol(i,this->GlyphSource->GetOutput());
580           }
581         if ( ! this->LegendActor->GetEntryString(i) )
582           {
583           static char legendString[12];
584           sprintf(legendString, "%s%d", "Curve ", i);
585           this->LegendActor->SetEntryString(i,legendString);
586           }
587         }
588
589       this->LegendActor->SetPadding(2);
590       this->LegendActor->GetProperty()->DeepCopy(this->GetProperty());
591       this->LegendActor->ScalarVisibilityOff();
592       }
593
594     // Rebuid text props
595     // Perform shallow copy here since each individual axis can be
596     // accessed through the class API (i.e. each individual axis text prop
597     // can be changed). Therefore, we can not just assign pointers otherwise
598     // each individual axis text prop would point to the same text prop.
599
600     if (this->AxisLabelTextProperty &&
601         this->AxisLabelTextProperty->GetMTime() > this->BuildTime)
602       {
603       if (this->XAxis->GetLabelTextProperty())
604         {
605         this->XAxis->GetLabelTextProperty()->ShallowCopy(
606           this->AxisLabelTextProperty);
607         }
608       if (this->YAxis->GetLabelTextProperty())
609         {
610         this->YAxis->GetLabelTextProperty()->ShallowCopy(
611           this->AxisLabelTextProperty);
612         }
613       }
614     
615     if (this->AxisTitleTextProperty &&
616         this->AxisTitleTextProperty->GetMTime() > this->BuildTime)
617       {
618       if (this->XAxis->GetTitleTextProperty())
619         {
620         this->XAxis->GetTitleTextProperty()->ShallowCopy(
621           this->AxisTitleTextProperty);
622         }
623       if (this->YAxis->GetTitleTextProperty())
624         {
625         this->YAxis->GetTitleTextProperty()->ShallowCopy(
626           this->AxisTitleTextProperty);
627         }
628       }
629     
630     // setup x-axis
631     vtkDebugMacro(<<"Rebuilding x-axis");
632     
633     this->XAxis->SetTitle(this->XTitle);
634     this->XAxis->SetNumberOfLabels(this->NumberOfXLabels);
635     this->XAxis->SetProperty(this->GetProperty());
636
637     vtkDebugMacro(<<"xrange = (" << range[0] << ", " << range[1] << ")"); // RKV
638     lengths = new double[num];
639     if ( numDS > 0 ) //plotting data sets
640       {
641       this->ComputeXRange(range, lengths);
642       }
643     else
644       {
645       this->ComputeDORange(range, yrange, lengths);
646       }
647     if ( this->XRange[0] < this->XRange[1] )
648       {
649       range[0] = this->XRange[0];
650       range[1] = this->XRange[1];
651       }
652
653 /* RKV    vtkAxisActor2D::ComputeRange(range, xRange, this->NumberOfXLabels,
654                                  numTicks, interval);
655 */    // RKV : Begin
656     vtkDebugMacro(<<"XRange = (" << XRange[0] << ", " << XRange[1] << ")");
657     vtkDebugMacro(<<"xrange = (" << range[0] << ", " << range[1] << ")");
658     xRange[0] = range[0];
659     xRange[1] = range[1];
660     // RKV : End
661     if ( !this->ExchangeAxes )
662       {
663       this->XComputedRange[0] = xRange[0];
664       this->XComputedRange[1] = xRange[1];
665       if ( this->ReverseXAxis )
666         {
667         this->XAxis->SetRange(range[1],range[0]);
668         }
669       else
670         {
671         this->XAxis->SetRange(range[0],range[1]);
672         }
673       }
674     else
675       {
676       this->XComputedRange[1] = xRange[0];
677       this->XComputedRange[0] = xRange[1];
678       if ( this->ReverseYAxis )
679         {
680         this->XAxis->SetRange(range[0],range[1]);
681         }
682       else
683         {
684         this->XAxis->SetRange(range[1],range[0]);
685         }
686       }
687     
688     // setup y-axis
689     vtkDebugMacro(<<"Rebuilding y-axis");
690     this->YAxis->SetTitle(this->YTitle);
691     this->YAxis->SetNumberOfLabels(this->NumberOfYLabels);
692
693     vtkDebugMacro(<<"yrange = (" << yrange[0] << ", " << yrange[1] << ")"); // RKV
694     if ( this->YRange[0] >= this->YRange[1] )
695       {
696       if ( numDS > 0 ) //plotting data sets
697         {
698         this->ComputeYRange(yrange);
699         }
700       }
701     else
702       {
703       yrange[0] = this->YRange[0];
704       yrange[1] = this->YRange[1];
705       }
706 /* RKV   vtkAxisActor2D::ComputeRange(yrange, yRange, this->NumberOfYLabels,
707                                  numTicks, interval);
708 */
709     // RKV : Begin
710     vtkDebugMacro(<<"YRange = (" << YRange[0] << ", " << YRange[1] << ")");
711     vtkDebugMacro(<<"yrange = (" << yrange[0] << ", " << yrange[1] << ")");
712     yRange[0] = yrange[0];
713     yRange[1] = yrange[1];
714     // RKV : End
715     
716     if ( !this->ExchangeAxes )
717       {
718       this->YComputedRange[0] = yRange[0];
719       this->YComputedRange[1] = yRange[1];
720       if ( this->ReverseYAxis )
721         {
722         this->YAxis->SetRange(yrange[0],yrange[1]);
723         }
724       else
725         {
726         this->YAxis->SetRange(yrange[1],yrange[0]);
727         }
728       }
729     else
730       {
731       this->YComputedRange[1] = yRange[0];
732       this->YComputedRange[0] = yRange[1];
733       if ( this->ReverseXAxis )
734         {
735         this->YAxis->SetRange(yrange[1],yrange[0]);
736         }
737       else
738         {
739         this->YAxis->SetRange(yrange[0],yrange[1]);
740         }
741       }
742       
743
744     this->PlaceAxes(viewport, size, pos, pos2);
745     
746     // manage title
747     if (this->Title != NULL && this->Title[0])
748       {
749       this->TitleMapper->SetInput(this->Title);
750       if (this->TitleTextProperty->GetMTime() > this->BuildTime)
751         {
752         this->TitleMapper->GetTextProperty()->ShallowCopy(
753           this->TitleTextProperty);
754         }
755
756       
757 #if (VTK_XVERSION < 0x050100)
758       //VSV:  Function is not supported in VTK 5.2 and high
759       vtkAxisActor2D::SetFontSize(viewport, 
760                                   this->TitleMapper, 
761                                   size, 
762                                   1.0,
763                                   stringSize);
764 #endif
765       
766       this->TitleActor->GetPositionCoordinate()->SetValue(
767         pos[0] + 0.5 * (pos2[0] - pos[0]) - stringSize[0] / 2.0, 
768         pos2[1] - stringSize[1] / 2.0);
769
770       this->TitleActor->SetProperty(this->GetProperty());
771       }
772
773     vtkDebugMacro(<<"Creating Plot Data");
774     // Okay, now create the plot data and set up the pipeline
775     this->CreatePlotData(pos, pos2, xRange, yRange, lengths, numDS, numDO);
776     delete [] lengths;
777     
778     this->BuildTime.Modified();
779
780     }//if need to rebuild the plot
781
782   vtkDebugMacro(<<"Rendering Axes");
783   renderedSomething += this->XAxis->RenderOpaqueGeometry(viewport);
784   renderedSomething += this->YAxis->RenderOpaqueGeometry(viewport);
785   for (int i=0; i < this->NumberOfInputs; i++)
786     {
787     vtkDebugMacro(<<"Rendering plotactors");
788     renderedSomething += this->PlotActor[i]->RenderOpaqueGeometry(viewport);
789     }
790   if ( this->Title )
791     {
792     vtkDebugMacro(<<"Rendering titleactors");
793     renderedSomething += this->TitleActor->RenderOpaqueGeometry(viewport);
794     }
795   if ( this->Legend )
796     {
797     vtkDebugMacro(<<"Rendering legendeactors");
798     renderedSomething += this->LegendActor->RenderOpaqueGeometry(viewport);
799     }
800
801   return renderedSomething;
802 }
803
804 //----------------------------------------------------------------------------
805 const char *VISU_XYPlotActor::GetXValuesAsString()
806 {
807   switch (this->XValues)
808     {
809     case VTK_XYPLOT_INDEX:
810       return "Index";
811     case VTK_XYPLOT_ARC_LENGTH:
812       return "ArcLength";
813     case VTK_XYPLOT_NORMALIZED_ARC_LENGTH:
814       return "NormalizedArcLength";
815     default:
816       return "Value";
817     }
818 }
819
820 //----------------------------------------------------------------------------
821 const char *VISU_XYPlotActor::GetDataObjectPlotModeAsString()
822 {
823   if ( this->DataObjectPlotMode == VTK_XYPLOT_ROW )
824     {
825     return "Plot Rows";
826     }
827   else 
828     {
829     return "Plot Columns";
830     }
831 }
832
833 //----------------------------------------------------------------------------
834 // Release any graphics resources that are being consumed by this actor.
835 // The parameter window could be used to determine which graphic
836 // resources to release.
837 void VISU_XYPlotActor::ReleaseGraphicsResources(vtkWindow *win)
838 {
839   this->TitleActor->ReleaseGraphicsResources(win);
840   this->XAxis->ReleaseGraphicsResources(win);
841   this->YAxis->ReleaseGraphicsResources(win);
842   for (int i=0; i < this->NumberOfInputs; i++)
843     {
844     this->PlotActor[i]->ReleaseGraphicsResources(win);
845     }
846   this->LegendActor->ReleaseGraphicsResources(win);
847 }
848
849 //----------------------------------------------------------------------------
850 unsigned long VISU_XYPlotActor::GetMTime()
851 {
852   unsigned long mtime, mtime2;
853   mtime = this->vtkActor2D::GetMTime();
854
855   if (this->Legend)
856     {
857     mtime2 = this->LegendActor->GetMTime();
858     if (mtime2 > mtime)
859       {
860       mtime = mtime2;
861       }
862     }
863
864   return mtime;
865 }
866
867 //----------------------------------------------------------------------------
868 void VISU_XYPlotActor::PrintSelf(ostream& os, vtkIndent indent)
869 {
870   vtkIndent i2 = indent.GetNextIndent();
871   vtkDataSet *input;
872   char *array;
873   int component;
874   int idx, num;
875
876   this->Superclass::PrintSelf(os,indent);
877
878   vtkCollectionSimpleIterator dsit;
879   this->InputList->InitTraversal(dsit);
880   num = this->InputList->GetNumberOfItems();
881   os << indent << "DataSetInputs: " << endl;
882   for (idx = 0; idx < num; ++idx)
883     {
884     input = this->InputList->GetNextDataSet(dsit);
885     array = this->SelectedInputScalars[idx];
886     component = this->SelectedInputScalarsComponent->GetValue((vtkIdType)idx);
887     if (array == NULL)
888       {
889       os << i2 << "(" << input << ") Default Scalars,  Component = " << component << endl;
890       }
891     else
892       {
893       os << i2 << "(" << input << ") " << array << ",  Component = " << component << endl;
894       }
895     }
896
897   os << indent << "Input DataObjects:\n";
898   this->DataObjectInputList->PrintSelf(os,indent.GetNextIndent());
899   
900   if (this->TitleTextProperty)
901     {
902     os << indent << "Title Text Property:\n";
903     this->TitleTextProperty->PrintSelf(os,indent.GetNextIndent());
904     }
905   else
906     {
907     os << indent << "Title Text Property: (none)\n";
908     }
909
910   if (this->AxisTitleTextProperty)
911     {
912     os << indent << "Axis Title Text Property:\n";
913     this->AxisTitleTextProperty->PrintSelf(os,indent.GetNextIndent());
914     }
915   else
916     {
917     os << indent << "Axis Title Text Property: (none)\n";
918     }
919
920   if (this->AxisLabelTextProperty)
921     {
922     os << indent << "Axis Label Text Property:\n";
923     this->AxisLabelTextProperty->PrintSelf(os,indent.GetNextIndent());
924     }
925   else
926     {
927     os << indent << "Axis Label Text Property: (none)\n";
928     }
929
930   os << indent << "Data Object Plot Mode: " << this->GetDataObjectPlotModeAsString() << endl;
931
932   os << indent << "Title: " << (this->Title ? this->Title : "(none)") << "\n";
933   os << indent << "X Title: " 
934      << (this->XTitle ? this->XTitle : "(none)") << "\n";
935   os << indent << "Y Title: " 
936      << (this->YTitle ? this->YTitle : "(none)") << "\n";
937  
938   os << indent << "X Values: " << this->GetXValuesAsString() << endl;
939   os << indent << "Log X Values: " << (this->Logx ? "On\n" : "Off\n");
940
941   os << indent << "Plot global-points: " << (this->PlotPoints ? "On\n" : "Off\n");
942   os << indent << "Plot global-lines: " << (this->PlotLines ? "On\n" : "Off\n");
943   os << indent << "Plot per-curve points: " << (this->PlotCurvePoints ? "On\n" : "Off\n");
944   os << indent << "Plot per-curve lines: " << (this->PlotCurveLines ? "On\n" : "Off\n");
945   os << indent << "Exchange Axes: " << (this->ExchangeAxes ? "On\n" : "Off\n");
946   os << indent << "Reverse X Axis: " << (this->ReverseXAxis ? "On\n" : "Off\n");
947   os << indent << "Reverse Y Axis: " << (this->ReverseYAxis ? "On\n" : "Off\n");
948
949   os << indent << "Number Of X Labels: " << this->NumberOfXLabels << "\n";
950   os << indent << "Number Of Y Labels: " << this->NumberOfYLabels << "\n";
951
952   os << indent << "Label Format: " << this->LabelFormat << "\n";
953   os << indent << "Border: " << this->Border << "\n";
954   
955   os << indent << "X Range: ";
956   if ( this->XRange[0] >= this->XRange[1] )
957     {
958     os << indent << "(Automatically Computed)\n";
959     }
960   else
961     {
962     os << "(" << this->XRange[0] << ", " << this->XRange[1] << ")\n";
963     }
964
965   os << indent << "Y Range: ";
966   if ( this->XRange[0] >= this->YRange[1] )
967     {
968     os << indent << "(Automatically Computed)\n";
969     }
970   else
971     {
972     os << "(" << this->YRange[0] << ", " << this->YRange[1] << ")\n";
973     }
974
975   os << indent << "Viewport Coordinate: ("
976      << this->ViewportCoordinate[0] << ", " 
977      << this->ViewportCoordinate[1] << ")\n";
978
979   os << indent << "Plot Coordinate: ("
980      << this->PlotCoordinate[0] << ", " 
981      << this->PlotCoordinate[1] << ")\n";
982
983   os << indent << "Legend: " << (this->Legend ? "On\n" : "Off\n");
984   os << indent << "Legend Position: ("
985      << this->LegendPosition[0] << ", " 
986      << this->LegendPosition[1] << ")\n";
987   os << indent << "Legend Position2: ("
988      << this->LegendPosition2[0] << ", " 
989      << this->LegendPosition2[1] << ")\n";
990
991   os << indent << "Glyph Size: " << this->GlyphSize << endl;
992
993   os << indent << "Legend Actor:";
994   this->LegendActor->PrintSelf( os << endl, i2);
995   os << indent << "Glyph Source:";
996   this->GlyphSource->PrintSelf( os << endl, i2);
997 }
998
999 //----------------------------------------------------------------------------
1000 void VISU_XYPlotActor::ComputeXRange(double range[2], double *lengths)
1001 {
1002   int dsNum;
1003   vtkIdType numPts, ptId, maxNum;
1004   double maxLength=0.0, xPrev[3], x[3];
1005   vtkDataSet *ds;
1006
1007   range[0] = VTK_DOUBLE_MAX, range[1] = VTK_DOUBLE_MIN;
1008
1009   vtkCollectionSimpleIterator dsit;
1010   for ( dsNum=0, maxNum=0, this->InputList->InitTraversal(dsit); 
1011         (ds = this->InputList->GetNextDataSet(dsit)); dsNum++)
1012     {
1013     numPts = ds->GetNumberOfPoints();
1014     if (numPts == 0)
1015       {
1016       vtkErrorMacro(<<"No scalar data to plot!");
1017       continue;
1018       }
1019
1020     if ( this->XValues != VTK_XYPLOT_INDEX )
1021       {
1022       ds->GetPoint(0, xPrev);
1023       for ( lengths[dsNum]=0.0, ptId=0; ptId < numPts; ptId++ )
1024         {
1025         ds->GetPoint(ptId, x);
1026         switch (this->XValues)
1027           {
1028           case VTK_XYPLOT_VALUE:
1029             if (this->GetLogx() == 0)
1030               {
1031               if ( x[this->XComponent->GetValue(dsNum)] < range[0] )
1032                 {
1033                 range[0] = x[this->XComponent->GetValue(dsNum)];
1034                 }
1035               if ( x[this->XComponent->GetValue(dsNum)] > range[1] )
1036                 {
1037                 range[1] = x[this->XComponent->GetValue(dsNum)];
1038                 }
1039               }
1040             else
1041               {
1042               //ensure range strictly > 0 for log
1043               if ( (x[this->XComponent->GetValue(dsNum)]) < range[0] && 
1044                    (x[this->XComponent->GetValue(dsNum)] > 0))
1045                 {
1046                 range[0] = x[this->XComponent->GetValue(dsNum)];
1047                 }
1048               if ( (x[this->XComponent->GetValue(dsNum)] > range[1]) && 
1049                    (x[this->XComponent->GetValue(dsNum)] > 0))
1050                 {
1051                 range[1] = x[this->XComponent->GetValue(dsNum)];
1052                 }
1053               }
1054             break;
1055           default:
1056             lengths[dsNum] += sqrt(vtkMath::Distance2BetweenPoints(x,xPrev));
1057             xPrev[0] = x[0]; xPrev[1] = x[1]; xPrev[2] = x[2];
1058           }
1059         }//for all points
1060       if ( lengths[dsNum] > maxLength )
1061         {
1062         maxLength = lengths[dsNum];
1063         }
1064       }//if need to visit all points
1065     
1066     else //if ( this->XValues == VTK_XYPLOT_INDEX )
1067       {
1068       if ( numPts > maxNum )
1069         {
1070         maxNum = numPts;
1071         }
1072       }
1073     }//over all datasets
1074
1075   // determine the range
1076   switch (this->XValues)
1077     {
1078     case VTK_XYPLOT_ARC_LENGTH:
1079       range[0] = 0.0;
1080       range[1] = maxLength;
1081       break;
1082     case VTK_XYPLOT_NORMALIZED_ARC_LENGTH:
1083       range[0] = 0.0;
1084       range[1] = 1.0;
1085       break;
1086     case VTK_XYPLOT_INDEX:
1087       range[0] = 0.0;
1088       range[1] = (double)(maxNum - 1);
1089       break;
1090     case VTK_XYPLOT_VALUE:
1091       if (this->GetLogx() == 1)
1092         {
1093         if (range[0] > range[1]) 
1094           {
1095           range[0] = 0;
1096           range[1] = 0;
1097           }
1098         else
1099           {
1100           range[0] = log10(range[0]);
1101           range[1] = log10(range[1]);
1102           }
1103         }
1104       break; //range computed in for loop above
1105     default:
1106       vtkErrorMacro(<< "Unkown X-Value option.");
1107       return;
1108     }
1109 }
1110
1111 //----------------------------------------------------------------------------
1112 void VISU_XYPlotActor::ComputeYRange(double range[2])
1113 {
1114   vtkDataSet *ds;
1115   vtkDataArray *scalars;
1116   double sRange[2];
1117   int count;
1118   int component;
1119
1120   range[0]=VTK_DOUBLE_MAX, range[1]=VTK_DOUBLE_MIN;
1121
1122   vtkCollectionSimpleIterator dsit;
1123   for ( this->InputList->InitTraversal(dsit), count = 0; 
1124         (ds = this->InputList->GetNextDataSet(dsit)); ++count)
1125     {
1126     scalars = ds->GetPointData()->GetScalars(this->SelectedInputScalars[count]);
1127     component = this->SelectedInputScalarsComponent->GetValue(count);
1128     if ( !scalars)
1129       {
1130       vtkErrorMacro(<<"No scalar data to plot!");
1131       continue;
1132       }
1133     if ( component < 0 || component >= scalars->GetNumberOfComponents())
1134       {
1135       vtkErrorMacro(<<"Bad component!");
1136       continue;
1137       }
1138     
1139     scalars->GetRange(sRange, component);
1140     if ( sRange[0] < range[0] )
1141       {
1142       range[0] = sRange[0];
1143       }
1144
1145     if ( sRange[1] > range[1] )
1146       {
1147       range[1] = sRange[1];
1148       }
1149     }//over all datasets
1150 }
1151
1152 //----------------------------------------------------------------------------
1153 static inline int VISU_XYPlotActorGetComponent(vtkFieldData* field,
1154   vtkIdType tuple, int component, double* val)
1155 {
1156   int array_comp;
1157   int array_index = field->GetArrayContainingComponent(component, array_comp);
1158   if (array_index < 0)
1159     {
1160     return 0;
1161     }
1162   vtkDataArray* da = field->GetArray(array_index);
1163   if (!da)
1164     {
1165     // non-numeric array.
1166     return 0;
1167     }
1168   *val = da->GetComponent(tuple, array_comp);
1169   return 1;
1170 }
1171
1172 //----------------------------------------------------------------------------
1173 void VISU_XYPlotActor::ComputeDORange(double xrange[2], double yrange[2], 
1174                                     double *lengths)
1175 {
1176   int i;
1177   vtkDataObject *dobj;
1178   vtkFieldData *field;
1179   int doNum, numColumns;
1180   vtkIdType numTuples, numRows, num, ptId, maxNum;
1181   double maxLength=0.0;
1182   double x = 0.0;
1183   double y = 0.0;
1184   double xPrev = 0.0;
1185   vtkDataArray *array;
1186   
1187   // NOTE: FieldData can have non-numeric arrays. However, XY plot can only 
1188   // work on numeric arrays (or vtkDataArray subclasses). 
1189   
1190   xrange[0] = yrange[0] = VTK_DOUBLE_MAX;
1191   xrange[1] = yrange[1] = -VTK_DOUBLE_MAX;
1192   vtkCollectionSimpleIterator doit;
1193   for ( doNum=0, maxNum=0, this->DataObjectInputList->InitTraversal(doit); 
1194         (dobj = this->DataObjectInputList->GetNextDataObject(doit)); doNum++)
1195     {
1196
1197     lengths[doNum] = 0.0;
1198     field = dobj->GetFieldData();
1199     numColumns = field->GetNumberOfComponents();  //number of "columns"
1200       // numColumns includes the components for non-numeric arrays as well.
1201     for (numRows = VTK_LARGE_ID, i=0; i<field->GetNumberOfArrays(); i++)
1202       {
1203       array = field->GetArray(i);
1204       if (!array)
1205         {
1206         // non-numeric array, skip.
1207         continue;
1208         }
1209       numTuples = array->GetNumberOfTuples();
1210       if ( numTuples < numRows )
1211         {
1212         numRows = numTuples;
1213         }
1214       }
1215
1216     num = (this->DataObjectPlotMode == VTK_XYPLOT_ROW ? 
1217            numColumns : numRows);
1218
1219     if ( this->XValues != VTK_XYPLOT_INDEX )
1220       {
1221       // gather the information to form a plot
1222       for ( ptId=0; ptId < num; ptId++ )
1223         {
1224         int status = 0;
1225       
1226         if ( this->DataObjectPlotMode == VTK_XYPLOT_ROW )
1227           {
1228           // x = field->GetComponent(this->XComponent->GetValue(doNum), ptId);
1229           status = ::VISU_XYPlotActorGetComponent(field,
1230             this->XComponent->GetValue(doNum), ptId, &x);
1231           }
1232         else //if ( this->DataObjectPlotMode == VTK_XYPLOT_COLUMN )
1233           {
1234           // x = field->GetComponent(ptId, this->XComponent->GetValue(doNum));
1235           status = ::VISU_XYPlotActorGetComponent(field,
1236             ptId, this->XComponent->GetValue(doNum), &x);
1237           }
1238         if (!status)
1239           {
1240           // requested component falls in a non-numeric array, skip it.
1241           continue;
1242           }
1243         if ( ptId == 0 )
1244           {
1245           xPrev = x;
1246           }
1247               
1248         switch (this->XValues)
1249           {
1250           case VTK_XYPLOT_VALUE:
1251             if (this->GetLogx() == 0)
1252               {
1253               if ( x < xrange[0] )
1254                 {
1255                 xrange[0] = x;
1256                 }
1257               if ( x > xrange[1] )
1258                 {
1259                 xrange[1] = x;
1260                 }
1261               }
1262             else //ensure positive values
1263               {
1264               if ( (x < xrange[0]) && (x > 0) )
1265                 {
1266                 xrange[0] = x;
1267                 }
1268               if ( x > xrange[1]  && (x > 0) )
1269                 {
1270                 xrange[1] = x;
1271                 }
1272               }
1273             break;
1274           default:
1275             lengths[doNum] += fabs(x-xPrev);
1276             xPrev = x;
1277           }
1278         }//for all points
1279       if ( lengths[doNum] > maxLength )
1280         {
1281         maxLength = lengths[doNum];
1282         }
1283       }//if all data has to be visited
1284     
1285     else //if (this->XValues == VTK_XYPLOT_INDEX)
1286       {
1287       if ( num > maxNum )
1288         {
1289         maxNum = num;
1290         }
1291       }
1292
1293     // Get the y-values
1294     for ( ptId=0; ptId < num; ptId++ )
1295       {
1296       int status = 0;
1297       if ( this->DataObjectPlotMode == VTK_XYPLOT_ROW )
1298         {
1299         //y = field->GetComponent(this->YComponent->GetValue(doNum), ptId);
1300         status = ::VISU_XYPlotActorGetComponent(field,
1301           this->YComponent->GetValue(doNum), ptId, &y);
1302         }
1303       else //if ( this->DataObjectPlotMode == VTK_XYPLOT_COLUMN )
1304         {
1305         //y = field->GetComponent(ptId, this->YComponent->GetValue(doNum));
1306         status = ::VISU_XYPlotActorGetComponent(field,
1307           ptId, this->YComponent->GetValue(doNum), &y);
1308         }
1309       if (!status)
1310         {
1311         // requested component falls in non-numeric array.
1312         // skip.
1313         continue;
1314         }
1315       if ( y < yrange[0] )
1316         {
1317         yrange[0] = y;
1318         }
1319       if ( y > yrange[1] )
1320         {
1321         yrange[1] = y;
1322         }
1323       }//over all y values
1324     }//over all dataobjects
1325
1326   // determine the range
1327   switch (this->XValues)
1328     {
1329     case VTK_XYPLOT_ARC_LENGTH:
1330       xrange[0] = 0.0;
1331       xrange[1] = maxLength;
1332       break;
1333     case VTK_XYPLOT_NORMALIZED_ARC_LENGTH:
1334       xrange[0] = 0.0;
1335       xrange[1] = 1.0;
1336       break;
1337     case VTK_XYPLOT_INDEX:
1338       xrange[0] = 0.0;
1339       xrange[1] = (double)(maxNum - 1);
1340       break;
1341     case VTK_XYPLOT_VALUE:
1342       if (this->GetLogx() == 1)
1343         {
1344         xrange[0] = log10(xrange[0]);
1345         xrange[1] = log10(xrange[1]);
1346         }
1347       break;
1348     default:
1349       vtkErrorMacro(<< "Unknown X-Value option");
1350       return;
1351     }
1352 }
1353
1354 //----------------------------------------------------------------------------
1355 /* RKV void VISU_XYPlotActor::CreatePlotData(int *pos, int *pos2, double xRange[2], 
1356                                     double yRange[2], double *lengths,
1357                                     int numDS, int numDO) */
1358 // RKV : Begin
1359 void VISU_XYPlotActor::CreatePlotData(int *pos, int *pos2Extern, double xRange[2], 
1360                                     double yRange[2], double *lengths,
1361                                     int numDS, int numDO)
1362 // RKV : End
1363 {
1364   double xyz[3]; xyz[2] = 0.0;
1365   int i, numLinePts, dsNum, doNum, num;
1366   vtkIdType numPts, ptId, id;
1367   double length, x[3], xPrev[3];
1368   vtkDataArray *scalars;
1369   int component;
1370   vtkDataSet *ds;
1371   vtkCellArray *lines;
1372   vtkPoints *pts;
1373   int clippingRequired = 0;
1374
1375   // Allocate resources for the polygonal plots
1376   //
1377   num = (numDS > numDO ? numDS : numDO);
1378   this->InitializeEntries();
1379   this->NumberOfInputs = num;
1380   this->PlotData = new vtkPolyData* [num];
1381   this->PlotGlyph = new vtkGlyph2D* [num];
1382   this->PlotAppend = new vtkAppendPolyData* [num];
1383   this->PlotTransform = new vtkTransformPolyDataFilter* [num]; // RKV
1384   this->PlotMapper = new vtkPolyDataMapper2D* [num];
1385   this->PlotActor = new vtkActor2D* [num];
1386   
1387   // RKV : Begin
1388   // Prepare the transformation of the curve according to the plot location
1389   vtkTransform *tf = vtkTransform::New();
1390   tf->Translate(pos[0], pos[1], 0);
1391   if ((this->PlotLocation == VISU_XYPLOT_LEFT) || (this->PlotLocation == VISU_XYPLOT_RIGHT))
1392     tf->RotateZ(90);
1393   tf->Translate(-pos[0], -pos[1], 0);
1394   
1395   // Compute the position2 to build the curve before the transformation
1396   int pos2[2];
1397   vtkDebugMacro(<< "pos = (" << pos[0] << ", " << pos[1] << ")"); 
1398   vtkDebugMacro(<< "pos2 = (" << pos2Extern[0] << ", " << pos2Extern[1] << ")"); 
1399   if ((this->PlotLocation == VISU_XYPLOT_LEFT) || (this->PlotLocation == VISU_XYPLOT_RIGHT))
1400     {
1401     pos2[0] = pos[0] + pos2Extern[1] - pos[1];
1402     pos2[1] = pos[1] + pos[0] - pos2Extern[0];
1403     }
1404   else
1405     {
1406     pos2[0] = pos2Extern[0];
1407     pos2[1] = pos2Extern[1];
1408     }
1409   // RKV : End
1410   
1411   for (i=0; i<num; i++)
1412     {
1413     this->PlotData[i] = vtkPolyData::New();
1414     this->PlotGlyph[i] = vtkGlyph2D::New();
1415     this->PlotGlyph[i]->SetInput(this->PlotData[i]);
1416     this->PlotGlyph[i]->SetScaleModeToDataScalingOff();
1417     this->PlotAppend[i] = vtkAppendPolyData::New();
1418     this->PlotAppend[i]->AddInput(this->PlotData[i]);
1419     if ( this->LegendActor->GetEntrySymbol(i) != NULL &&
1420          this->LegendActor->GetEntrySymbol(i) != this->GlyphSource->GetOutput() )
1421       {
1422       this->PlotGlyph[i]->SetSource(this->LegendActor->GetEntrySymbol(i));
1423       this->PlotGlyph[i]->SetScaleFactor(this->ComputeGlyphScale(i,pos,pos2));
1424       this->PlotAppend[i]->AddInput(this->PlotGlyph[i]->GetOutput());
1425       }
1426     this->PlotMapper[i] = vtkPolyDataMapper2D::New();
1427     
1428     // RKV : Begin
1429     // Insert a transformation filter into the pipeline to 
1430     // take into account a plot location.
1431     this->PlotTransform[i] = vtkTransformPolyDataFilter::New();
1432     this->PlotTransform[i]->SetInput(this->PlotAppend[i]->GetOutput());
1433     this->PlotTransform[i]->SetTransform(tf); 
1434     this->PlotMapper[i]->SetInput(this->PlotTransform[i]->GetOutput());
1435     // RKV : End
1436     
1437 // RKV    this->PlotMapper[i]->SetInput(this->PlotAppend[i]->GetOutput());
1438     this->PlotMapper[i]->ScalarVisibilityOff();
1439     this->PlotActor[i] = vtkActor2D::New();
1440     this->PlotActor[i]->SetMapper(this->PlotMapper[i]);
1441     this->PlotActor[i]->GetProperty()->DeepCopy(this->GetProperty());
1442     if ( this->LegendActor->GetEntryColor(i)[0] < 0.0 )
1443       {
1444       this->PlotActor[i]->GetProperty()->SetColor(
1445         this->GetProperty()->GetColor());
1446       }
1447     else
1448       {
1449       this->PlotActor[i]->GetProperty()->SetColor(
1450         this->LegendActor->GetEntryColor(i));
1451       }
1452     }
1453     
1454   tf->Delete(); // RKV
1455
1456   // Prepare to receive data
1457   this->GenerateClipPlanes(pos,pos2);
1458   for (i=0; i<this->NumberOfInputs; i++)
1459     {
1460     lines = vtkCellArray::New();
1461     pts = vtkPoints::New();
1462
1463     lines->Allocate(10,10);
1464     pts->Allocate(10,10);
1465     this->PlotData[i]->SetPoints(pts);
1466     this->PlotData[i]->SetVerts(lines);
1467     this->PlotData[i]->SetLines(lines);
1468
1469     pts->Delete();
1470     lines->Delete();
1471     }
1472    
1473   // Okay, for each input generate plot data. Depending on the input
1474   // we use either dataset or data object.
1475   //
1476   if ( numDS > 0 )
1477     {
1478     vtkCollectionSimpleIterator dsit;
1479     for ( dsNum=0, this->InputList->InitTraversal(dsit); 
1480           (ds = this->InputList->GetNextDataSet(dsit)); dsNum++ )
1481       {
1482       clippingRequired = 0;
1483       numPts = ds->GetNumberOfPoints();
1484       scalars = ds->GetPointData()->GetScalars(this->SelectedInputScalars[dsNum]);
1485       if ( !scalars)
1486         {
1487         continue;
1488         }
1489       component = this->SelectedInputScalarsComponent->GetValue(dsNum);
1490       if ( component < 0 || component >= scalars->GetNumberOfComponents())
1491         {
1492         continue;
1493         }
1494
1495       pts = this->PlotData[dsNum]->GetPoints();
1496       lines = this->PlotData[dsNum]->GetLines();
1497       lines->InsertNextCell(0); //update the count later
1498
1499       ds->GetPoint(0, xPrev);
1500       for ( numLinePts=0, length=0.0, ptId=0; ptId < numPts; ptId++ )
1501         {
1502         xyz[1] = scalars->GetComponent(ptId, component);
1503         ds->GetPoint(ptId, x);
1504         switch (this->XValues)
1505           {
1506           case VTK_XYPLOT_NORMALIZED_ARC_LENGTH:
1507             length += sqrt(vtkMath::Distance2BetweenPoints(x,xPrev));
1508             xyz[0] = length / lengths[dsNum];
1509             xPrev[0] = x[0]; xPrev[1] = x[1]; xPrev[2] = x[2];
1510             break;
1511           case VTK_XYPLOT_INDEX:
1512             xyz[0] = (double)ptId;
1513             break;
1514           case VTK_XYPLOT_ARC_LENGTH:
1515             length += sqrt(vtkMath::Distance2BetweenPoints(x,xPrev));
1516             xyz[0] = length;
1517             xPrev[0] = x[0]; xPrev[1] = x[1]; xPrev[2] = x[2];
1518             break;
1519           case VTK_XYPLOT_VALUE:
1520             xyz[0] = x[this->XComponent->GetValue(dsNum)];
1521             break;
1522           default:
1523             vtkErrorMacro(<< "Unknown X-Component option");
1524           }
1525         
1526         if ( this->GetLogx() == 1 )
1527           {
1528           if (xyz[0] > 0)
1529             {
1530             xyz[0] = log10(xyz[0]);
1531             // normalize and position
1532             if ( xyz[0] < xRange[0] || xyz[0] > xRange[1] ||
1533                  xyz[1] < yRange[0] || xyz[1] > yRange[1] )
1534               {
1535               clippingRequired = 1;
1536               }
1537
1538             numLinePts++;
1539             xyz[0] = fabs( xRange[1] - xRange[0] ) < 1.0 / VTK_LARGE_FLOAT ? pos[0] : pos[0] + 
1540               (xyz[0]-xRange[0])/(xRange[1]-xRange[0])*(pos2[0]-pos[0]);
1541             xyz[1] = fabs( yRange[1] - yRange[0] ) < 1.0 / VTK_LARGE_FLOAT ? pos[1] : pos[1] + 
1542               (xyz[1]-yRange[0])/(yRange[1]-yRange[0])*(pos2[1]-pos[1]);
1543             id = pts->InsertNextPoint(xyz);
1544             lines->InsertCellPoint(id);
1545             }
1546           } 
1547         else
1548           {
1549           // normalize and position
1550           if ( xyz[0] < xRange[0] || xyz[0] > xRange[1] ||
1551                xyz[1] < yRange[0] || xyz[1] > yRange[1] )
1552             {
1553             clippingRequired = 1;
1554             }
1555
1556           numLinePts++;
1557           xyz[0] = fabs( xRange[1] - xRange[0] ) < 1.0 / VTK_LARGE_FLOAT ? pos[0] : pos[0] + 
1558             (xyz[0]-xRange[0])/(xRange[1]-xRange[0])*(pos2[0]-pos[0]);
1559           xyz[1] = fabs( yRange[1] - yRange[0] ) < 1.0 / VTK_LARGE_FLOAT ? pos[1] : pos[1] + 
1560             (xyz[1]-yRange[0])/(yRange[1]-yRange[0])*(pos2[1]-pos[1]);
1561           id = pts->InsertNextPoint(xyz);
1562           lines->InsertCellPoint(id);
1563           }
1564         }//for all input points
1565
1566       lines->UpdateCellCount(numLinePts);
1567       if ( clippingRequired )
1568         {
1569         this->ClipPlotData(pos,pos2,this->PlotData[dsNum]);
1570         }
1571       }//loop over all input data sets
1572     }//if plotting datasets
1573
1574   else //plot data from data objects
1575     {
1576     vtkDataObject *dobj;
1577     int numColumns;
1578     vtkIdType numRows, numTuples;
1579     vtkDataArray *array;
1580     vtkFieldData *field;
1581     vtkCollectionSimpleIterator doit;
1582     for ( doNum=0, this->DataObjectInputList->InitTraversal(doit); 
1583           (dobj = this->DataObjectInputList->GetNextDataObject(doit)); 
1584           doNum++ )
1585       {
1586       // determine the shape of the field
1587       field = dobj->GetFieldData();
1588       numColumns = field->GetNumberOfComponents(); //number of "columns"
1589       // numColumns also includes non-numeric array components.
1590       for (numRows = VTK_LARGE_ID, i=0; i<field->GetNumberOfArrays(); i++)
1591         {
1592         array = field->GetArray(i);
1593         if (!array)
1594           {
1595           // skip non-numeric arrays.
1596           continue;
1597           }
1598         numTuples = array->GetNumberOfTuples();
1599         if ( numTuples < numRows )
1600           {
1601           numRows = numTuples;
1602           }
1603         }
1604
1605       pts = this->PlotData[doNum]->GetPoints();
1606       lines = this->PlotData[doNum]->GetLines();
1607       lines->InsertNextCell(0); //update the count later
1608
1609       numPts = (this->DataObjectPlotMode == VTK_XYPLOT_ROW ? 
1610                 numColumns : numRows);
1611
1612       // gather the information to form a plot
1613       for ( numLinePts=0, length=0.0, ptId=0; ptId < numPts; ptId++ )
1614         {
1615         int status1, status2;
1616         if ( this->DataObjectPlotMode == VTK_XYPLOT_ROW )
1617           {
1618           //x[0] = field->GetComponent(this->XComponent->GetValue(doNum),ptId);
1619           //xyz[1] = field->GetComponent(this->YComponent->GetValue(doNum),ptId);
1620           status1 = ::VISU_XYPlotActorGetComponent(field,
1621             this->XComponent->GetValue(doNum), ptId, &x[0]);
1622           status2 = ::VISU_XYPlotActorGetComponent(field,
1623             this->YComponent->GetValue(doNum), ptId, &xyz[1]);
1624           }
1625         else //if ( this->DataObjectPlotMode == VTK_XYPLOT_COLUMN )
1626           {
1627           //x[0] = field->GetComponent(ptId, this->XComponent->GetValue(doNum));
1628           //xyz[1] = field->GetComponent(ptId, this->YComponent->GetValue(doNum));
1629
1630           status1 = ::VISU_XYPlotActorGetComponent(field,
1631             ptId, this->XComponent->GetValue(doNum), &x[0]);
1632
1633           if (!status1)
1634             {
1635             vtkWarningMacro(<< this->XComponent->GetValue(doNum) << " is a non-numeric component.");
1636             }
1637           
1638           status2 = ::VISU_XYPlotActorGetComponent(field,
1639             ptId, this->YComponent->GetValue(doNum), &xyz[1]);
1640
1641           if (!status2)
1642             {
1643             vtkWarningMacro(<< this->YComponent->GetValue(doNum) << " is a non-numeric component.");
1644             }
1645           }
1646         if (!status1 || !status2)
1647           {
1648           // component is non-numeric.
1649           // Skip it.
1650           continue;
1651           }
1652
1653         switch (this->XValues)
1654           {
1655           case VTK_XYPLOT_NORMALIZED_ARC_LENGTH:
1656             length += fabs(x[0]-xPrev[0]);
1657             xyz[0] = length / lengths[doNum];
1658             xPrev[0] = x[0];
1659             break;
1660           case VTK_XYPLOT_INDEX:
1661             xyz[0] = (double)ptId;
1662             break;
1663           case VTK_XYPLOT_ARC_LENGTH:
1664             length += fabs(x[0]-xPrev[0]);
1665             xyz[0] = length;
1666             xPrev[0] = x[0];
1667             break;
1668           case VTK_XYPLOT_VALUE:
1669             xyz[0] = x[0];
1670             break;
1671           default:
1672             vtkErrorMacro(<< "Unknown X-Value option");
1673           }
1674
1675         if ( this->GetLogx() == 1 )
1676           {
1677           if (xyz[0] > 0)
1678             {
1679             xyz[0] = log10(xyz[0]);
1680             // normalize and position
1681             if ( xyz[0] < xRange[0] || xyz[0] > xRange[1] ||
1682                  xyz[1] < yRange[0] || xyz[1] > yRange[1] )
1683               {
1684               clippingRequired = 1;
1685               }
1686             numLinePts++;
1687             xyz[0] = fabs( xRange[1] - xRange[0] ) < 1.0 / VTK_LARGE_FLOAT ? pos[0] : pos[0] + 
1688               (xyz[0]-xRange[0])/(xRange[1]-xRange[0])*(pos2[0]-pos[0]);
1689             xyz[1] = fabs( yRange[1] - yRange[0] ) < 1.0 / VTK_LARGE_FLOAT ? pos[1] : pos[1] + 
1690               (xyz[1]-yRange[0])/(yRange[1]-yRange[0])*(pos2[1]-pos[1]);
1691             id = pts->InsertNextPoint(xyz);
1692             lines->InsertCellPoint(id);
1693             }
1694           } 
1695         else
1696           {
1697           // normalize and position
1698           if ( xyz[0] < xRange[0] || xyz[0] > xRange[1] ||
1699                xyz[1] < yRange[0] || xyz[1] > yRange[1] )
1700             {
1701             clippingRequired = 1;
1702             }    
1703           numLinePts++;
1704           xyz[0] = fabs( xRange[1] - xRange[0] ) < 1.0 / VTK_LARGE_FLOAT ? pos[0] : pos[0] +
1705             (xyz[0]-xRange[0])/(xRange[1]-xRange[0])*(pos2[0]-pos[0]);
1706           xyz[1] = fabs( yRange[1] - yRange[0] ) < 1.0 / VTK_LARGE_FLOAT ? pos[1] : pos[1] +
1707             (xyz[1]-yRange[0])/(yRange[1]-yRange[0])*(pos2[1]-pos[1]);
1708           id = pts->InsertNextPoint(xyz);
1709           lines->InsertCellPoint(id);
1710           }
1711         }//for all input points
1712
1713       lines->UpdateCellCount(numLinePts);
1714       if ( clippingRequired )
1715         {
1716         this->ClipPlotData(pos,pos2,this->PlotData[doNum]);
1717         }
1718       }//loop over all input data sets
1719     }
1720   
1721   // Remove points/lines as directed by the user
1722   for ( i = 0; i < num; i++)
1723     {
1724     if (!this->PlotCurveLines) 
1725       {
1726       if ( !this->PlotLines ) 
1727         {
1728         this->PlotData[i]->SetLines(NULL);
1729         }
1730       }
1731     else
1732       {
1733       if ( this->GetPlotLines(i) == 0)
1734         {
1735         this->PlotData[i]->SetLines(NULL);
1736         }
1737       }
1738
1739     if (!this->PlotCurvePoints) 
1740       {
1741       if ( !this->PlotPoints || (this->LegendActor->GetEntrySymbol(i) &&
1742                                  this->LegendActor->GetEntrySymbol(i) != 
1743                                  this->GlyphSource->GetOutput()))
1744         {
1745         this->PlotData[i]->SetVerts(NULL);
1746         }
1747       }
1748     else
1749       {
1750       if ( this->GetPlotPoints(i) == 0 || 
1751           (this->LegendActor->GetEntrySymbol(i) &&
1752            this->LegendActor->GetEntrySymbol(i) != 
1753            this->GlyphSource->GetOutput()))
1754         {
1755         this->PlotData[i]->SetVerts(NULL);
1756         }
1757       }
1758     }
1759 }
1760
1761 //----------------------------------------------------------------------------
1762 // Position the axes taking into account the expected padding due to labels
1763 // and titles. We want the result to fit in the box specified. This method
1764 // knows something about how the vtkAxisActor2D functions, so it may have 
1765 // to change if that class changes dramatically.
1766 //
1767 void VISU_XYPlotActor::PlaceAxes(vtkViewport *viewport, int *size,
1768                                int pos[2], int pos2[2])
1769 {
1770   int titleSizeX[2], titleSizeY[2], labelSizeX[2], labelSizeY[2];
1771   double labelFactorX, labelFactorY;
1772   double fontFactorX, fontFactorY;
1773   double tickOffsetX, tickOffsetY;
1774   double tickLengthX, tickLengthY;
1775
1776   vtkAxisActor2D *axisX;
1777   vtkAxisActor2D *axisY;
1778
1779   char str1[512], str2[512];
1780
1781   if (this->ExchangeAxes)
1782     {
1783     axisX = this->YAxis;
1784     axisY = this->XAxis;
1785     }
1786   else
1787     {
1788     axisX = this->XAxis;
1789     axisY = this->YAxis;
1790     }
1791
1792   // RKV : Begin
1793   // Take into account a location of the plot.
1794   if ((this->PlotLocation == VISU_XYPLOT_LEFT) || (this->PlotLocation == VISU_XYPLOT_RIGHT))
1795     {
1796     vtkAxisActor2D *axisBid;
1797     axisBid = axisX;
1798     axisX = axisY;
1799     axisY = axisBid;
1800     }
1801     
1802   // RKV : End
1803   
1804   fontFactorY = axisY->GetFontFactor();
1805   fontFactorX = axisX->GetFontFactor();
1806
1807   labelFactorY = axisY->GetLabelFactor();
1808   labelFactorX = axisX->GetLabelFactor();
1809
1810   // Create a dummy text mapper for getting font sizes
1811   vtkTextMapper *textMapper = vtkTextMapper::New();
1812   vtkTextProperty *tprop = textMapper->GetTextProperty();
1813
1814   // Get the location of the corners of the box
1815   int *p1 = this->PositionCoordinate->GetComputedViewportValue(viewport);
1816   int *p2 = this->Position2Coordinate->GetComputedViewportValue(viewport);
1817
1818   // Estimate the padding around the X and Y axes
1819   tprop->ShallowCopy(axisX->GetTitleTextProperty());
1820   textMapper->SetInput(axisX->GetTitle());
1821     
1822 #if (VTK_XVERSION < 0x050100)
1823   //VSV:  Function is not supported in VTK 5.2 and high
1824   vtkAxisActor2D::SetFontSize(
1825     viewport, textMapper, size, fontFactorX, titleSizeX);
1826 #endif
1827       
1828   tprop->ShallowCopy(axisY->GetTitleTextProperty());
1829   textMapper->SetInput(axisY->GetTitle());
1830      
1831 #if (VTK_XVERSION < 0x050100)
1832   //VSV:  Function is not supported in VTK 5.2 and high
1833   vtkAxisActor2D::SetFontSize(
1834     viewport, textMapper, size, fontFactorY, titleSizeY);
1835 #endif
1836       
1837   // At this point the thing to do would be to actually ask the Y axis
1838   // actor to return the largest label.
1839   // In the meantime, let's try with the min and max
1840   sprintf(str1, axisY->GetLabelFormat(), axisY->GetAdjustedRange()[0]);
1841   sprintf(str2, axisY->GetLabelFormat(), axisY->GetAdjustedRange()[1]);
1842   tprop->ShallowCopy(axisY->GetLabelTextProperty());
1843   textMapper->SetInput(strlen(str1) > strlen(str2) ? str1 : str2);
1844       
1845 #if (VTK_XVERSION < 0x050100)
1846   //VSV:  Function is not supported in VTK 5.2 and high
1847   vtkAxisActor2D::SetFontSize(
1848     viewport, textMapper, size, labelFactorY * fontFactorY, labelSizeY);
1849 #endif
1850       
1851   // We do only care of the height of the label in the X axis, so let's
1852   // use the min for example
1853   sprintf(str1, axisX->GetLabelFormat(), axisX->GetAdjustedRange()[0]);
1854   tprop->ShallowCopy(axisX->GetLabelTextProperty());
1855   textMapper->SetInput(str1);
1856       
1857 #if (VTK_XVERSION < 0x050100)
1858   //VSV:  Function is not supported in VTK 5.2 and high
1859   vtkAxisActor2D::SetFontSize(
1860     viewport, textMapper, size, labelFactorX * fontFactorX, labelSizeX);
1861 #endif
1862      
1863   tickOffsetX = axisX->GetTickOffset();
1864   tickOffsetY = axisY->GetTickOffset();
1865   tickLengthX = axisX->GetTickLength();
1866   tickLengthY = axisY->GetTickLength();
1867
1868   // Okay, estimate the size
1869 /* RKV  pos[0] = (int)(p1[0] + titleSizeY[0] + 2.0 * tickOffsetY + tickLengthY + 
1870                  labelSizeY[0] + this->Border);
1871
1872   pos[1] = (int)(p1[1] + titleSizeX[1] + 2.0 * tickOffsetX + tickLengthX + 
1873                  labelSizeX[1] + this->Border);
1874
1875   pos2[0] = (int)(p2[0] - labelSizeY[0] / 2 - tickOffsetY - this->Border);
1876
1877   pos2[1] = (int)(p2[1] - labelSizeX[1] / 2 - tickOffsetX - this->Border);
1878   */
1879   // RKV : Begin
1880   pos[0] = (int)(p1[0]);
1881
1882   pos[1] = (int)(p1[1]);
1883
1884   pos2[0] = (int)(p2[0]);
1885
1886   pos2[1] = (int)(p2[1]);
1887   // RKV : End
1888
1889   // Now specify the location of the axes
1890   axisX->GetPositionCoordinate()->SetValue(
1891     (double)pos[0], (double)pos[1]);
1892   axisX->GetPosition2Coordinate()->SetValue(
1893     (double)pos2[0], (double)pos[1]);
1894   axisY->GetPositionCoordinate()->SetValue(
1895     (double)pos[0], (double)pos2[1]);
1896   axisY->GetPosition2Coordinate()->SetValue(
1897     (double)pos[0], (double)pos[1]);
1898     
1899   textMapper->Delete();
1900 }
1901
1902 //----------------------------------------------------------------------------
1903 void VISU_XYPlotActor::ViewportToPlotCoordinate(vtkViewport *viewport, double &u, double &v)
1904 {
1905   int *p0, *p1, *p2;
1906
1907   // XAxis, YAxis are in viewport coordinates already
1908   p0 = this->XAxis->GetPositionCoordinate()->GetComputedViewportValue(viewport);
1909   p1 = this->XAxis->GetPosition2Coordinate()->GetComputedViewportValue(viewport);
1910   p2 = this->YAxis->GetPositionCoordinate()->GetComputedViewportValue(viewport);
1911
1912   u = ((u - p0[0]) / (double)(p1[0] - p0[0]))
1913     *(this->XComputedRange[1] - this->XComputedRange[0])
1914     + this->XComputedRange[0];
1915   v = ((v - p0[1]) / (double)(p2[1] - p0[1]))
1916     *(this->YComputedRange[1] - this->YComputedRange[0])
1917     + this->YComputedRange[0];
1918 }
1919
1920 //----------------------------------------------------------------------------
1921 void VISU_XYPlotActor::PlotToViewportCoordinate(vtkViewport *viewport,
1922                                               double &u, double &v)
1923 {
1924   int *p0, *p1, *p2;
1925
1926   // XAxis, YAxis are in viewport coordinates already
1927   p0 = this->XAxis->GetPositionCoordinate()->GetComputedViewportValue(viewport);
1928   p1 = this->XAxis->GetPosition2Coordinate()->GetComputedViewportValue(viewport);
1929   p2 = this->YAxis->GetPositionCoordinate()->GetComputedViewportValue(viewport);
1930
1931   u = (((u - this->XComputedRange[0])
1932         / (this->XComputedRange[1] - this->XComputedRange[0]))
1933        * (double)(p1[0] - p0[0])) + p0[0];
1934   v = (((v - this->YComputedRange[0])
1935         / (this->YComputedRange[1] - this->YComputedRange[0]))
1936        * (double)(p2[1] - p0[1])) + p0[1];
1937 }
1938
1939 //----------------------------------------------------------------------------
1940 void VISU_XYPlotActor::ViewportToPlotCoordinate(vtkViewport *viewport)
1941 {
1942   this->ViewportToPlotCoordinate(viewport, 
1943                                  this->ViewportCoordinate[0],
1944                                  this->ViewportCoordinate[1]);
1945 }
1946
1947 //----------------------------------------------------------------------------
1948 void VISU_XYPlotActor::PlotToViewportCoordinate(vtkViewport *viewport)
1949 {
1950   this->PlotToViewportCoordinate(viewport, 
1951                                  this->PlotCoordinate[0],
1952                                  this->PlotCoordinate[1]);
1953 }
1954
1955 //----------------------------------------------------------------------------
1956 int VISU_XYPlotActor::IsInPlot(vtkViewport *viewport, double u, double v)
1957 {
1958   int *p0, *p1, *p2;
1959
1960   // Bounds of the plot are based on the axes...
1961   p0 = this->XAxis->GetPositionCoordinate()->GetComputedViewportValue(viewport);
1962   p1 = this->XAxis->GetPosition2Coordinate()->GetComputedViewportValue(viewport);
1963   p2 = this->YAxis->GetPositionCoordinate()->GetComputedViewportValue(viewport);
1964   
1965   if (u >= p0[0] && u <= p1[0] && v >= p0[1] && v <= p2[1])
1966     {
1967     return 1;
1968     }
1969
1970   return 0;
1971 }
1972
1973 //----------------------------------------------------------------------------
1974 void VISU_XYPlotActor::SetPlotLines(int i, int isOn)
1975 {
1976   i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
1977   int val = this->LinesOn->GetValue(i);
1978   if ( val != isOn )
1979     {
1980     this->Modified();
1981     this->LinesOn->SetValue(i, isOn);
1982     }
1983 }
1984
1985 //----------------------------------------------------------------------------
1986 int VISU_XYPlotActor::GetPlotLines(int i)
1987 {
1988   i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
1989   return this->LinesOn->GetValue(i);
1990 }
1991
1992 //----------------------------------------------------------------------------
1993 void VISU_XYPlotActor::SetPlotPoints(int i, int isOn)
1994 {
1995   i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
1996   int val = this->PointsOn->GetValue(i);
1997   if ( val != isOn )
1998     {
1999     this->Modified();
2000     this->PointsOn->SetValue(i, isOn);
2001     }
2002 }
2003
2004 //----------------------------------------------------------------------------
2005 int VISU_XYPlotActor::GetPlotPoints(int i)
2006 {
2007   i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
2008   return this->PointsOn->GetValue(i);
2009 }
2010
2011 //----------------------------------------------------------------------------
2012 void VISU_XYPlotActor::SetPlotColor(int i, double r, double g, double b)
2013 {
2014   this->LegendActor->SetEntryColor(i, r, g, b);
2015 }
2016
2017 //----------------------------------------------------------------------------
2018 double *VISU_XYPlotActor::GetPlotColor(int i)
2019 {
2020   return this->LegendActor->GetEntryColor(i);
2021 }
2022
2023 //----------------------------------------------------------------------------
2024 void VISU_XYPlotActor::SetPlotSymbol(int i,vtkPolyData *input)
2025 {
2026   this->LegendActor->SetEntrySymbol(i, input);
2027 }
2028
2029 //----------------------------------------------------------------------------
2030 vtkPolyData *VISU_XYPlotActor::GetPlotSymbol(int i)
2031 {
2032   return this->LegendActor->GetEntrySymbol(i);
2033 }
2034
2035 //----------------------------------------------------------------------------
2036 void VISU_XYPlotActor::SetPlotLabel(int i, const char *label)
2037 {
2038   this->LegendActor->SetEntryString(i, label);
2039 }
2040
2041 //----------------------------------------------------------------------------
2042 const char *VISU_XYPlotActor::GetPlotLabel(int i)
2043 {
2044   return this->LegendActor->GetEntryString(i);
2045 }
2046
2047 //----------------------------------------------------------------------------
2048 void VISU_XYPlotActor::GenerateClipPlanes(int *pos, int *pos2)
2049 {
2050   double n[3], x[3];
2051   vtkPoints *pts=this->ClipPlanes->GetPoints();
2052   vtkDataArray *normals=this->ClipPlanes->GetNormals();
2053   
2054   n[2] = x[2] = 0.0;
2055   
2056   //first
2057   n[0] = 0.0;
2058   n[1] = -1.0;
2059   normals->SetTuple(0,n);
2060   x[0] = (double)0.5*(pos[0]+pos2[0]);
2061   x[1] = (double)pos[1];
2062   pts->SetPoint(0,x);
2063   
2064   //second
2065   n[0] = 1.0;
2066   n[1] = 0.0;
2067   normals->SetTuple(1,n);
2068   x[0] = (double)pos2[0];
2069   x[1] = (double)0.5*(pos[1]+pos2[1]);
2070   pts->SetPoint(1,x);
2071   
2072   //third
2073   n[0] = 0.0;
2074   n[1] = 1.0;
2075   normals->SetTuple(2,n);
2076   x[0] = (double)0.5*(pos[0]+pos2[0]);
2077   x[1] = (double)pos2[1];
2078   pts->SetPoint(2,x);
2079   
2080   //fourth
2081   n[0] = -1.0;
2082   n[1] = 0.0;
2083   normals->SetTuple(3,n);
2084   x[0] = (double)pos[0];
2085   x[1] = (double)0.5*(pos[1]+pos2[1]);
2086   pts->SetPoint(3,x);
2087 }
2088
2089 //----------------------------------------------------------------------------
2090 double VISU_XYPlotActor::ComputeGlyphScale(int i, int *pos, int *pos2)
2091 {
2092   vtkPolyData *pd=this->LegendActor->GetEntrySymbol(i);
2093   pd->Update();
2094   double length=pd->GetLength();
2095   double sf = this->GlyphSize * sqrt((double)(pos[0]-pos2[0])*(pos[0]-pos2[0]) + 
2096                                     (pos[1]-pos2[1])*(pos[1]-pos2[1])) / length;
2097
2098   return sf;
2099 }
2100
2101 //----------------------------------------------------------------------------
2102 //This assumes that there are multiple polylines
2103 void VISU_XYPlotActor::ClipPlotData(int *pos, int *pos2, vtkPolyData *pd)
2104 {
2105   vtkPoints *points=pd->GetPoints();
2106   vtkPoints *newPoints;
2107   vtkCellArray *lines=pd->GetLines();
2108   vtkCellArray *newLines, *newVerts;
2109   vtkIdType numPts=pd->GetNumberOfPoints();
2110   vtkIdType npts = 0;
2111   vtkIdType newPts[2];
2112   vtkIdType *pts=0;
2113   vtkIdType i, id;
2114   int j;
2115   double x1[3], x2[3], px[3], n[3], xint[3], t;
2116   double p1[2], p2[2];
2117
2118   p1[0] = (double)pos[0]; p1[1] = (double)pos[1];
2119   p2[0] = (double)pos2[0]; p2[1] = (double)pos2[1];
2120   
2121   newPoints = vtkPoints::New();
2122   newPoints->Allocate(numPts);
2123   newVerts = vtkCellArray::New();
2124   newVerts->Allocate(lines->GetSize());
2125   newLines = vtkCellArray::New();
2126   newLines->Allocate(2*lines->GetSize());
2127   int *pointMap = new int [numPts];
2128   for (i=0; i<numPts; i++)
2129     {
2130     pointMap[i] = -1;
2131     }
2132   
2133   //Loop over polyverts eliminating those that are outside
2134   for ( lines->InitTraversal(); lines->GetNextCell(npts,pts); )
2135     {
2136     //loop over verts keeping only those that are not clipped
2137     for (i=0; i<npts; i++)
2138       {
2139       points->GetPoint(pts[i], x1);
2140
2141       if (x1[0] >= p1[0] && x1[0] <= p2[0] && x1[1] >= p1[1] && x1[1] <= p2[1] )
2142         {
2143         id = newPoints->InsertNextPoint(x1);
2144         pointMap[i] = id;
2145         newPts[0] = id;
2146         newVerts->InsertNextCell(1,newPts);
2147         }
2148       }
2149     }
2150
2151   //Loop over polylines clipping each line segment
2152   for ( lines->InitTraversal(); lines->GetNextCell(npts,pts); )
2153     {
2154     //loop over line segment making up the polyline
2155     for (i=0; i<(npts-1); i++)
2156       {
2157       points->GetPoint(pts[i], x1);
2158       points->GetPoint(pts[i+1], x2);
2159
2160       //intersect each segment with the four planes
2161       if ( (x1[0] < p1[0] && x2[0] < p1[0]) || (x1[0] > p2[0] && x2[0] > p2[0]) ||
2162            (x1[1] < p1[1] && x2[1] < p1[1]) || (x1[1] > p2[1] && x2[1] > p2[1]) )
2163         {
2164         ;//trivial rejection
2165         }
2166       else if (x1[0] >= p1[0] && x2[0] >= p1[0] && x1[0] <= p2[0] && x2[0] <= p2[0] &&
2167                x1[1] >= p1[1] && x2[1] >= p1[1] && x1[1] <= p2[1] && x2[1] <= p2[1] )
2168         {//trivial acceptance
2169         newPts[0] = pointMap[pts[i]];
2170         newPts[1] = pointMap[pts[i+1]];
2171         newLines->InsertNextCell(2,newPts);
2172         }
2173       else
2174         {
2175         newPts[0] = -1;
2176         if (x1[0] >= p1[0] && x1[0] <= p2[0] && x1[1] >= p1[1] && x1[1] <= p2[1] )
2177           {//first point in
2178           newPts[0] = pointMap[pts[i]];
2179           }
2180         else if (x2[0] >= p1[0] && x2[0] <= p2[0] && x2[1] >= p1[1] && x2[1] <= p2[1] )
2181           {//second point in
2182           newPts[0] = pointMap[pts[i+1]];
2183           }
2184
2185         //only create cell if either x1 or x2 is inside the range
2186         if (newPts[0] >= 0)
2187           {
2188           for (j=0; j<4; j++)
2189             {
2190             this->ClipPlanes->GetPoints()->GetPoint(j, px);
2191             this->ClipPlanes->GetNormals()->GetTuple(j, n);
2192             if ( vtkPlane::IntersectWithLine(x1,x2,n,px,t,xint) && t >= 0 && t <= 1.0 )
2193               {
2194               newPts[1] = newPoints->InsertNextPoint(xint);
2195               break;
2196               }
2197             }
2198             newLines->InsertNextCell(2,newPts);
2199           }
2200         }
2201       }
2202     }
2203   delete [] pointMap;
2204   
2205   //Update the lines
2206   pd->SetPoints(newPoints);
2207   pd->SetVerts(newVerts);
2208   pd->SetLines(newLines);
2209   
2210   newPoints->Delete();
2211   newVerts->Delete();
2212   newLines->Delete();
2213   
2214 }
2215
2216 //----------------------------------------------------------------------------
2217 void VISU_XYPlotActor::SetDataObjectXComponent(int i, int comp)
2218 {
2219   i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
2220   int val=this->XComponent->GetValue(i);
2221   if ( val != comp )
2222     {
2223     this->Modified();
2224     this->XComponent->SetValue(i,comp);
2225     }
2226 }
2227
2228 //----------------------------------------------------------------------------
2229 int VISU_XYPlotActor::GetDataObjectXComponent(int i)
2230 {
2231   i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
2232   return this->XComponent->GetValue(i);
2233 }
2234
2235 //----------------------------------------------------------------------------
2236 void VISU_XYPlotActor::SetDataObjectYComponent(int i, int comp)
2237 {
2238   i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
2239   int val=this->YComponent->GetValue(i);
2240   if ( val != comp )
2241     {
2242     this->Modified();
2243     this->YComponent->SetValue(i,comp);
2244     }
2245 }
2246
2247 //----------------------------------------------------------------------------
2248 int VISU_XYPlotActor::GetDataObjectYComponent(int i)
2249 {
2250   i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
2251   return this->YComponent->GetValue(i);
2252 }
2253
2254 //----------------------------------------------------------------------------
2255 void VISU_XYPlotActor::SetPointComponent(int i, int comp)
2256 {
2257   i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
2258   int val = this->XComponent->GetValue(i);
2259   if ( val != comp )
2260     {
2261     this->Modified();
2262     this->XComponent->SetValue(i,comp);
2263     }
2264 }
2265
2266 //----------------------------------------------------------------------------
2267 int VISU_XYPlotActor::GetPointComponent(int i)
2268 {
2269   i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
2270   return this->XComponent->GetValue(i);
2271 }
2272
2273 //----------------------------------------------------------------------------
2274 double *VISU_XYPlotActor::TransformPoint(int pos[2], int pos2[2],
2275                                        double x[3], double xNew[3])
2276 {
2277   // First worry about exchanging axes
2278   if ( this->ExchangeAxes )
2279     {
2280     double sx = (x[0]-pos[0]) / (pos2[0]-pos[0]);
2281     double sy = (x[1]-pos[1]) / (pos2[1]-pos[1]);
2282     xNew[0] = sy*(pos2[0]-pos[0]) + pos[0];
2283     xNew[1] = sx*(pos2[1]-pos[1]) + pos[1];
2284     xNew[2] = x[2];
2285     }
2286   else
2287     {
2288     xNew[0] = x[0];
2289     xNew[1] = x[1];
2290     xNew[2] = x[2];
2291     }
2292
2293   // Okay, now swap the axes around if reverse is on
2294   if ( this->ReverseXAxis )
2295     {
2296     xNew[0] = pos[0] + (pos2[0]-xNew[0]);
2297     }
2298   if ( this->ReverseYAxis )
2299     {
2300     xNew[1] = pos[1] + (pos2[1]-xNew[1]);
2301     }
2302
2303   return xNew;
2304 }
2305     
2306 //----------------------------------------------------------------------------
2307 void VISU_XYPlotActor::SetLabelFormat(const char* _arg)
2308 {
2309   if (this->LabelFormat == NULL && _arg == NULL) 
2310     { 
2311     return;
2312     }
2313
2314   if (this->LabelFormat && _arg && (!strcmp(this->LabelFormat,_arg))) 
2315     { 
2316     return;
2317     }
2318
2319   if (this->LabelFormat) 
2320     { 
2321     delete [] this->LabelFormat; 
2322     }
2323
2324   if (_arg)
2325     {
2326     this->LabelFormat = new char[strlen(_arg)+1];
2327     strcpy(this->LabelFormat,_arg);
2328     }
2329   else
2330     {
2331     this->LabelFormat = NULL;
2332     }
2333
2334   this->XAxis->SetLabelFormat(this->LabelFormat);
2335   this->YAxis->SetLabelFormat(this->LabelFormat);
2336
2337   this->Modified();
2338 }
2339
2340 //----------------------------------------------------------------------------
2341 void VISU_XYPlotActor::PrintAsCSV(ostream &os)
2342 {
2343   vtkDataArray *scalars;
2344   vtkDataSet *ds;
2345   vtkCollectionSimpleIterator dsit;
2346   double s;
2347   int dsNum,component;
2348   for ( dsNum=0, this->InputList->InitTraversal(dsit); 
2349     (ds = this->InputList->GetNextDataSet(dsit)); dsNum++ )
2350     {
2351     vtkIdType numPts = ds->GetNumberOfPoints();
2352     scalars = ds->GetPointData()->GetScalars(this->SelectedInputScalars[dsNum]);
2353     component = this->SelectedInputScalarsComponent->GetValue(dsNum);
2354     for ( vtkIdType ptId=0; ptId < numPts; ptId++ )
2355       {
2356       s = scalars->GetComponent(ptId, component);
2357       if( ptId == 0 )
2358         {
2359         os << s;
2360         }
2361       else
2362         {
2363         os << "," << s;
2364         }
2365       }
2366     os << endl;
2367     }
2368 }
2369