@@ -76,7 +76,7 @@ namespace OpenCVGUI {
76
76
}
77
77
}
78
78
79
- void OGUIPlotArea::drawLinePlot (){
79
+ void OGUIPlotArea::drawSeriesPlot (){
80
80
float margin= 120 ;
81
81
float start_x= x+margin/2 .0f ;
82
82
float x_length= data.cols ;
@@ -249,6 +249,194 @@ namespace OpenCVGUI {
249
249
}
250
250
}
251
251
252
+ void OGUIPlotArea::drawLinePlot (){
253
+ float margin= 120 ;
254
+ float start_x= x+margin/2 .0f ;
255
+ float start_y= y+height-margin/2 .0f ;
256
+
257
+ float x_length= data.cols ;
258
+ float dx= (width-margin);
259
+
260
+ // Extract X and Y separatly
261
+ vector<Mat> plot_channels;
262
+ split (data, plot_channels);
263
+ double min_x=0.0 ;
264
+ double max_x=1.0 ;
265
+ double mx=0 ;
266
+ double min_y=0.0 ;
267
+ double max_y=1.0 ;
268
+ double my=0 ;
269
+
270
+ minMaxLoc (plot_channels[0 ], &min_x, &max_x, NULL , NULL );
271
+ mx= (max_x-min_x);
272
+
273
+ minMaxLoc (plot_channels[1 ], &min_y, &max_y, NULL , NULL );
274
+ my= (max_y-min_y);
275
+
276
+ float dy= (height-margin);
277
+
278
+
279
+ NVGcontext* vg= (NVGcontext*)(window->vg );
280
+
281
+ // Plot each graph
282
+ for (int p=0 ; p<data.rows ; p++) {
283
+ int c=p*3 ;
284
+ NVGcolor color= nvgRGBA (color_scheme.at (c), color_scheme.at (c+1 ), color_scheme.at (c+2 ), 255 );
285
+ nvgBeginPath (vg);
286
+ for (int i = 0 ; i < data.cols ; i++) {
287
+ Vec2f values= data.at <Vec2f>(p,i);
288
+ float p_x=start_x + dx * ((values[0 ]-min_x) / mx);
289
+ float p_y=start_y - dy * ((values[1 ]-min_y) / my);
290
+ if (i==0 )
291
+ nvgMoveTo (vg, p_x, p_y);
292
+ else
293
+ nvgLineTo (vg, p_x, p_y);
294
+ }
295
+ nvgStrokeColor (vg, color);
296
+ nvgStrokeWidth (vg, 2 .0f );
297
+ nvgStroke (vg);
298
+
299
+
300
+ // Dots
301
+ for (int i = 0 ; i < data.cols ; i++) {
302
+ Vec2f values= data.at <Vec2f>(p,i);
303
+ float dot_x=start_x + dx * ((values[0 ]-min_x) / mx);
304
+ float dot_y=start_y - dy * ((values[1 ]-min_y) / my);
305
+
306
+ nvgBeginPath (vg);
307
+ nvgCircle (vg, dot_x, dot_y, 3 .0f );
308
+ nvgFillColor (vg, nvgRGBA (220 , 220 , 220 , 255 ));
309
+ nvgFill (vg);
310
+
311
+ nvgBeginPath (vg);
312
+ nvgCircle (vg, dot_x, dot_y, 2 .0f );
313
+ nvgFillColor (vg, color);
314
+ nvgFill (vg);
315
+
316
+ }
317
+ }
318
+
319
+ nvgResetScissor (vg);
320
+ // Plot hover labels
321
+ for (int p=0 ; p<data.rows ; p++) {
322
+ int c=p*3 ;
323
+ NVGcolor color= nvgRGBA (color_scheme.at (c), color_scheme.at (c+1 ), color_scheme.at (c+2 ), 255 );
324
+ // Dots
325
+ for (int i = 0 ; i < data.cols ; i++) {
326
+ Vec2f values= data.at <Vec2f>(p,i);
327
+ float dot_x=start_x + dx * ((values[0 ]-min_x) / mx);
328
+ float dot_y=start_y - dy * ((values[1 ]-min_y) / my);
329
+ // Draw hover label
330
+ if (isMouseIn ()) {
331
+ if ( dot_y-4 <= window->mouse_y && window->mouse_y <= dot_y+4 &&
332
+ dot_x-4 <= window->mouse_x && window->mouse_x <= dot_x+4 ){
333
+
334
+ // Calculate text width for box
335
+ nvgFontSize (vg, 16 .0f );
336
+ nvgFontFace (vg, " sans" );
337
+ nvgTextAlign (vg, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE);
338
+ stringstream ss_value;
339
+ ss_value.precision (4 );
340
+ ss_value << _labels.at (p) <<" : " << values[0 ] << " , " << values[1 ];
341
+ float tw = nvgTextBounds (vg, 0 , 0 , ss_value.str ().c_str (), NULL , NULL );
342
+
343
+ nvgBeginPath (vg);
344
+ nvgRect (vg, dot_x-tw-20 , dot_y-32 , tw+20 , 32 );
345
+ nvgFillColor (vg, nvgRGBA (0 , 0 , 0 , 200 ));
346
+ nvgFill (vg);
347
+
348
+ // Draw text
349
+ nvgFillColor (vg, nvgRGBA (255 , 255 , 255 , 255 ));
350
+ nvgText (vg, dot_x - tw - 10 , dot_y - 16 , ss_value.str ().c_str (), NULL );
351
+ }
352
+ }
353
+ }
354
+ }
355
+ nvgScissor (vg, x, y, width, height);
356
+
357
+ // /Plot labels box
358
+ nvgBeginPath (vg);
359
+ nvgRect (vg, x + width - 100 -20 , y + 40 , 120 , 15 + data.rows *20 );
360
+ nvgFillColor (vg, nvgRGBA (0 , 0 , 0 , 100 ));
361
+ nvgFill (vg);
362
+ for (int p=0 ; p<data.rows ; p++) {
363
+ int c = p * 3 ;
364
+ NVGcolor color = nvgRGBA (color_scheme.at (c), color_scheme.at (c + 1 ), color_scheme.at (c + 2 ), 255 );
365
+ float dot_x=x + width - 100 ;
366
+ float dot_y=y + 60 + p*20 ;
367
+ nvgBeginPath (vg);
368
+ nvgCircle (vg, dot_x, dot_y, 4 .0f );
369
+ nvgFillColor (vg, color);
370
+ nvgFill (vg);
371
+
372
+ // Calculate text width for box
373
+ nvgFontSize (vg, 16 .0f );
374
+ nvgFontFace (vg, " sans" );
375
+ nvgTextAlign (vg, NVG_ALIGN_LEFT);
376
+ // Draw text
377
+ nvgFillColor (vg, nvgRGBA (255 , 255 , 255 , 255 ));
378
+ nvgText (vg, dot_x + 10 , dot_y+3 , _labels.at (p).c_str (), NULL );
379
+ }
380
+
381
+ // X axis
382
+ nvgBeginPath (vg);
383
+ nvgMoveTo (vg, start_x, start_y);
384
+ nvgLineTo (vg, start_x+width-margin, start_y);
385
+ nvgStrokeColor (vg, nvgRGBA (255 ,255 ,255 ,255 ));
386
+ nvgStrokeWidth (vg, 1 .0f );
387
+ nvgStroke (vg);
388
+
389
+ // Lines x axis coord
390
+ for (int i=1 ; i<=10 ; i++){
391
+ nvgBeginPath (vg);
392
+ nvgMoveTo (vg, start_x + (i/10 .0f ) * dx, start_y);
393
+ nvgLineTo (vg, start_x + (i/10 .0f ) * dx, start_y + 5 );
394
+ nvgStrokeColor (vg, nvgRGBA (255 , 255 , 255 , 255 ));
395
+ nvgStrokeWidth (vg, 1 .0f );
396
+ nvgStroke (vg);
397
+
398
+ // Text label
399
+ stringstream ss;
400
+ ss << (min_x + i*mx/10 );
401
+ nvgFontSize (vg, 12 .0f );
402
+ nvgFontFace (vg, " sans" );
403
+ float tw = nvgTextBounds (vg, 0 , 0 , ss.str ().c_str (), NULL , NULL );
404
+ nvgTextAlign (vg, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE);
405
+ nvgFillColor (vg, nvgRGBA (255 , 255 , 255 , 255 ));
406
+ nvgText (vg, start_x + (i/10 .0f ) * dx, start_y + 10 , ss.str ().c_str (), NULL );
407
+ }
408
+
409
+ // Y axis
410
+ nvgBeginPath (vg);
411
+ nvgMoveTo (vg, start_x, start_y);
412
+ nvgLineTo (vg, start_x, start_y-dy);
413
+ nvgStrokeColor (vg, nvgRGBA (255 ,255 ,255 ,255 ));
414
+ nvgStrokeWidth (vg, 1 .0f );
415
+ nvgStroke (vg);
416
+
417
+ // Lines y axis coord
418
+ for (int i=1 ; i<=10 ; i++){
419
+ nvgBeginPath (vg);
420
+ nvgMoveTo (vg, start_x, start_y-(i/10 .0f )*dy);
421
+ nvgLineTo (vg, start_x-5 , start_y-(i/10 .0f )*dy);
422
+ nvgStrokeColor (vg, nvgRGBA (255 ,255 ,255 ,255 ));
423
+ nvgStrokeWidth (vg, 1 .0f );
424
+ nvgStroke (vg);
425
+
426
+ // Text label
427
+ stringstream ss;
428
+ ss.precision (2 );
429
+ ss << (min_y + i*my/10 );
430
+ nvgFontSize (vg, 12 .0f );
431
+ nvgFontFace (vg, " sans" );
432
+ float tw = nvgTextBounds (vg, 0 , 0 , ss.str ().c_str (), NULL , NULL );
433
+ nvgTextAlign (vg, NVG_ALIGN_RIGHT | NVG_ALIGN_MIDDLE);
434
+ nvgFillColor (vg, nvgRGBA (255 , 255 , 255 , 255 ));
435
+ nvgText (vg, start_x-10 , start_y-(i/10 .0f )*dy, ss.str ().c_str (), NULL );
436
+ }
437
+
438
+ }
439
+
252
440
void OGUIPlotArea::drawScatterPlot (){
253
441
float margin= 120 ;
254
442
float start_x= x+margin/2 .0f ;
@@ -426,6 +614,9 @@ namespace OpenCVGUI {
426
614
void OGUIPlotArea::drawPlot () {
427
615
428
616
switch (_plot_type){
617
+ case PLOT_SERIES:
618
+ drawSeriesPlot ();
619
+ break ;
429
620
case PLOT_LINE:
430
621
drawLinePlot ();
431
622
break ;
0 commit comments