View Issue Details

IDProjectCategoryView StatusLast Update
0035535LazarusTAChartpublic2020-08-08 19:35
Reporterwp Assigned Towp  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Summary0035535: Axis labels for rotated series
DescriptionIn TAChart, series get their data points from so-called chart sources and via TChartDataItem records which contain the x,y values of data points as well as some text for data point labels. When the chart source is assigned to the Marks.Source property of an axis then the axis can be labeled with these data point labels as well.

This works fine for the basic configuration of a horizontal axis. By interchanging the series properties AxisIndexX and AxisIndexY, however, the presentation can be rotated, i.e. x values are plotted along the vertical, y values along the horizontal axis.

In this case the assignment of the data point labels to the axis often does not work any more. The reason is that the axis not knowing anything about the series plotted along it uses the y value of the data point to position the label, but the series has exchanged x and y and plots the data point with its x value on the y axis.

An adapter chart source is required to adjust the chart source with the data to the axis. This can be achieved by a TUserDefinedChartSource which reads the data point source and passes the x/y values in reverse order (as y/x) to the series.

In total this procedure is rather complicated and should be simplified.
Steps To ReproduceRun attched demo; it shows as stacked bar series with x values 1, 2, 3, ...; the associated y values can be changed by the radiobuttons accordingly. The bars are labeled via their data point records as "A", "B", ... along the horizontal axis.

Click on the checkbox "Rotated" - the bars are rotated by 90°, i.e. x runs vertically, y horizontally. The axis labels are correct in the case "y = 1,2,3...", i.e. when x = y. When switching to y = '2, 4, 6..." or "y = 10, 20, 30...", however, some or all labels are missing - this is because scaling of the y axis is determined by the data plotted along it. Since in the rotated case the original x values are drawn on the y axis, the y axis range is 1..4; but the labels are drawn according to the y value in the data point record, i.e. at y=2, 4, 6 or 10, 20, 30, respectively - this does not match.

When "use adapter source" is checked the labels are not connected directly to the axis but via a userdefined chart source which exchanges x and y. In this case the rotated axes are always labeled correctly.
TagsNo tags attached.
Fixed in Revisionr63677
LazTarget2.2
Widgetset
Attached Files

Activities

wp

2019-05-07 16:30

developer  

Marcin Wiazowski

2019-05-07 21:42

reporter   ~0116069

For documentation purposes: the problem described here was already discussed a bit in notes 0035356:0116030 and 0035356:0116060.

Marcin Wiazowski

2019-05-07 22:14

reporter   ~0116071

Ok.



I also think, that using an "exchange X-Y" feature - as proposed in 0035356:0116030 - would be an overkill.

What's more, I think, that using an intermediate source - like TCalculatedChartSource or TUserDefinedChartSource - is also an overkill.



My (not very surprising) observation is: although the discussed "exchange X-Y" feature is useful for rotated series, the axis does not know anything about the series; it has only some source assigned to Marks.Source, and it doesn't know, if this source is also assigned to some series, or not.

So the problem should be solved either in source's code, or in axis' code. Since the problem is specific to axis functionality (which may be horizontal or vertical), and not to any specific source - I think that the problem should be solved in the axis' code.



Now some experiment: in TChartAxis.MakeValuesInRangeParams(), change:

  Result.FUseY := IsVertical;

to:

  Result.FUseY := false;

and start the attached LabelsOnRotatedAxis demo - the problem is solved.



So I think that the right solution would be to add a property like SourceExchangeXY: Boolean to TChartAxisMarks. In this case, in TChartAxis.MakeValuesInRangeParams(), we could have:

  Result.FUseY := IsVertical xor Marks.SourceExchangeXY;

wp

2020-08-03 14:07

reporter   ~0124527

Picked up your idea. Resolving.

Issue History

Date Modified Username Field Change
2019-05-07 16:26 wp New Issue
2019-05-07 16:27 wp Assigned To => wp
2019-05-07 16:27 wp Status new => assigned
2019-05-07 16:27 wp File Added: LabelsOnRotatedAxis.zip
2019-05-07 16:28 wp Reproducibility have not tried => always
2019-05-07 16:28 wp LazTarget => -
2019-05-07 16:30 wp File Deleted: LabelsOnRotatedAxis.zip
2019-05-07 16:30 wp File Added: LabelsOnRotatedAxis.zip
2019-05-07 16:31 wp Steps to Reproduce Updated View Revisions
2019-05-07 21:42 Marcin Wiazowski Note Added: 0116069
2019-05-07 22:14 Marcin Wiazowski Note Added: 0116071
2020-08-03 14:07 wp Note Added: 0124527
2020-08-03 14:08 wp Status assigned => resolved
2020-08-03 14:08 wp Resolution open => fixed
2020-08-03 14:08 wp Fixed in Revision => r63677
2020-08-03 14:08 wp LazTarget - => 2.2
2020-08-08 19:35 wp Status resolved => closed