ASE Home Page Products Download Purchase Support About ASE
ChartDirector Support
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

Posted by Norm on Apr-12-2018 23:07
I’m using ChartDirector as realtime chart on VB6!
My chart content data for 24 hours with 4460 entry  for 19.5 seconds each !:

I have 1 array for timestamps and 10 others array for different data as this:
Public Const sampleSize = 4460
Public dataSeries1(sampleSize - 1)
Public timeStamps(sampleSize - 1)
Public dataSeriesDefrostToléré(sampleSize - 1)
Public dataSeriesSouhait(sampleSize - 1)
Public dataSeriesRouge(sampleSize - 1)
Public dataSeriesVert(sampleSize - 1)
Public dataSeriesBleu(sampleSize - 1)
Public dataSeriesExtérieur(sampleSize - 1)
Public dataSeriesExtérieurText(sampleSize - 1)
Public dataSeriesDefrost(sampleSize - 1)
Public dataSeriesMinuit(sampleSize - 1)

When loading the DrawChart function (every 19 seconds), near of the end of this function exist  a command:
Set viewer.Picture = c.makePicture ()

I know that this command is one of the last command to draw a chart

This command requires 550ms to complete a draw, and during this time all events on VB6 are delayed!

Exemple, when scrool my ListView or when I move a Form.

I tried to use a timer to start a DrawChart function, but this Delay is again present for all others events VB6!

I noticed this observation in the VB6 environment and with a real .EXE executable compiled for a standalone instance.

On my form, I added a Check9 control and add a condition on drawChart function to make sure !

Dim d As Double
d = GetTickCount
If Form1.Check9.Value = vbChecked Then Set viewer.Chart = c '
Form1.Label6 = GetTickCount - d
I'm observing this:

When Check9 is checked, the difference is 550 ms and, when not checked, the difference is 0 ms

I tried this :
Set viewer.Picture = c.makePicture ()
Set viewer.Chart = c

Does exist anothers command  running to BackGround as a shell to complete drawing of a chartViewer control ?

Which is a best ?


  Re: Delay
Posted by Peter Kwan on Apr-14-2018 02:28
Hi Norm,

I have just done a test with 10 lines in one LineLayer, each 10000 data points. In my test case, even on 10-year old computer (using Q8400 CPU, 8G DDR2 RAM), it only takes less than 50ms (around 35ms) if the chart is 640 x 350 in size, and less than 200ms (around 170ms) if the chart is 1920 x 1080 in size. The chart I used is a line chart with fast line mode enabled (LineLayer.setFastLineMode).

For your reference, my test code is based on the following "Realtime Chart with Zooming and Scrolling" sample code:

The above code is modified to create data at a rate of 40 points per second per line, so it should reach thousands of points per line quickly. (The random number generator only generate 3 lines in the above code, but during testing, I changed it to 10 lines and it still runs quickly.)

Note that the pixel count of the chart affects the speed quite a lot.

For your case, I am not sure of the CPU speed or the chart size. But if it is similar to my test case, the speed would be slower than expected. May be you can try to see if you can speed up the code a bit. A pure line chart drawing using "fast line mode" with symbols is usually the fastest.

Because VB6 does not support multi-threading, so it is more complicated if you want to create the chart in the background. As mentioned in your last message, we need to use  "shell" to run another program. You can try to write another program that just creates the chart and save it as an image to a file (using BaseChart.makeChart). In your main program, you can periodically check if the image file has been updated and use LoadPicture to load the file into a Picture object and set it to the ChartViewer. One disadvantage of this method is that you can only display the chart, but the user interactions features (track cursors, zooming and scrolling, etc) would not be supported.

In my opinion, for VB6, it should be better to just use one program, and try to speed up the code to make it fast enough.

Peter Kwan

  Re: Delay
Posted by Norm on Apr-20-2018 00:49
Hi Peter,

With your last suggestion, I reduce a pixel count for my ChartViewer1 and reduced the time to 16ms and sometime to 32ms. A ChartViewer1 width was set to 7526 ...

