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