Recent

Author Topic: TAChart - adding series at runtime with random color  (Read 1500 times)

Nicole

  • Hero Member
  • *****
  • Posts: 1308
TAChart - adding series at runtime with random color
« on: February 14, 2024, 03:40:11 pm »
I want to draw a date / bar chart. All days (or perhaps weeks) shall be drawn.
The bars shall be added colored and maybe piled.

If shall look alike the second graphic here:
https://wiki.freepascal.org/TAChart_Tutorial:_BarSeries

What I want to:
Iterating a set of data and displaying a new group it in a NEW color at the same chart.

e.g. This process shall be done:

- we found a new type, great! Let us generate a new color for it, let's say this time the result is "blue"
I find the data for it, e.g.
1.1.2023   50,
22.4.2026 - 66,
....
we display blue bars for them at the dates when they occur.

The data pour in and there is a new sort of
- I want a new color for it, this color shall be generated by the software, let's say this time it is yellow
and so on

Case the data blue and the yellow data are at the same day, they shall be piled.
Have I understood the turtrial correctly that TAChart would do this as default?

in other words I need only these ideas for a code:
- generate a new bar chart series at runtime
- generate a new, random color for it, which evidently shall not bee to close to the existing ones
- how to clean up best





wp

  • Hero Member
  • *****
  • Posts: 13424
Re: TAChart - adding series at runtime with random color
« Reply #1 on: February 14, 2024, 06:26:14 pm »
Can't say that I understood everything. Let me put it in my words: Suppose I am selling some articles. There are several article types, and I want to plot how many of each article are sold per month. So, I create a table: "Month" in the first column, "Article 1" in the 2nd column containing how many articles of type 1 are sold in each month, then "Article 2" in the next column, etc - one column for each article, and each cell contains the count of articles sold in that specific month.

Similar to this:
MonthArticle 1Article 2Article 3
2023-15212040
2023-26263750
2023-34572120
2023-43851640
2023-550100
2023-664500
2023-769300
2023-86630101
2023-97210130
2023-106340285
2023-115480363
2023-125740381

Here, article 2 is no longer available after 2023-4. It still must be kept in the table with zero in the following cells. And article 3 is newly available in 2023-8; it cannot appear out of nothing, it must already be present in the months before that date with zero cells.

If you can reduce your application to this situation you can visualize it in a stacked bar chart: Each row is a data point, in the example we have 12 data points. Each column (after the date column) is a level in the stacked series, here we have 3 levels. Each level is a y value in the chart - we need 3 y values.

How to store the values? There are many ways to do it, let's put them into a TListChartSource which must be attached to the Source property of the bar series. At first we specify the number of y values: ListChartSource.YCount := 3 - this sets up a data point record with 1 x and 3 y values. Then call ListChartSource.AddXYList(x, [y1, y2, y3]) for the data of each month (you can add the month text as well):
Code: Pascal  [Select][+][-]
  1.   ListChartSource1.YCount := 3;
  2.   ListChartSource1.AddXYList(EncodeDate(2023, 1,1), [521, 204,   0], '2024-1');
  3.   ListChartSource1.AddXYList(EncodeDate(2023, 2,1), [626, 375,   0], '2024-2');
  4.   ListChartSource1.AddXYList(EncodeDate(2023, 3,1), [457, 212,   0], '2024-3');
  5.   ...
In order to assign individual colors to each y level you need a TChartStyles component which must be assigned to the Styles property of the series. Add a Style for each y level, in each style you can specify the brush for filling this part of the bar stack, and you can also assign a Text to be displayed in the legend. The following code creates a random color for each stack level:
Code: Pascal  [Select][+][-]
  1.   ChartStyles1.Styles.Clear;
  2.   for i := 1 to ListChartSource1.YCount do
  3.     with ChartStyles1.Add do
  4.     begin
  5.       Brush.Color := Random($FFFFFF);      // Create a random color
  6.       Pen.Color := Brush.Color;
  7.       Text := 'Article ' + IntToStr(i);
  8.     end;  
See attached project which contains additional comments.

When later a new article is added you must increment the source's YCount. Basically, a zero should be added to the existing y values in the square bracket of the AddXYList call, but TAChart is tolerant enough when YCount is expanded - the missing field is assumed to be a zero. Of course new data must be entered with the new YCount then.


Nicole

  • Hero Member
  • *****
  • Posts: 1308
Re: TAChart - adding series at runtime with random color
« Reply #2 on: February 14, 2024, 07:26:16 pm »
WOW, thank you so very much.

 

TinyPortal © 2005-2018