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