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

Message ListMessage List     Post MessagePost Message

  I can’t build a new layer after I found out the scale through layout()
Posted by Alex on Oct-01-2023 02:15
Attachments:
Hi!
I'm making an XY chart with 6 independent dimensions and I'm having a problem.
For clarity, I created a simpler example.
So this code runs and outputs the following.

            double[] Xdata1And3start = { 20, 80, 60 };
            double[] Ydata1And3start = { 40, 30, 100 };

            double[] Xdata3end = { 120, 180, 160 };
            double[] Ydata3end = { 90, 80, 150 };

            XYChart c = new XYChart(450, 390);
            c.setPlotArea(55, 40, 350, 300, -1, -1, 0xc0c0c0, 0xc0c0c0, -1);
            c.xAxis().setWidth(3);
            c.yAxis().setWidth(3);


            c.addScatterLayer(Xdata1And3start, Ydata1And3start);

            c.addVectorLayer(Xdata1And3start, Ydata1And3start, Xdata3end, Ydata3end, Chart.EndPoints, 0x0000cc).setArrowHead(11);

            winChartViewer1.Chart = c;

            winChartViewer1.ImageMap = c.getHTMLImageMap("clickable", "",
                "title='Vector at ({x}, {value}): Length = {len}, Angle = {dir} deg'");

But the problem is that the length and direction of the arrows are dimensions completely independent of X and Y.
Let's say that the arrows should point 50 pixels above and 100 pixels to the right of each red dot - whatever the X and Y values of the red dots would be the next time we run the program. (in reality, the task is, of course, completely different and the values of all coordinates are calculated and not hardcoded in arrays, but I don’t want to complicate my example with real formulas).

So, to solve the problem, I chose the following tactics.
After the line
c.addScatterLayer(Xdata1And3start, Ydata1And3start);
I'm calling
c.layout(); - so that the chart can scale the X and Y axes, which will allow me to call the getXValue and c.getXCoor methods, through which I have a chance to know the resulting scale/proportion between dollars on the X axis (kilograms on the Y axis) - and pixels on the screen.

Then I can add the calculated X-axis and Y-axis values to the starting (red) point of each arrow, which will give me the required 100 pixels to the right and 50 pixels up from the red point on the screen.
However, my tactics are not working.
Because after calling c.layout(); the .addVectorLayer line stops working - i.e. No arrows appear on the screen at all. But without calling c.layout(), I have no way of knowing the scale of the X and Y axes.

Calling the c.layout() method again doesn't help either.
I'm completely confused. Please tell me what to do. I hope that I clearly described my problem.

Best regards
Pic1.png

  Re: I can’t build a new layer after I found out the scale through layout()
Posted by Peter Kwan on Oct-01-2023 14:38
Hi Alex,

Your strategy is to obtain the x-axis and y-axis scales first, then add the vectors.

To do this, you can use a 2-pass method. In the first pass, the chart is created with the scatter layer and then c.layoutAxes() is called. This chart is then stored in a variable to be used by the second chart. The first pass has minimal overhead as long as you do not display the chart.

The second chart is the same as the first chart, except layoutAxes is not called. Instead, Axis.syncAxis is used to synchronize its axes with those of the first chart. In this way, the axis scale of the second chart is the same as that of the first chart, and you can use the getXCoor/getYCoor of the first chart to get the coordinates to be used in the second chart.

Note that by default, ChartDirector will auto-scale the axis to best fit the scatter points. That means some points may be close to the plot area boundary. If the vectors are too long, they may overflow the plot area and may overlap with things outside the plot area (such as axis labels, chart title, legend box, etc).

There are methods to configure the auto-scaling to ensure the points are not too close to the boundary, but you still need to specify how much space are required. See:

https://www.advsofteng.com/doc/cdnet.htm#Axis.setMargin.htm
https://www.advsofteng.com/doc/cdnet.htm#Axis.setAutoScale.htm

Best Regards
Peter Kwan

  Re: I can’t build a new layer after I found out the scale through layout()
Posted by Alex on Oct-07-2023 13:47
Hi!

Peter, many thanks for the help!

Yes, your method works.

But I found another one.

I myself track the maximum values in my data. And because I know the dimensions of the diagram area, then I can calculate the “pixels per 1 kg” scale myself. Therefore, I was able to solve the problem in 1 pass. It's still working. But if I encounter the fact that my maximum values do not coincide with those automatically calculated by your program, then I will have to use a 2-pass tactic.

Thank you again for your help!