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

Message ListMessage List     Post MessagePost Message

  Need Help for a Dual Y-Axis chart
Posted by Karsten Stein on Jan-15-2025 23:05
Attachments:
Hello friends,

I would like to create a chart with two Y axes and I can't figure out how to do the following things:

1. The second Y axis should be in rounded 200 steps, not like 238.4.

2. The borderline of the bar charts should be “hairline” / ultra-thin. This is too thick at the moment.

3. Connect the bars with lines.

4. The axis description should be at the top of the axis, not in the middle left/right.

The first point in particular is very important to me. A picture is attached for better understanding. I still use MicrosoftOfficeChart, but would like to replace this with ChartDirector.

Here is the code in short:

    SingleCW = Array(8, 14)
    SingleWW = Array(5, 7)
    TotalCW = Array(744, 712)
    TotalWW = Array(334, 303)
    fFactor = 47.68
    fMaxTotal = 1200
    fMaxSingle = fMaxTotal / fFactor

    Set c = cd.XYChart(500, 500)
    Call c.setPlotArea(26, 35, 435, 290, cd.TRANSPARENT, -1, cd.TRANSPARENT, &HCCCCCC)

    Call c.addTitle("Consumption cold- and warmwater")
    Call c.yAxis().setLinearScale(0, 30, 5)

    Set layer = c.addBarLayer2(cd.Stack, 0)
    Set layer2 = c.addBarLayer2(cd.Stack, 0)
    Call layer2.setUseYAxis2

    Call layer.addDataGroup("Single")
    Call layer.addDataSet(SingleCW, &HFF670A, "Single CW")
    Call layer.addDataSet(SingleWW, &HFFA74A, "Single WW")
    Call layer.addDataGroup("Total")
    Call layer2.addDataSet(TotalCW, &H3F63DF, "Total CW")
    Call layer2.addDataSet(TotalWW, &H7FA3FF, "Total WW")

    Call layer.setBarGap(0.5, 0.2)
    Call layer2.setBarGap(0.7)
    Call layer2.alignLayer(layer, 1)
    Call layer2.setBarWidth(50)
    Call c.syncYAxis(fFactor, 0)

    Call layer.setDataLabelStyle("Dax-Regular.ttf", 10, &HFFFFFF).setAlignment(cd.Center)
    Call layer.setDataLabelFormat("{value|0.,}")
    Call layer2.setDataLabelStyle("Dax-Regular.ttf", 10, &HFFFFFF).setAlignment(cd.Center)
    Call c.xAxis().setLabels(Array(2021, 2022)) ' Set the labels on the x axis.

    ' Output the chart
    Set viewer.Picture = c.makePicture()


Regards
Karsten Stein
ChartDirector.gif

  Re: Need Help for a Dual Y-Axis chart
Posted by Peter Kwan on Jan-16-2025 01:59
Attachments:
Hi Karsten,

I have modified the code to obtain the attached chart. I think it is similar to what you want.

For your case, the two y-axes are not synchronized. Even in the Microsoft chart, the labels do not align. The two y-axes are independent axes. In this case, ChartDirector will auto-scale each axis to best fit the data for that axes.

The ChartDirector "borderline" is 1 pixel thin - same as that in Microsoft's chart. This is the thinnest possible line. You can make the line look even thinner by using semi-transparent colors. In the code, I set the border color to semi-transparent black. You can make it look even thinner if you increase the transparency in the color.

To connect the bars with lines, you may use addLineLayer.

I use Axis.addTitle to add the axis titles and use top alignment to put them on top of the axis.


    Dim cd As New ChartDirector.API

    SingleCW = Array(8, 14)
    SingleWW = Array(5, 7)
    TotalCW = Array(744, 712)
    TotalWW = Array(334, 303)

    Set c = cd.XYChart(500, 500)
    Call c.setPlotArea(26, 35, 435, 290, cd.Transparent, -1, cd.Transparent, &HCCCCCC)

    Call c.addTitle("Consumption cold- and warmwater")
    Call c.yAxis().setLinearScale(0, 30, 5)

    Call c.yAxis().setTitle("m<*super*>3", "arialbd.ttf", 10, &HFF670A).setAlignment(cd.Top)
    Call c.yAxis2().setTitle("m<*super*>3", "arialbd.ttf", 10, &H3F63DF).setAlignment(cd.Top)
    Call c.yAxis().setLabelStyle("arialbd.ttf", 10)
    Call c.yAxis2().setLabelStyle("arialbd.ttf", 10)

    Set layer = c.addBarLayer2(cd.Stack, 0)
    Call layer.setBorderColor(&H80000000)
    Call layer.setBarGap(0.3, 0.1)

    Call layer.addDataGroup("Single")
    Call layer.addDataSet(SingleCW, &HFF670A, "Single CW")
    Call layer.addDataSet(SingleWW, &HFFA74A, "Single WW")

    Call layer.addDataGroup("Total")
    Call layer.addDataSet(TotalCW, &H3F63DF, "Total CW").setUseYAxis2
    Call layer.addDataSet(TotalWW, &H7FA3FF, "Total WW").setUseYAxis2

    Set layer3 = c.addLineLayer(SingleCW, c.dashLineColor(&HFF670A))
    Call layer3.alignLayer(layer, 0)
    Call layer3.moveFront

    Set layer4 = c.addLineLayer(cd.ArrayMath(SingleCW).Add(SingleWW).result(), c.dashLineColor(&HFF670A))
    Call layer4.alignLayer(layer, 0)
    Call layer4.moveFront

    Set layer5 = c.addLineLayer(TotalCW, c.dashLineColor(&H3F63DF))
    Call layer5.setUseYAxis2
    Call layer5.alignLayer(layer, 1)
    Call layer5.moveFront

    Set layer6 = c.addLineLayer(cd.ArrayMath(TotalCW).Add(TotalWW).result(), c.dashLineColor(&H3F63DF))
    Call layer6.setUseYAxis2
    Call layer6.alignLayer(layer, 1)
    Call layer6.moveFront

    Call c.yAxis2().setTickDensity(40)
    Call c.yAxis().setTickDensity(40)

    Call layer.setDataLabelStyle("Dax-Regular.ttf", 10, &HFFFFFF).setAlignment(cd.Center)
    Call layer.setDataLabelFormat("{value|0.,}")

    Call c.xAxis().setLabels(Array(2021, 2022)) ' Set the labels on the x axis.
    Call c.xAxis().setLabelStyle("arialbd.ttf", 10)
    Call c.xAxis().setTickLength(0)
    Call c.xAxis().setLabelGap(10)

    ' Output the chart
    Set viewer.Picture = c.makePicture()


