TAChart Tutorial: BarSeries

From Lazarus wiki
Jump to navigationJump to search

--- WORK IN PROGRESS ---

--- NOT FINISHED ---

Introduction

The TAChart library can create a variety of charts in Lazarus. But in comparison with other series types, bar series appear to be more difficult, mostly because there is a wide range of possibilities: side-by-side bar series, stacked bar series, stacked bar series normalized to 100%, vertical bar series, horizontal bar series.

In this tutorial we want to show you the basic idea of how to create a chart with several bar series arranged in a side-by-side manner. A follow-up tutoral will teach you how to stack bars above each other.

You'll need some basic knowledge of Pascal and Lazarus. Have a look at the TAChart Tutorial: Getting started to learn some basic skills for working with TAChart if that library is new to you.

Preparation

Setting up the chart

Create a new project, save it. Add a TChart component from Lazarus' component palette to Form1, client-align it to fill the entire form.

Data for plotting

Before continuing let's think about which data we want to plot. Maybe you could use the balance of your checking and saving accounts, or the business results of large companies found somewhere in the internet, or something completely different...

Let's go a different way this time: why don't we plot just random data? Of course, they don't mean anything, but they are simple and a great tool for exercising. And in particular, TAChart contains the TRandomChartSource component which provides random data to be plugged into a series seamlessly at design-time. This means you can follow this tutorial without a need to write a line of code and without a need to compile the demo application.

As you will see shortly, there will be three series in the chart, each of them with - say - four bars. For each series, you'll need a RandomChartSource. To add a RandomChartSource have a look at the "Chart" component palette - it is the third icon in the palette highlighted by red in the screenshot below:

ComponentPalette RandomChartSource.png

Add three RandomChartSources to the form - one per series. Rename them as RedChartSource, BlueChartSource, and YellowChartSource since they will be linked to a "red", "blue" and "yellow" bar series to be created immediately (you should always prefer to use "speaking" variable names.)

Before doing so, we need to set up the RandomChartSources because they do not provide any data by default. We want to have four bars per series. Therefore, set the property PointsNumber to 4. In order to get the axis labels in sync with the bars the x axis must range between 1 and 4 (or between 0 and 3, or between 0 and 39, whatever you like - we'll come across axis labels later in more details). And finally we also have to specify the y axis range, maybe select YMin = 0 and YMay = 100.

Bar series

Adding series

Now that all preprations are done we can add the bar series to the chart. Double-click on the chart to open the series editor. Click "Add" and select "Bar series" from the list. Repeat twice. In the end, we have three bar series in the chart. We don't see them in the chart since they are not yet linked to our data. In the object tree of the Object Inspector, however, the series appear as children of the Chart node.

Click at the first series in the object tree, and - in the Object Inspector - go to the property Source and pick RedChartSource from the list. Now the series becomes visible in the chart. To make it "red" go to its property SeriesColor and select the color clRed. Rename the series to "RedBarSeries", and change its title to "red". The latter is for the legend which we turned on by setting the chart's Legend.Visible to true.

Repeat with the other two series correspondingly.

AllBarSeries.png

Now the chart displays the bar series. However, the bars are located at the same value of the x axis, the yellow bars are partly covered by the red bars. Let's fix this.

Side-by-side arrangement of bars

In oder to arrange the bars of each group (i.e. bars corresponding to the same x value) side-by-side, we have to shift them horizontally. TBarSeries offers two properties for this purpose:

  • BarWidthPercent
  • BarOffsetPercent

Both numbers are expressed as a percentage of the distance to the next bar group. (In some charts, the bars are not equidistant and therefore get varying bar widths. To achieve a constant bar thickness in such a case, set the property BarWidthStyle to bwPercentMin.)

The basic idea is that the space between the bar groups (100%) is divided by the bars and some empty space to the next group. If we want to leave a gap of - say - one bar width between the groups, we have to divide 100% by 4 (3 bars plus gap), i.e. each series can occupy a width of 25%.

So, let's set the BarWidthPercent to 25% and see what happens. Oh - not quite what we wanted: The bars did get narrower, but they are still overlapping. Of course, this happens because we did not change the BarOffsetPercent parameter.

Currently, BarOffsetPercent is zero which means that the center of each bar is exactly at the position of the axis tick mark. We have to shift the red bars to the left and the yellow bars to the right such that they touch the blue bars which remain in the center. The shift difference is one bar width, i.e. 25%. For moving the red bars to the left their BarOffsetPercent has to be negative.

In summary, we use the following values:

  • RedBarSeries: BarOffsetPercent = -25, BarWidthPercent = 25
  • BlueBarSeries: BarOffsetPercent = 0, BarWidthPercent = 25
  • YellowBarSeries: BarOffsetPercent = 25, BarWidthPercent = 25

Axis

Use text label

Show grid & ticks between groups


AllBarSeries-WidthVarying.png

Now reset the BarWidthPercents to - say - 50 for all series - the bar widths shrink and leave a gap of the same width to the next group. Let's have a look at BarOffsetPercent. In the first test, use a value of 10 for series. The chart does not change much, still the bars are fully overlapping, there is a little change on the axis, though. What is happening is that the offset is applied to all series which shifts all series by the same amount.

Now let's try different offset: the red bar will be offset by 0, the blue bars by 10, and the yellow bars by 20.

Sometimes the bars


-- Axis labels -- In the chart, you can now see all three series, the layout is not perfect because the series are overlapping - we'll address this issue below.

For the moment, let us look at the x axis of the chart: It shows values ranging between 0 and 10, but the labels do not match the position of the bars. And quite often, text labels are used, like "Quarter 1", "Quarter 2" etc., instead of the numerical labels shown here.

To fix this we add a TListChartSource to the form. Its sole purpose is to provide the correspond to the bars. but their bars are at the same x position, i.e. directly behind each other. The right-most red bar even hides the other bars of that data point. What we need is a shift of the bars.