1

I am plotting up to 16 traces, each one with 300 datapoints, I am updating continuously 100 datapoints every 100 ms. So on average I am updating in total 1600 datapoints every 100 ms and that is reaching the limit of points I can plot real time. Is there any way to improve even more the plotting speed or that amount of points is really reaching the limit of what can be achieved with JChart2D.

As a note, JChart2D is way better than other libraries as JFreeChart for real time applications. JFreeChart has a great functionality but is pretty heavy for real time.

The loop I am actually using whenever the swing worker is notified that data has been added is the following:

            for (int l = 0; l < readcycles; l++){   
                sixteenBitNumber = data[l];      
                for (int k = 0; k < (SampledSignalPerPacket); k+=ScreenPointJump){
                    for (int o = 0; o < root.getChildCount(); o++){
                        for (int p = 0; p < graphnodes[o].getChildCount(); p++){
                            if (seriesindex[o][p] > ScreenSize){
                                seriesindex[o][p] = 0;
                            }
                            datapoint = (float)(sixteenBitNumber[signalnodes[o][p].signalIndex + NbOfSampledSignal*k])*10/32767;                               
                            trace[o][p].addPoint(seriesindex[o][p], datapoint);
                            seriesindex[o][p] = seriesindex[o][p] + ScreenPointJump;//seriesindex[o][p]++;
                        }                               
                    }
                }   

            }

where trace has been initialized as

public Trace2DLtd[][] trace =  new Trace2DLtd[4][4];
Camilo Guevara
  • 165
  • 1
  • 12
  • Try something like checking which data has changed and only updating those traces – Teddy Jun 16 '14 at 12:49
  • Thanks Teddy, I am only updating data point when data is received by trace[o][p].addPoint(point); where trace[o][p] is an multidimensional array of 4 by 4 for a total of 16 traces. – Camilo Guevara Jun 16 '14 at 12:58
  • Store the last data array and compare with the new data array. If the data has changed then update the chart. If there is no change in data skip the redraw. – Teddy Jun 16 '14 at 13:03
  • Actually, for my application every single data that come is different (sine wave, sawtooth, etc) But you have a good point, I could add at lease 10 points before refreshing the Chart. I looked for it every where but could find that functionality on JChart2D. Do you know any way how to do it? – Camilo Guevara Jun 16 '14 at 13:57
  • As you said.. keep accumulating the data for a few samples in your java code and then call the charting method. If you share the input or output data formats it can be figured out.. – Teddy Jun 16 '14 at 16:08
  • 1
    Teddy, I just edited my coment and added the loop code where I add data – Camilo Guevara Jun 16 '14 at 16:17
  • Its not an easy scenario and I'm not sure if its useful, anyway: (1) Is your code fast enough? Maybe Jchart2d is not getting the addPoint command fast enough. (2) If Jchart is the bottleneck... can you average 10 data points on every trace and call addPoint only once in 10 data points? (Or even average 50 data points and call once in 50 times) – Teddy Jun 16 '14 at 19:17

1 Answers1

0

Instead of the addPoint line, could you do this? I may be wrong though..

                    datapoint = (float)(sixteenBitNumber[signalnodes[o][p].signalIndex + NbOfSampledSignal*k])*10/32767;                               
                    //trace[o][p].addPoint(seriesindex[o][p], datapoint);
                    avgX[o][p]+=seriesindex[o][p];  //Accumulate
                    avgY[o][p]+=datapoint;          //Accumulate
                    avgCounter[o][p]++;             //Keep track
                    if(avgCounter[o][p]==10){             //Done accumulating... plot average
                        trace[o][p].addPoint(avgX[o][p]/10, avgY[o][p]/10);   //Add average point
                        avgCounter[o][p]=0;  //Clear data
                        avgX[o][p]=0;        //Clear data
                        avgY[o][p]=0;        //Clear data
                    }
                    seriesindex[o][p] = seriesindex[o][p] + ScreenPointJump;//seriesindex[o][p]++;
                }                               
            }
        }   

    }
Teddy
  • 4,009
  • 2
  • 33
  • 55
  • That is a good idea, nevertheless, I am already doing something similar at the hardware level. The hardware is sampling at 10KHz and averaging 5 points so I get a final sampling of 2KHz. This was the only way I got it to plot the 16 signals at the time without problem. When the signal I am sampling is a low freq signal the averaging works, but as soon as the sampled signal is high freq. the end result is horrible. Thanks for the try!!! – Camilo Guevara Jun 16 '14 at 19:43
  • Ok... can you buffer 10 values and call addPoint 10 times in succession? Also chk if loop is bottleneck or drawing. ATB – Teddy Jun 16 '14 at 19:48
  • 1
    Looks like every addPoint is triggering a refresh of the chart. If there was an addPoints(point[]) method to add sets of points it might have been useful. Else if there was a BufferedTracePainter that could have worked as well. – Teddy Jun 16 '14 at 20:27
  • 1
    I added a timer to check which one is the step the takes the bulk of the time and it is definitely addPoint, adding the points 10 times in a row didn't make any difference. And I completely agree having something like addPoints(point[]) would solve the issue, unfortunately is not available. It does indeed refreshes the chart every time I add a point, and I tried to find a way to cancel the refreshing events and only call it very x number of points, I didn't find how to do this either. – Camilo Guevara Jun 16 '14 at 21:07
  • @CamiloGuevara had you fix it? – justcode Aug 08 '18 at 18:41