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

Message ListMessage List     Post MessagePost Message

  Add image and line on Realtime chart on VB6 ?
Posted by Norm on Mar-03-2018 03:45
Attachments:
Hi,

Is it possible to add a scrollable half vertical line, a scrollable icon and character on Realtime chart while process as I represented in the red ellipse of this zoomed image ?

Thanks
AsInsideEllipse.jpg

  Re: Add image and line on Realtime chart on VB6 ?
Posted by Norm on Mar-03-2018 03:46
I forgot to specify on VB6 !

  Re: Add image and line on Realtime chart on VB6 ?
Posted by Peter Kwan on Mar-05-2018 15:18
Attachments:
Hi Norm,

There are several methods to create the scrollable half vertical line, icons and text. The easiest method is to just use data symbols.

In a normal line chart, the code is like:

Dim layer As lineLayer
Set layer = c.addLineLayer2()
Call layer.setXData(viewPortTimeStamps)
Call layer.addDataSet(viewPortDataSeriesA, &HFF0000, "Product Alpha")
Call layer.addDataSet(viewPortDataSeriesB, &HCC00, "Product Beta")

You have one data set for each line. If you want to add icons, you can create another line, but set the line width to 0. So you cannot see the line, but you can still use data symbols for the data points. In your case, only some positions have symbols. For other positions that do not have symbols, just use cd.NoValue as the data value.

An example is like:

Dim layer As lineLayer
Set layer = c.addLineLayer2()
Call layer.setXData(viewPortTimeStamps)

' The normal lines
Call layer.addDataSet(viewPortDataSeriesA, &HFF0000, "Product Alpha")
Call layer.addDataSet(viewPortDataSeriesB, &HCC00, "Product Beta")

' The symbol
Dim ds As DataSet
Set ds = layer.addDataSet(viewPortSymbolDataSeries, &HAADDFF)
Call ds.setLineWidth(0)
Call ds.setDataSymbol(cd.GlassSphereShape, 13, &HAADDFF)

In the above, the viewPortSymbolDataSeries is an array of numbers for the y-coordinates of the symbol. If there is no symbol for a certain position, please use cd.NoValue as the y-coordinate.

The above uses a circle as the symbol. For the small vertical line segment, you can use  a vertical line segment as the symbol. This symbol can be created with a custom DrawArea. This is like:

' Create DrawArea 1 x 17 in size with a red background. This becomes a red vertical line
Dim mySymbol As DrawArea
Set mySymbol = cd.DrawArea()
Call mySymbol.setSize(1, 17, &HFF0000)

' Use the above as the symbol
Dim ds As DataSet
Set ds = layer.addDataSet(viewPortSymbolDataSeries2, &HAADDFF)
Call ds.setLineWidth(0)
Call ds.setDataSymbol3(mySymbol)

For the gradient line at the bottom (near 02:30 and 03:00), they look like grid lines to me. You can use a semi-transparent gradient for the grid lines to achieve this effect. For example:

Dim gridLineColor As Long
gridLineColor = c.linearGradientColor(0, c.getPlotArea().getBottomY(), 0, c.getPlotArea().getBottomY() - 50, &H8888FF, cd.Transparent)
Call c.getPlotArea().setGridColor(cd.Transparent, gridLineColor)

For the text, if the text is associated with the symbols, and the text are the same except the data value is different, you can use DataSet.setDataLabelFormat to add the text to the symbol and use DataSet.setDataLabelStyle for configure the font size and style. An example is:

Call ds.setDataLabelFormat("{value} degrees")

See:

http://www.advsofteng.com/doc/cdcom.htm#symbolline.htm

If the text is different for every symbol, you can use custom labels. See:

http://www.advsofteng.com/doc/cdcom.htm#scatterlabels.htm

If the texts are put in positions that may not have symbols, you can just add another data series with transparent symbols. In this way, the symbol will not be visible but will be used as the position to put your text.

If the texts are just put along the top border or bottom border of the plot area, you can also use Axis.addMark. It is like:

Dim m As Mark
Set m = c.xAxis().addMark(xCoor, -1, "ABC Text", "arialbd.ttf", 8)
Call m.setMarkColor(cd.Transaparent, &HFF6600)
Call m.setAlignment(cd.Top)

In your case, you just need to use binary search to determine the marks that are within the visible axis scale, then use a loop to add those marks.

For your reference, I have attached a VB6 realtime chart example which is zoomable and scrollable, and with one series used for symbols.

Hope this can help.

Regards
Peter Kwan
vb6_realtimezoomscroll.zip
vb6_realtimezoomscroll.zip