So I want to inform you about how I took to reduce this time

Before it was as follows:
Public dataSeries1(4460 - 1)
Public timeStamps(4460 - 1)
Public dataSeriesDefrostToléré(4460 - 1)
Public dataSeriesSouhait(4460 - 1)
Public dataSeriesRouge(4460 - 1)
Public dataSeriesVert(4460 - 1)
Public dataSeriesBleu(4460 - 1)
Public dataSeriesExtérieur(4460 - 1)
Public dataSeriesExtérieurText(4460 - 1)
Public dataSeriesDefrost(4460 - 1)
Public dataSeriesMinuit(4460 - 1)

So I increased the number of Array but I decreased their size(no more than necessary) as follows:

After :
Public timeStamps(4460 - 1)
Public dataSeries1(4460 - 1)
Public timeStampsDefrostToléré(2000 - 1)
Public dataSeriesDefrostToléré(2000 - 1)
Public timeStampsSouhait(2000 - 1)
Public dataSeriesSouhait(2000 - 1)
Public timeStampsExtérieurText(96 - 1)
Public dataSeriesExtérieurText(96 - 1)
Public timeStampsExtérieur(96 - 1)
Public dataSeriesExtérieur(96 - 1)
Public timeStampsRouge(96 - 1)
Public dataSeriesRouge(96 - 1)
Public timeStampsBleu(96 - 1)
Public dataSeriesBleu(96 - 1)
Public timeStampsVert(96 - 1)
Public dataSeriesVert(96 - 1)
Public timeStampsDefrost(10 - 1)
Public dataSeriesDefrost(10 - 1)
Public timeStampsMinuit(10 - 1)
Public dataSeriesMinuit(10 - 1)

Also in order to avoid drawing a chart each 250ms during the scrolls I had chosen to set a Charttviewer1  wider than the Form1, and to set a left position (hidden) on the left side of the Form1 ! This large size was a principal reason for excessive delay for drawing. I named this function “Simili-Scrool”. With this methode a function DrawChart is called only to an interval of 19 seconds.

Before was  :
Set  c = cd.XYChart(7526, 190, co.BackGroundScaleXY, co.BackGroundScaleXY, 0)
lastTime = timeStamps(UBound(timeStamps))
Call c.xAxis().setDateScale(lastTime -86400, lastTime)
Form1.ChatViewer1.left = -98735
With this method(Simili-Scrool), when I was ready to scroll a ChatViewer1, I was  just to move to my mouse to left  side to change a left position. Was no needing to redraw a graph with DrawChart function .

After this:
Set  c = cd.XYChart(918, 190, co.BackGroundScaleXY, co.BackGroundScaleXY, 0)
lastTime = timeStamps(UBound(timeStamps))
Call c.xAxis().setDateScale(lastTime -10800, lastTime)
Form1.ChatViewer1.left = 0

But now, because these new values,  it  impossible to use my simili-Scrool function. So,  when I want use my simili-scrool (one or two times by day), I just to do this :
Change value  from 918 to 7526 for width
Change value  from 0 to  -98735 for left position of Chartviewer1
Change value  from 10800 to 86400 (3hours to 24hours) for setDateScale
Call once time a DrawChart  function.
And when I termined to do a simili-scooling 90 second later, I just to return with previous values and call DrawChart function to return with a normal size.

Later, to each 19 seconds when I receive Data from my Arduino Card by a Serial COM Port ,  I just to  call DrawChart function to update ChartViewer1.

I know that you will say me that it a curious or weird method, but this is very fast and work fine. When my program run my PC CPU Process is continually to 0% without peak.

About a ShiftData function for all 20 array, when I start my program I needing to load my old data from my database for last 24 hours and 375 ms is necessary for ShiftData.

When I receive data for my Arduino card (each 19 seconds), 0ms is necessary for ShiftData. And finally 16ms for DrawChart function.

Thanks for your help !