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