Best Regards
Peter Kwan
test.png

  Re: Need Help for a Dual Y-Axis chart
Posted by Karsten Stein on Jan-16-2025 07:01
Hi Kevin,

looks great, thanks for your huge help. That helps me a lot.

Regards
Karsten Stein

  Re: Need Help for a Dual Y-Axis chart
Posted by Karsten Stein on Jan-16-2025 07:06
Hi Kevin,

one thing is still missing, on the second y-axis, it have to be a fixed factor,  47.68 for example. And then the secondary y-axis should have 200 steps. Is it possible to do that with ChartDirector?

Regards
Karsten Stein

  Re: Need Help for a Dual Y-Axis chart
Posted by Karsten Stein on Jan-16-2025 07:19
Hi Kevin,

>For your case, the two y-axes are not synchronized. Even in the Microsoft chart, the labels do not align. The two y-axes are independent axes. In this case, ChartDirector will auto-scale each axis to best fit the data for that axes.

Is it possible to do that like in Microsoft chart? The labels must not align. But the relationship between left and right axis has to be a given factor. And it's easier to understand numbers like 100, 400 instead of 421. A own scale for the secondary Y-axes, without align to the horizontal line.

Best Regards
Karsten Stein

  Re: Need Help for a Dual Y-Axis chart
Posted by Karsten Stein on Jan-16-2025 08:29
Attachments:
Hi Kevin,

now it works, in use of setLinearScale. Many thanks again for your help.

    fFactor = 47.68
    fMaxTotal = 1200
    fMaxSingle = 30
    Call c.yAxis2.setLinearScale(0, fMaxSingle * fFactor, 200)

Regards
Karsten Stein
Image20.gif

  Re: Need Help for a Dual Y-Axis chart
Posted by Peter Kwan on Jan-16-2025 14:44
Hi Karsten,

If you know the labels step is 200, then Call c.yAxis2.setLinearScale(0, fMaxSingle * fFactor, 200) is what you need.

If you want ChartDirector to automatically pick the labels based on the axis range (the min/max values of the axis), you may synchronize the scale only but not the label positions.

Call c.yAxis2().syncAxis(c.yAxis(), fFactor)

ChartDirector will then automatically determine the labels, which are always "nice numbers" (like one label every 100, 200 500, etc). ChartDirector will consider the min/max value of the axis and the number of labels that can fit on the axis (configurable with setTickDensity) to come up the "nice numbers". For your plot area height, if you can accept at most 7 labels on the y-axis, I think Call c.yAxis2().setTickDensity(30) may be a suitable choice.

Best Regards
Peter Kwan

  Re: Need Help for a Dual Y-Axis chart
Posted by Karsten Stein on Jan-16-2025 15:27
Attachments:
Hi Peter,

but if I use

    Call c.yAxis2().syncAxis(c.yAxis(), fFactor)

same result as

    Call c.syncYAxis(fFactor)

I'l get following diagram:

Regards
Karsten Stein
Image21.gif

  Re: Need Help for a Dual Y-Axis chart
Posted by Peter Kwan on Jan-16-2025 17:04
Hi Karsten.

Sorry, I use the wrong API. It should be:

Call c.yAxis2().syncScale(c.yAxis(), fFactor)

The API should be "syncScale" instead of "syncAxis".

Also, "syncScale" is only available in ChartDirector 7 (the latest version). It is not available in earlier versions of ChartDirector.

Best Regards
Peter Kwan

  Re: Need Help for a Dual Y-Axis chart
Posted by Karsten Stein on Jan-16-2025 18:24
Attachments:
Hi Peter,

I have ChartDirector 7, and your function works:

Call c.yAxis2().syncScale(c.yAxis(), fFactor)

I will get following chart:


Regards
Karsten Stein
Image4.gif

  Re: Need Help for a Dual Y-Axis chart
Posted by Peter Kwan on Jan-16-2025 22:36
Hi Karsten,

If you think the axis labels for the right y-axis is too sparse, you can change the tickDensity. In the code in my previous message, I use:

Call c.yAxis2().setTickDensity(40)

You can change it to the followings for higher label density.

Call c.yAxis2().setTickDensity(30)

Best Regards
Peter Kwan