]> Creatis software - creaMaracasVisu.git/blob - lib/maracasVisuLib/src/interface/wxWindows/widgets/include/wxChart.cxx
f825f723ce498e7ee3451a227af2a1649334753a
[creaMaracasVisu.git] / lib / maracasVisuLib / src / interface / wxWindows / widgets / include / wxChart.cxx
1 /*=========================================================================
2
3   Program:   wxMaracas
4   Module:    $RCSfile: wxChart.cxx,v $
5   Language:  C++
6   Date:      $Date: 2009/05/14 13:54:57 $
7   Version:   $Revision: 1.1 $
8
9   Copyright: (c) 2002, 2003
10   License:
11
12      This software is distributed WITHOUT ANY WARRANTY; without even
13      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14      PURPOSE.  See the above copyright notice for more information.
15
16 =========================================================================*/
17
18 #include "wxChart.h"
19
20 #include <math.h>
21
22 //----------------------------------------------------------------
23 // DataSet : Constructor & Destructor
24 //-------------------------------------------------------------------
25 wxDataSet::wxDataSet(wxPen *lStyle, wxBrush *dStyle, int dWidth,
26                      int lWidth, int dGap, int pMark, int disValues)
27 {
28    m_lineStyle = lStyle;
29    m_dataStyle = dStyle;
30    m_dataWidth = dWidth;
31    m_lineWidth = lWidth;
32    m_pointMark = pMark;
33    m_displayValues = disValues;
34    m_display = false;
35    m_rowsList = NULL;
36    m_text = NULL;
37 }
38
39 wxDataSet::wxDataSet(wxPen *lStyle, wxBrush *dStyle,
40              wxString *lText, bool lDisplay)
41 {
42    m_lineStyle = lStyle;
43    m_dataStyle = dStyle;
44    m_display = lDisplay;
45    m_text = lText;
46    m_rowsList = NULL;
47    m_dataWidth = 0;
48    m_lineWidth = 0;
49    m_pointMark = 0;
50    m_displayValues = 0;
51 }
52
53
54
55 wxDataSet::wxDataSet()
56 {
57    m_lineStyle = NULL;
58    m_dataStyle = NULL;
59    m_dataWidth = 0;
60    m_lineWidth = 0;
61    m_pointMark = 0;
62    m_displayValues = 0;
63    m_display = false;
64    m_rowsList = NULL;
65    m_text = NULL;
66 }
67
68
69 wxDataSet::~wxDataSet()
70 {
71   // Nothing
72 }
73
74
75
76
77 //-----------------------------------------------------------------
78 // Chart
79 //-------------------------------------------------------------------
80 BEGIN_EVENT_TABLE(wxChart, wxPanel)
81   EVT_PAINT(wxChart::OnPaint)
82 END_EVENT_TABLE()
83
84 //---------------------------------------------------------------------
85 // Constructor & Destructor
86 wxChart::wxChart(wxWindow *parent, wxWindowID id,
87                  const wxPoint& pos, const wxSize& size,
88                  long  style, const wxString& name)
89                  : wxPanel(parent, id, pos, size, style, name)
90 {
91   SetMaxWidthHeight(size.GetWidth(), size.GetHeight());
92   SetCenterChart(pos.x + (GetLargeur()/2), pos.y + (GetHauteur()/2));
93   InitDataSet();
94   InitChart();
95 }
96
97
98
99 wxChart::~wxChart()
100 {
101   for(int i=0; i<m_NumDataSet ; i++)
102     delete(m_dataSetArray[i]);
103 }
104
105
106
107 void  wxChart::InitChart()
108 {
109   SetShowPer(false); //not display line % per default
110   for(int i=0; i<m_NumDataSet ; i++)
111     ShowDataSet(false, i);
112   InitData();
113 }
114
115 // Static Function
116 //--------------------------------------------------------------
117 static double st_difference(double val, int multi, bool sens=true)
118 {
119   double retour=0;
120   div_t result;
121   result = div(int(val), multi);
122
123   // multiple sup
124   if ( sens ) {
125     if ( val > 1) {
126       if ( result.rem == 0 ) {
127         if (val - (int)val > 0 )
128           retour =  (multi - result.rem) - (val - int(val));
129       }
130       else {
131         retour =  (multi - result.rem) - (val - int(val));
132       }
133     }
134   }
135   // multiple inf
136   else
137     retour = result.rem + (val - (int)val);
138   return retour;
139 }
140
141 static double st_decalage(double IncX, double MinX)
142 {
143   double retour = 0.00;
144   div_t result;
145
146   if (IncX >= 1) {
147     result = div((int)MinX, (int)IncX);
148     if ( result.rem == 0 ) {
149       if (MinX - (int)MinX > 0 )
150         retour = ((result.quot + 1) * IncX) - MinX;
151     }
152     else {
153       retour = ((result.quot+1) * IncX) - MinX;
154     }
155   }
156   return retour;
157 }
158
159 static double st_origine(double IncX, double MinX)
160 {
161   double retour = MinX;
162   div_t result;
163
164   if (IncX >=1) {
165     result = div((int)MinX, (int)IncX);
166     if (result.rem == 0) {
167       if (MinX - (int)MinX > 0 )
168         retour = (result.quot + 1) * IncX;
169     }
170     else {
171       retour = (result.quot + 1) * IncX;
172     }
173   }
174   return retour;
175 }
176
177
178 static void st_Inverse(double *l_MinCol, double  *l_MaxCol)
179 {
180   if  (*l_MinCol > *l_MaxCol) {
181     int tempo = (int)(*l_MaxCol);
182     *l_MaxCol = *l_MinCol;
183     *l_MinCol = tempo;
184   }
185 }
186
187
188 //--------------------------------------------------------------
189 void wxChart::SetInfX(double inf)
190 {
191   m_InfX = inf;
192 }
193
194 void wxChart::SetSupX(double sup)
195 {
196   m_SupX = sup;
197 }
198
199
200 void wxChart::SetSupY(double sup)
201 {
202   m_SupY = sup;
203 }
204
205
206 void wxChart::SetIncAxisX(double minor, double major)
207 {
208   m_MinorIncX = minor;
209   m_MajorIncX = major;
210 }
211
212 void wxChart::SetIncAxisY(double minor, double major)
213 {
214   m_MinorIncY = minor;
215   m_MajorIncY = major;
216 }
217
218
219 void wxChart::SetInitEdge()
220 {
221
222   SetEdgeTop(15);
223   SetEdgeBottom(35);
224   SetEdgeLeft(37);
225   SetEdgeRight(15);
226 }
227
228
229
230 void wxChart::SetChartBounds()
231 {
232   m_Top = m_CenterY - (m_MaxHauteur/2) + m_EdgeTop;
233   m_Bottom = m_CenterY + (m_MaxHauteur/2) - m_EdgeBottom;
234   m_Left = m_CenterX - (m_MaxLargeur/2) + m_EdgeLeft;
235   m_Right = m_CenterX + (m_MaxLargeur/2) - m_EdgeRight;
236 }
237
238 void wxChart::SetChartBoundsLegend()
239 {
240   m_TopLegend = m_CenterY - (m_MaxHauteur/2) + m_EdgeTopLegend;
241   m_BottomLegend = m_CenterY + (m_MaxHauteur/2) - m_EdgeBottomLegend;
242   m_LeftLegend = m_CenterX - (m_MaxLargeur/2) + m_EdgeLeftLegend;
243   m_RightLegend = m_CenterX + (m_MaxLargeur/2) - m_EdgeRightLegend;
244 }
245
246
247 void wxChart::SetCadreLegend(int nbr, int *bottom)
248 {
249   int val=GetEdgeBottom();
250   div_t result = div(nbr, 2);
251   if (result.rem == 0)
252     val+= (nbr * 10) + 5;
253   else
254     val+= (( nbr + 1 ) * 10) + 5;
255
256   *bottom = val;
257   SetEdgeTopLegend(m_CenterY + (m_MaxHauteur/2) - val + 33);
258   SetEdgeBottomLegend(8);
259
260   int l_left = GetEdgeLeft();
261   int l_right = GetEdgeRight();
262
263   // more small for only 1 line
264   if (nbr == 1) {
265     l_left+=m_CenterX - (m_MaxLargeur/3);
266     l_right+=m_CenterX - (m_MaxLargeur/3);
267   }
268
269   SetEdgeLeftLegend(l_left);
270   SetEdgeRightLegend(l_right);
271 }
272
273
274 void wxChart::SetShowPer(bool per)
275 {
276   m_ShowPer = per;
277 }
278
279
280 void  wxChart::SetMaxValue(double max)
281 {
282   // Axe Y
283   m_MaxValue = max;
284 }
285
286 double wxChart::MaxValue()
287 {
288   double data, val = 1.00;
289   int maxdata = GetNumDataSet()-1;
290   int maxitem = GetNumItem();
291
292   // Exclure Stenosis for calcul MaxValue
293   for(int a=0; a < maxdata; a++) {
294     if (GetShowDataSet(a)) {
295       for(int j=0; j<=maxitem; j++) {
296         if ( IsEmpty(a,j) == false ) {
297           data = GetDataY(a,j);
298           if (data > val)
299             val = data;
300         }
301       }
302     }
303   }
304
305   return val;
306 }
307
308
309 double wxChart::MinCol(double min)
310 {
311   double retour = 0.00;
312   int maxdata = GetNumDataSet()-1;
313
314   // Exclure Stenosis for calcul MaxValue
315   for(int a=0; a < maxdata; a++) {
316     if (GetShowDataSet(a)) {
317       if (min > retour)
318         retour = min;
319       a = maxdata - 1;
320     }
321   }
322
323   return retour;
324 }
325
326
327 double wxChart::MaxCol(double max)
328 {
329   double retour = 1.00;
330   int maxdata = GetNumDataSet()-1;
331
332   // Exclure Stenosis for calcul MaxValue
333   for(int a=0; a < maxdata; a++) {
334     if (GetShowDataSet(a)) {
335       if (max > retour)
336         retour = max;
337       a = maxdata - 1;
338     }
339   }
340
341   return retour;
342 }
343
344 void  wxChart::SetStepSizeX(double stepX)
345 {
346   m_StepSizeX = stepX;
347 }
348
349 void  wxChart::SetStepSizeY(double stepY)
350 {
351   m_StepSizeY = stepY;
352 }
353
354
355 void  wxChart::SetStepSizePer(double stepPer)
356 {
357   m_StepSizePer = stepPer;
358 }
359
360
361 void   wxChart::SetCenterChart(int x, int y)
362 {
363   m_CenterX = x;
364   m_CenterY = y;
365 }
366
367 void wxChart::SetMaxWidthHeight(int x,int y)
368 {
369   m_MaxLargeur = x;
370   m_MaxHauteur = y;
371 }
372
373
374 void wxChart::SetMinX(double MinX)
375 {
376   m_MinX = MinX;
377 }
378
379
380 void wxChart::SetMaxX(double MaxX)
381 {
382   m_MaxX = MaxX;
383 }
384
385
386
387 void wxChart::SetEdgeTop(int top)
388 {
389   m_EdgeTop = top;
390 }
391
392 void wxChart::SetEdgeBottom(int bottom)
393 {
394   m_EdgeBottom = bottom;
395 }
396
397 void wxChart::SetEdgeLeft(int left)
398 {
399   m_EdgeLeft = left;
400 }
401
402 void wxChart::SetEdgeRight(int right)
403 {
404   m_EdgeRight = right;
405 }
406
407
408 void  wxChart::SetEdgeTopLegend(int top)
409 {
410   m_EdgeTopLegend = top;
411 }
412
413 void  wxChart::SetEdgeBottomLegend(int bottom)
414 {
415   m_EdgeBottomLegend = bottom;
416 }
417
418 void  wxChart::SetEdgeLeftLegend(int left)
419 {
420   m_EdgeLeftLegend = left;
421 }
422
423
424 void  wxChart::SetEdgeRightLegend(int right)
425 {
426   m_EdgeRightLegend = right;
427 }
428
429
430
431 void   wxChart::SetNumDataSet(int num)
432 {
433   m_NumDataSet = num;
434 }
435
436 void   wxChart::SetNumItem(int num)
437 {
438   m_NumItem = num;
439 }
440
441
442 int  wxChart::GetShow()
443 {
444   int retour = 0;
445
446   for(int i=0; i < m_NumDataSet ; i++) {
447     if (GetShowDataSet(i))
448       retour++;
449   }
450   return retour;
451 }
452
453
454 void wxChart::InitDataSet()
455 {
456
457   // Initialization
458   SetNumDataSet(8);
459   for(int i=0; i<MAX_DATASET ; i++)
460     m_dataSetArray[i]=NULL;
461
462   // Colour
463   wxColour *BlueColour       = new wxColour(0,0,255);
464   wxColour *GreyColour       = new wxColour(192,192,192);
465   wxColour *YellowColour     = new wxColour(255,255,0);
466   wxColour *VioletColour     = new wxColour(255,0,255);
467   wxColour *CyanColour       = new wxColour(0,255,255);
468
469   // Create All DataSet
470   // Per default : Show(false)
471   m_dataSetArray[wxArea] = new wxDataSet(wxRED_PEN, wxRED_BRUSH, (wxString*)"Area");
472   m_dataSetArray[wxPerimeter] = new wxDataSet(new wxPen(*BlueColour, 1, wxSOLID),
473                                               new wxBrush(*BlueColour, wxSOLID),
474                                               (wxString*)"Perimeter");
475
476   m_dataSetArray[wxDiameterArea] =  new wxDataSet(new wxPen(*GreyColour, 1, wxSOLID),
477                                                   new wxBrush(*GreyColour, wxSOLID),
478                                                   (wxString*)"Diameter from area");
479
480   m_dataSetArray[wxDiameterPerimeter] = new wxDataSet(new wxPen(*YellowColour, 1, wxSOLID),
481                                                       new wxBrush(*YellowColour, wxSOLID),
482                                                       (wxString*)"Diameter from perimeter");
483
484   m_dataSetArray[wxMinimumDiameter] = new wxDataSet(new wxPen(*VioletColour, 1, wxSOLID),
485                                                     new wxBrush(*VioletColour, wxSOLID),
486                                                     (wxString*)"Minimum diameter");
487
488   m_dataSetArray[wxMaximumDiameter] = new wxDataSet(new wxPen(*CyanColour, 1, wxSOLID),
489                                                     new wxBrush(*CyanColour, wxSOLID),
490                                                     (wxString*)"Maximum diameter");
491
492   m_dataSetArray[wxAverageDiameter] = new wxDataSet(wxBLACK_PEN, wxBLACK_BRUSH, (wxString*)"Average diameter");
493
494   m_dataSetArray[wxStenosis] =    new wxDataSet(wxGREEN_PEN, wxGREEN_BRUSH, (wxString*)"Stenosis");
495
496 }
497
498
499 // Paint
500 //---------------------------------------------------------------------
501 void wxChart::OnPaint(wxPaintEvent& event)
502 {
503   wxPaintDC dc(this);
504   Draw(dc);
505 }
506
507
508 void wxChart::Draw(wxDC& dc)
509 {
510   wxBrush *dataBrush;
511   wxPen *dataPen;
512
513   //----------------------------------------------------------------------------
514   // Begin
515   dc.BeginDrawing();
516   dc.Clear();
517
518   //----------------------------------------------------------------------------
519   // Font : one for all chart
520   dc.SetFont(*(new wxFont(1, wxDEFAULT, wxNORMAL, wxLIGHT)));
521
522   //----------------------------------------------------------------------------
523   // Dimension
524   wxSize size = GetClientSize();
525   SetMaxWidthHeight(size.GetWidth(), size.GetHeight());
526   SetCenterChart((GetLargeur()/2), (GetHauteur()/2));
527   SetInitEdge();
528
529   //-----------------------------------------------------------------------------
530   // Show Line
531   ShowDataSet(true,wxArea);
532   ShowDataSet(true,wxPerimeter);
533   ShowDataSet(true,wxDiameterArea);
534   ShowDataSet(true,wxDiameterPerimeter);
535   ShowDataSet(true,wxMinimumDiameter);
536   ShowDataSet(true,wxMaximumDiameter);
537   ShowDataSet(true,wxAverageDiameter);
538   ShowDataSet(true,wxStenosis);
539
540   m_ShowPer = true;
541
542   // Show Axe %
543   if (m_ShowPer) {
544     SetEdgeRight(45);
545     ShowDataSet(true,wxStenosis);
546   }
547
548   //--------------------------------------------------------------------
549   // Legend
550   int nbr = GetShow();
551   if (nbr > 0) {
552     SetCadreLegend(nbr, &m_EdgeBottom);
553     SetChartBoundsLegend();
554     DrawLegend(dc, nbr);
555   }
556
557   //-------------------------------------------------------------------
558   // Valeur Min et Max des abscisses
559   SetMinX(MinCol(0));
560   SetMaxX(MaxCol(1));
561   SetInfX(st_difference(m_MinX,10,false));
562   SetSupX(st_difference(m_MaxX,10,true));
563
564   //------------------------------------------------------------------
565   // Data
566   // Stenosis
567   SetNumItem(6);
568   SetData(wxStenosis, 0,   0,  -45);
569   SetData(wxStenosis, 1, 0.4,    0);
570   SetData(wxStenosis, 2, 0.6,  -15);
571   SetData(wxStenosis, 3, 0.8,    0);
572   SetData(wxStenosis, 4, 0.9,  100);
573   SetData(wxStenosis, 5,   1,    0);
574
575   // Area
576   SetData(wxArea,0,   0, 0.8);
577   SetData(wxArea,1, 0.2, 0.6);
578   SetData(wxArea,2, 0.3, 0.8);
579   SetData(wxArea,3, 0.4,   1);
580   SetData(wxArea,4, 0.8, 0.4);
581   SetData(wxArea,5,   1, 0.2);
582
583   //-----------------------------------------------------------------
584   // Valeur Max du chart
585   SetMaxValue(MaxValue());
586   SetSupY(st_difference(m_MaxValue, 10, true));
587
588   //-------------------------------------------------------------------------------
589   // Scale
590   SetIncAxisX((m_MaxX + m_SupX  -  (m_MinX - m_InfX)) / (double)MINOR_STEP,
591               (m_MaxX + m_SupX  -  (m_MinX - m_InfX)) / (double)MAJOR_STEP);
592   SetIncAxisY((m_MaxValue + m_SupY) / (double)MINOR_STEP,
593               (m_MaxValue + m_SupY) / (double)MAJOR_STEP);
594   SetStepSizeX(( m_MaxLargeur - (m_EdgeLeft + m_EdgeRight + m_SupX + m_InfX)) /
595                (m_MaxX - m_MinX));
596   SetStepSizeY(( m_MaxHauteur - (m_EdgeBottom + m_EdgeTop + m_SupY )) /
597                 (m_MaxValue));
598   SetStepSizePer(( m_MaxHauteur - (m_EdgeBottom + m_EdgeTop)) /
599                  (double)MAX_PER);
600
601   //-----------------------------------------------------------------------------
602   // Empty Chart
603   //---------------------------------------------------------------------------
604   SetChartBounds();
605   DrawGrille(dc);
606   DrawAxe(dc);
607   if (m_ShowPer)
608     DrawAxePer(dc);
609
610   //-----------------------------------------------------------------------------
611   // Clipping
612   //---------------------------------------------------------------------------
613   dc.DestroyClippingRegion();
614   dc.SetClippingRegion(m_Left , m_Top ,
615                        GetLargeur() - (m_EdgeRight + m_EdgeLeft   ),
616                        GetHauteur() - (m_EdgeTop   + m_EdgeBottom ));
617
618    //---------------------------------------------------------------------------
619    // Draw line
620    //---------------------------------------------------------------------------
621   int maxdataset = GetNumDataSet();
622   for(int a=0; a < maxdataset; a++) {
623     if(m_dataSetArray[a] && m_dataSetArray[a]->GetShow()) {
624       dataBrush = m_dataSetArray[a]->GetDataStyle();
625       dataPen = m_dataSetArray[a]->GetLineStyle();
626       dc.SetBrush(*dataBrush);
627       dc.SetPen(*dataPen);
628       DrawLine(dc, a);
629     }
630   }
631
632   //---------------------------------------
633   // end
634   dc.DestroyClippingRegion();
635   dc.EndDrawing();
636 }
637
638
639 void wxChart::DrawAxe(wxDC& dc)
640 {
641   double x,y;
642   double val, supx;
643   char text[20];
644   int widthx,heighty;
645
646   double minorIncStepY= m_MinorIncY * m_StepSizeY;
647   double majorIncStepY= m_MajorIncY * m_StepSizeY;
648   double minorIncStepX= m_MinorIncX * m_StepSizeX;
649   double majorIncStepX= m_MajorIncX * m_StepSizeX;
650
651   dc.SetPen(*wxBLACK_PEN);
652   dc.SetBrush(*wxBLACK_BRUSH);
653
654   // Axe X
655   dc.DrawLine(m_Left, m_Bottom+(7*MARGE/4), m_Right, m_Bottom+(7*MARGE/4));
656   // Axe Y
657   dc.DrawLine(m_Left-(7*MARGE/4), m_Bottom, m_Left-(7*MARGE/4), m_Top);
658
659   // AXE Y
660   // Major Tick Marks with values
661   val=0.00;
662   for(x=m_Left,y=m_Bottom; y >= m_Top; y-=majorIncStepY, val+=m_MajorIncY) {
663     dc.DrawLine( (int)(m_Left-7-(7*MARGE/4)) , (int)(y) , (int)(m_Left-(7*MARGE/4)) , (int)(y) );
664     sprintf(text,"%g", val);
665     dc.GetTextExtent(wxString(text, wxConvUTF8),&widthx,&heighty);
666     dc.DrawText(wxString(text, wxConvUTF8), (int)(m_Left-10-widthx-(7*MARGE/4)) , (int)(y-(heighty/2)) );
667   }
668   // Ne pas Depasser
669   if (m_SupY == 0 ) {
670     dc.DrawLine(m_Left-7-(7*MARGE/4),m_Top,m_Left-(7*MARGE/4),m_Top);
671     sprintf(text,"%g", val);
672     dc.GetTextExtent(wxString(text, wxConvUTF8),&widthx,&heighty);
673     dc.DrawText( wxString(text, wxConvUTF8),m_Left-10-widthx-(7*MARGE/4),m_Top-(heighty/2));
674   }
675
676   // Minor Tick Marks
677   for(x=m_Left,y=m_Bottom; y >= m_Top; y-=minorIncStepY) {
678     dc.DrawLine((int)(m_Left-3-(7*MARGE/4)) , (int)(y) , (int)(m_Left-(7*MARGE/4)) , (int)(y) );
679   }
680
681   // AXE X
682   // Major Tick Marks with values
683   supx = st_decalage(m_MajorIncX, m_MinX) * m_StepSizeX;
684   val = st_origine(m_MajorIncX, m_MinX);
685   for(y=m_Bottom,x=m_Left + supx; x <= m_Right; x+=majorIncStepX, val+=m_MajorIncX) {
686     dc.DrawLine((int)x,(int)(m_Bottom+7+(7*MARGE/4)),(int)(x),(int)(m_Bottom+(7*MARGE/4)));
687     sprintf(text,"%g", val);
688     dc.GetTextExtent(wxString(text, wxConvUTF8),&widthx,&heighty);
689     dc.DrawText(wxString(text, wxConvUTF8), (int)(x-(widthx/2)) , (int)(y+3+heighty) );
690   }
691
692   // Ne pas Depasser
693   if ( m_SupX == 0 ) {
694     dc.DrawLine(m_Right,m_Bottom+7+(7*MARGE/4),m_Right,m_Bottom+(7*MARGE/4));
695     sprintf(text,"%g", val);
696     dc.GetTextExtent(wxString(text, wxConvUTF8),&widthx,&heighty);
697     dc.DrawText(wxString(text, wxConvUTF8), (int)(m_Right-(widthx/2)), (int)(m_Right+3+heighty));
698   }
699
700   supx = st_decalage(m_MinorIncX, m_MinX) * m_StepSizeX;
701   //Minor Tick Marks
702   for(y=m_Bottom,x=m_Left + supx; x <= m_Right; x+=minorIncStepX) {
703     dc.DrawLine((int)(x),(int)(m_Bottom+3+(7*MARGE/4)),(int)(x),(int)(m_Bottom+(7*MARGE/4)));
704   }
705 }
706
707
708 void wxChart::DrawAxePer(wxDC& dc)
709 {
710   double x,y;
711   double val;
712   char text[20];
713   int widthx,heighty;
714
715   double minorIncStepPer= MINOR_PER * m_StepSizePer;
716   double majorIncStepPer= MAJOR_PER * m_StepSizePer;
717
718   dc.SetPen(*wxBLACK_PEN);
719   dc.SetBrush(*wxBLACK_BRUSH);
720
721   // AXE Per
722   dc.DrawLine((int)(m_Right+(7*MARGE/4))  , m_Bottom, (int)(m_Right+(7*MARGE/4)), m_Top);
723
724   // Major Tick Marks with values
725   val=0.00;
726   for(x=m_Right,y=m_Bottom; y >= m_Top; y-=majorIncStepPer, val+=MAJOR_PER) {
727     dc.DrawLine( (int)(m_Right+(7*MARGE/4)) , (int)y , (int)(m_Right+7+(7*MARGE/4)) , (int)(y) );
728     sprintf(text,"%g",(val-(MAX_PER/2)));
729     dc.GetTextExtent(wxString(text, wxConvUTF8),&widthx,&heighty);
730     dc.DrawText(wxString(text, wxConvUTF8) , (int)(m_Right+10+(7*MARGE/4)) , (int)(y-(heighty/2)) );
731   }
732   dc.DrawLine(m_Right+(7*MARGE/4),m_Top,m_Right+7+(7*MARGE/4),m_Top);
733   sprintf(text,"%g",(val-(MAX_PER/2)));
734   dc.GetTextExtent(wxString(text, wxConvUTF8),&widthx,&heighty);
735   dc.DrawText(wxString(text, wxConvUTF8),(int) (m_Right+10+(7*MARGE/4) ), (int) (m_Top-(heighty/2) ));
736
737   // Minor Tick Marks
738   for(x=m_Right,y=m_Bottom; y >= m_Top; y-=minorIncStepPer) {
739     dc.DrawLine((int)(m_Right+(7*MARGE/4)),(int)y,(int)(m_Right+3+(7*MARGE/4)),(int)(y) );
740   }
741 }
742
743
744 void wxChart::DrawGrille(wxDC& dc)
745 {
746   double x,y;
747   double val;
748   double minorIncStepY = m_MinorIncY * m_StepSizeY;
749   double minorIncStepX = m_MinorIncX * m_StepSizeX;
750
751   dc.SetBrush(*wxLIGHT_GREY_BRUSH);
752
753   // Tracer DOT
754   wxPen *Pen = new wxPen(*wxLIGHT_GREY, 1, wxDOT);
755   dc.SetPen(*Pen);
756
757   // quadrillage en point
758   // axe Y
759   for(x=m_Left,y=m_Bottom; y >= m_Top; y-=minorIncStepY)
760     dc.DrawLine((int)(m_Left-MARGE),(int)y,(int)(m_Right+MARGE),(int)y);
761   if (m_SupY == 0)
762     dc.DrawLine(m_Left-MARGE,m_Top,m_Right+MARGE,m_Top);
763
764   // axe X
765   val = st_decalage(m_MinorIncX, m_MinX) * m_StepSizeX;
766   for(y=m_Bottom, x=m_Left + val ; x <= m_Right; x+=minorIncStepX)
767     dc.DrawLine((int)x,(int)(m_Bottom+MARGE),(int)x,(int)(m_Top-MARGE));
768   if (m_SupX == 0)
769     dc.DrawLine(m_Right,m_Bottom+MARGE,m_Right,m_Top-MARGE);
770
771   // Contour
772   Pen->SetStyle(wxSOLID);
773   dc.SetPen(*Pen);
774   dc.DrawLine(m_Left-MARGE, m_Top-MARGE, m_Right+MARGE, m_Top-MARGE);
775   dc.DrawLine(m_Right+MARGE, m_Top-MARGE, m_Right+MARGE, m_Bottom+MARGE);
776   dc.DrawLine(m_Right+MARGE, m_Bottom+MARGE, m_Left-MARGE, m_Bottom+MARGE);
777   dc.DrawLine(m_Left-MARGE, m_Bottom+MARGE, m_Left-MARGE, m_Top-MARGE);
778 }
779
780
781 void wxChart::DrawLegend(wxDC& dc, int nbre)
782 {
783   // Init
784   wxString  *string;
785   wxPen     *dataPen;
786   wxBrush   *dataBrush;
787   int widthx, heighty, l_posx, l_posy;
788   char text[30];
789   int haut_ligne, compt = 0;
790   int l_haut = m_BottomLegend - m_TopLegend;
791   int l_larg = m_RightLegend - m_LeftLegend;
792
793   div_t result = div(nbre,2);
794   div_t resulta;
795   int l_debut = 30, l_trait = 15, l_space = 10;
796
797   if (result.rem == 0)
798     haut_ligne = l_haut / result.quot;
799   else
800     haut_ligne = l_haut / (result.quot+1);
801
802   // Contour
803   dc.SetPen(*wxBLACK_PEN);
804   dc.SetBrush(*wxBLACK_BRUSH);
805   dc.DrawLine(m_LeftLegend, m_TopLegend, m_RightLegend, m_TopLegend);
806   dc.DrawLine(m_RightLegend, m_TopLegend, m_RightLegend, m_BottomLegend);
807   dc.DrawLine(m_RightLegend, m_BottomLegend, m_LeftLegend, m_BottomLegend);
808   dc.DrawLine(m_LeftLegend, m_BottomLegend, m_LeftLegend, m_TopLegend);
809
810   // For each dataset
811   int maxdataset = GetNumDataSet();
812   for (int a=0; a < maxdataset; a++) {
813     if (m_dataSetArray[a] && m_dataSetArray[a]->GetShow()) {
814       compt++;
815       // Text
816       string = m_dataSetArray[a]->GetText();
817       sprintf(text,"%s",string);
818       dc.GetTextExtent(wxString(text, wxConvUTF8),&widthx,&heighty);
819       resulta = div(compt, 2);
820       l_posx = m_LeftLegend;
821       l_posy =  m_TopLegend;
822       if (resulta.rem == 0) {
823         l_posx+= l_larg/2;
824         l_posy+= (haut_ligne * resulta.quot);
825       }
826       else
827         l_posy+= (haut_ligne * (resulta.quot+1));
828       l_posy-= (haut_ligne/2);
829
830       // proportion
831       if (nbre==1)
832         l_posx = m_LeftLegend + ((l_larg - l_trait - l_space - widthx)/2) - l_debut;
833
834       // ligne
835       dataBrush = m_dataSetArray[a]->GetDataStyle();
836       dataPen = m_dataSetArray[a]->GetLineStyle();
837       dataPen->SetWidth(2);
838       dc.SetBrush(*dataBrush);
839       dc.SetPen(*dataPen);
840       dc.DrawLine(l_posx + l_debut, l_posy, l_posx + l_debut + 15, l_posy);
841       dataPen->SetWidth(1);
842
843       // text
844       dc.SetFont(*(new wxFont(1, wxDEFAULT, wxNORMAL, wxBOLD)));
845       dc.SetPen(*wxBLACK_PEN);
846       dc.SetBrush(*wxBLACK_BRUSH);
847       dc.DrawText(wxString(text, wxConvUTF8),l_posx + l_debut + l_trait + l_space ,l_posy - (heighty/2));
848       dc.SetFont(*(new wxFont(1, wxDEFAULT, wxNORMAL, wxLIGHT)));
849     }
850   }
851 }
852
853
854 void wxChart::DrawLine(wxDC &dc, int a)
855 {
856   int compt=0;
857   double val;
858   double mid = m_Bottom - ((m_Bottom-m_Top)/2);
859   int maxitem = GetNumItem();
860
861   float yprec, xprec;
862   float xsuiv, ysuiv;
863
864   for(int j=0; j < maxitem; j++) {
865     if ( IsEmpty(a,j) == false ) {
866       compt++;
867       xsuiv = m_Left + ((GetDataX(a,j) - m_MinX ) * m_StepSizeX);
868       val = GetDataY(a,j);
869       if ( a == wxStenosis)
870         // Axe Per for Stenosis
871         ysuiv = mid - (val * m_StepSizePer);
872       else
873         // Axe X
874         ysuiv = m_Bottom - (val * m_StepSizeY);
875
876       // Draw line
877       if (compt > 1)
878         dc.DrawLine((int)xprec, (int)yprec, (int)xsuiv, (int)ysuiv);
879
880       // save point prec
881       xprec = xsuiv;
882       yprec = ysuiv;
883     }
884   }
885 }
886
887
888 // Click Mouse
889 //-----------------------------------------------------------------
890 void wxChart::OnLeftClick(wxDC &dc, double x, double y, int keys)
891 {
892   // TO IMPLEMENT
893 }
894
895 void wxChart::OnRightClick(wxDC &dc, double x, double y, int keys)
896 {
897   // TO IMPLEMENT
898 }
899
900
901 // Data
902 //--------------------------------------------------------------------
903 void wxChart::InitData()
904 {
905   SetNumItem(0);
906   for(int a=0; a<MAX_DATASET; a++) {
907     for(int j=0; j<MAX_ITEM; j++) {
908       m_table[a][j].x=0.00;
909       m_table[a][j].y=0.00;
910       m_table[a][j].empty = true;
911     }
912   }
913 }
914
915 bool  wxChart::IsEmpty(int a, int j)
916 {
917   return m_table[a][j].empty;
918 }
919
920
921 double wxChart::GetDataX(int a, int j)
922 {
923   return  m_table[a][j].x;
924 }
925
926 double wxChart::GetDataY(int a, int j)
927 {
928   return  m_table[a][j].y;
929 }
930
931
932 void wxChart::SetData(int a, int j, double x, double y)
933 {
934   m_table[a][j].x = x;
935   m_table[a][j].y = y;
936   m_table[a][j].empty = false;
937 }
938
939
940 void wxChart::ShowDataSet(bool show,int dataset)
941 {
942   if(m_dataSetArray[dataset])
943     m_dataSetArray[dataset]->Show(show);
944 }
945
946 bool wxChart::GetShowDataSet(int dataset)
947 {
948   if(m_dataSetArray[dataset])
949     return m_dataSetArray[dataset]->GetShow();
950   else
951     return 1;
952 }
953
954