7.73 Kb
    
vb6_realtimezoomscroll.png

  Re: Add image and line on Realtime chart on VB6 ?
Posted by Norm on Mar-06-2018 00:56
Attachments:
Hi Peter,

I set my array as this :
Private Const sampleSize = 4460
Private Const sampleSize2 = 100

Private timeStamps(sampleSize - 1)
Private dataSeries1(sampleSize - 1)

Private dataSeriesVert(sampleSize2 - 1)
Private dataSeriesBleu(sampleSize2 - 1)
Private timeStampsVert(sampleSize2 - 1)
Private timeStampsBleu(sampleSize2 - 1)
Private dataSeriesRouge(sampleSize2 - 1)
Private timeStampsRouge(sampleSize2 - 1)
Private dataSeriesExtérieur(sampleSize2 - 1)
Private timeStampsExtérieur(sampleSize2 - 1)

You will notice that I'm using two sizes for different array to reduce a cpu usage while a shiftdata process,  100 or 4460(for 86400 seconds by day with an update each 19.3 second)

On the photo#1 you can notice that line for timeStampsBleu is visible, so I'm obligate to set a line color to cd.Transparent :

///// CodeA
Dim layerbleu As lineLayer
Set layerbleu = c.addLineLayer2()
Call layerbleu.setXData(timeStampsBleu())
Call layerbleu.addDataSet(dataSeriesBleu, cd.Transparent, "")
Dim ds As DataSet
Set ds = layerbleu.addDataSet(dataSeriesBleu, &HAADDFF)
Call ds.setLineWidth(0)
Call ds.setDataSymbol(cd.CircleSymbol, 13, &H10F00FF)


I tried with this CodeB to set symbol  to no transparent :

/// CodeB
Dim layerbleu As lineLayer
Set layerbleu = c.addLineLayer2()
Call layerbleu.setXData(timeStampsBleu())
Call layerbleu.addDataSet(dataSeriesBleu, cd.Transparent, "").setDataSymbol(cd.CircleSymbol, 13, &H10000FF)

But a symbol is again transparent as photo3 and appear identical to photo2

On the photo#2 with codeA I set a symbol color with H1 for solid color but it transparent anyway !

On the photo4 and photo5 you will can observ a final result obtained with codeB using 10 array :

- 1 principal array set to 4460 for data (x-coordinate)
- 1 other array set to 4460 for timestamps (y-coordinate) !
- 4 differents array set to 100 for data (x-coordinate)
- 4 others array set to 100 for timestamps (y-coordinate) !

Later I will use two others array to add a text for displaying outdoor temperatue with your previous suggestions  !

Now Two questions for you :
1 - How hide a line under each symbol ?
2 - Which code is a best, CodeA or CodeB for a best performance ?

Thanks Peter !
Compare.jpg

  Re: Add image and line on Realtime chart on VB6 ?
Posted by Peter Kwan on Mar-06-2018 23:44
Hi Norm,

For your case, code B is correct. If your Layer contains only the symbols, there is no need to use layerbleu.addDataSet(dataSeriesBleu, cd.Transparent, ""). Just use:

Dim layerbleu As lineLayer
Set layerbleu = c.addLineLayer2()
Call layerbleu.setXData(timeStampsBleu())
Call layerbleu.addDataSet(dataSeriesBleu, cd.Transparent, "").setDataSymbol(cd.CircleSymbol, 13, &H0000FF)

For both code A and B, the symbols are not transparent, but they are bebind the green line. If you want the symbols to be in front of the green line, please add the LineLayer for the symbol first, followed by the LineLayer for the green line. If you want to add the green line first, followed by the symbol in another LineLayer, you can use Layer.moveFront to move the symbol in front of the line.

Call layerbleu.moveFront(layerGreenLine)


In the VB6 Realtime chart sample code that comes with ChartDirector for ASP/COM/VB, it uses "ShiftData" to shift the new data into the array and remove old data points from the array.

In the "Realtime Chart with Zooming and Scrolling" sample code attached to you in my last message, because of zooming and scrolling support, it is usually another method. The data initially are appended to the array. When the array is full, it will shift the array by 5%. For example, if the array contains 5000 elements, it will shift is by 250 elements.  So it only shift the array once very 250 points, and the CPU usage is very low.

In the sample code in my last message, all arrays are of the same length. In this way, only one timeStamps array and one LineLayer is necessary for all the lines and symbols. It is also easier to write the code to support zooming and scrolling as there is only one timeStamps array.

Regards
Peter Kwan