Sign in Join
Wiki copytemporary

TAChart Tutorial: BarSeries/ru: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11## Введение
22
33![](/wiki-images/b/b1/BarSeries_finished.png%E2%80%8E)
44
55Библиотека `TAChart` различные диаграммы в Lazarus. Но в отличии от других типов рядов, гистограммы (столбчатые диаграммы) кажутся более сложными, главным образом потому, что существует широкий спектр возможностей:
66
77- смежные столбцы
88- сложенные столбцы
99- сложенные столбцы, приведенных к 100%
1010- вертикальные столбцы
1111- горизонтальные столбцы
1212
1313В этом руководстве мы хотим показать вам принципы того, как создать диаграмму с несколькими рядами столбцов, расположенными смежно. [[TAChart Tutorial: Stacked BarSeries|follow-up tutorial]] научит вас, как сложить столбцы друг над другом.
1414
1515Помимо гистограмм в этом руководстве будет представлен [[TAChart documentation|TRandomChartSource]], который является стандартным инструментом для разработки диаграммы без необходимости компиляции приложения.
1616
1717Вам понадобятся некоторые базовые знания в Pascal и в Lazarus. Взгляните на [[TAChart Tutorial: Getting started]], чтобы изучить некоторые базовые навыки работы с `TAChart`, если эта библиотека новая для Вас. Мы также рекомендуем [[TAChart documentation]].
1818
1919## Подготовка
2020
2121### Настройка диаграммы
2222
2323Создайте новый проект, сохраните его.
2424
2525Добавьте компонент `TChart` из палитры компонентов Lazarus на `Form1`, смасштабируйте его, чтобы заполнить заданную область формы.
2626
2727### Данные для вывода
2828
2929Прежде чем продолжить, давайте подумаем о том, какие данные мы хотим вывести. Возможно, вы могли бы использовать баланс своих чековых и сберегательных счетов, или бизнес-отчеты крупных компаний, найденные где-нибудь в Интернете, или что-то совершенно другое...
3030
3131Давайте на этот раз пойдем другим путем: почему бы нам не построить график только случайных данных? Конечно, они ничего не значат, но они просты и очень удобны для того, чтобы потренироваться с компонентом. В частности, `TAChart` содержит компонент [[TAChart documentation|TRandomChartSource]] который предоставляет случайные данные, подключающиеся к диаграммам прямо во время разработки. Это означает, что вы можете следовать этому руководству без необходимости написания хотя бы одной строчки кода и без необходимости компилировать демонстрационное приложение. Позже, когда работа над макетом будет завершена, вы можете удалить источники случайных диаграмм и заменить их источниками диаграмм, содержащими наши данные.
3232
3333Как вы вскоре увидите, на графике будет три ряда, каждый из которых, к примеру, с четырьмя столбцами. Для каждой серии вам понадобится `RandomChartSource`. Чтобы добавить `RandomChartSource` вгляните на палитру компонентов "Диаграммы" - это третий значок на палитре, подсвеченный красным на скриншоте ниже:
3434
3535![](/wiki-images/4/4b/ComponentPalette_RandomChartSource.png)
3636
3737Добавьте в форму три источника случайных диаграмм - по одному на серию. Переименуйте в `RedChartSource`, `BlueChartSource` и `YellowChartSource` таким образом, что они будут связаны с красным "red", синим "blue" и желтым "yellow" сериями диаграмм, которые сразу будут созданы (Вы всегда должны использовать "говорящие" названия для переменных.)
3838
3939Прежде чем сделать это, нам нужно настроить источники случайных диаграмм, потому что по умолчанию они не предоставлят никаких данных. Мы хотим, чтобы в каждой серии было по четыре диаграммы. Поэтому установите свойство `PointsNumber` в значение 4. Чтобы метки осей синхронизировались со столбцами, ось `x` должна находиться в диапазоне от 1 до 4 ( или от 0 до 3, или от 0 до 39, как Вам угодно - мы обсудим метки осей более подробно позже): `XMin = 1, XMax = 4`. И, наконец, мы также должны указать диапазон осей `y`, можно выбрать `YMin = 0` и `YMax = 100`.
4040
4141## Ряды столбцов
4242
4343### Добавление рядов
4444
4545Теперь, когда все приготовления закончены, мы можем добавить ряд столбцов на диаграмму. Дважды щелкните по диаграмме, чтобы открыть редактор рядов (series). Нажмите "Добавить" и выберите "Ряд столбцов" из списка. Повторите дважды. В конце концов, у нас есть три ряда столбцов на графике. Мы не видим их на диаграмме, так как они еще не связаны с нашими данными. Однако в дереве объектов Инспектора объектов ряды отображаются как дочерние элементы узла диаграммы.
4646
4747Щелкните на первом ряду в дереве объектов и - в Инспекторе объектов - перейдите к свойству `Source` и выберите `RedChartSource` из списка. Теперь ряды становятся видимыми на диаграмме. Для того, чтобы сделать его красным "red" перейдите к его свойству `SeriesColor` и выберите цвет `clRed`. Переименуйте ряд в "RedBarSeries", и измените заголовок (title) на "красный". Последнее предназначено для легенды, которую мы включаем, устанавливая `Legend.Visible` в `true`.
4848
4949Повторите все это с двумя другими рядами аналогично.
5050
5151![](/wiki-images/2/28/AllBarSeries.png)
5252
5353Теперь на графике отображается ряд столбцов (гистограмма). Однако столбики расположены на одном и том же значении оси `X`, желтые столбики частично закрыты другими столбиками. Давайте исправим это.
5454
5555### Side-by-side arrangement of bars
5656
5757In 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:
5858
5959- `BarWidthPercent`
6060- `BarOffsetPercent`
6161
6262Both 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`.)
6363
6464The 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 bar can occupy a width of 25%.
6565
6666So, 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.
6767
6868Currently, `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.
6969
7070In summary, we use the following values:
7171
7272- `RedBarSeries: BarOffsetPercent = -25, BarWidthPercent = 25`
7373- `BlueBarSeries: BarOffsetPercent = 0, BarWidthPercent = 25`
7474- `YellowBarSeries: BarOffsetPercent = 25, BarWidthPercent = 25`
7575
7676![](/wiki-images/0/09/AllBarSeries-side-by-side.png)
7777
7878## Axis
7979
8080### Using text labels
8181
8282The next issue to be addressed is the `x` axis. Usually bar charts are considered to display categories of some data sets which often requires text labels underneath each bar group. But so far, we only have numerical labels, and the intermediate labels at half integers are particularly annoying.
8383
8484The best way to get this right is to use an additional ChartSource for assigning the strings to the axis values, it is a `TListChartSource` this time to be found as the second icon in the chart component palette (immediately to the left of the `TRandomChartSource`.) Add it to the form and rename is as `LabelsChartSource`.
8585
8686The ListChartSource has a built-in data editor which allows to enter data at design-time. Select the `LabelsChartSource` and go to the property `DataPoints`. Click on "..." at the right to open the data points editor, and enter the following data:
8787
8888![](/wiki-images/3/36/LabelsSource_DataPoints_Editor.png)
8989
9090In the "X" column we enter the values of the `x` coordinates of each bar group. We could omit the "Y" column, but as we'll see later that it is conventient to have the same data in this column as well because labels are retained after rotation of the bars to an horizontal arrangement. In the column "Text" we specify the texts that will appear for each bar group along the axis as axis marks. Let us assume that our data represent some seasonal values and use the abbreviations "Q1", "Q2", "Q3", and "Q4" for "quarter 1" etc. Column "Color" can be left empty.
9191
9292In order to activate these labels we have to assign this ChartSource to the `Source` property of the `Marks` of the bottom axis, and we have to set the property `Style` of the `Marks` to `smsLabel`.
9393
9494Voila - here's what we get:
9595
9696![](/wiki-images/a/a5/BarSeries_with_Axis_Marks.png%E2%80%8E)
9797
9898### Showing grid lines & ticks between groups
9999
100100A minor issue can be improved: the chart would be clearer if the axis tick marks and grid lines were not at the center of the bar groups, but right between them.
101101
102102At first, we turn off the grid of the bottom axis: `BottomAxis.Grid.Visible = false`. To remove the ticks, we can set the `TickLength` and the `TickInnerLength` to `0`.
103103
104104But how to add grid lines between the chart groups? This can be done by creating a "minor" axis to the bottom axis. This is another set of ticks and gridlines in addition to the "major" axis. Go to the bottom axis and click on `Minors` to open the corresponding editor. Click "Add" and the select the `0 - M` in the list. Back in the normal Object Inspector, activate `Visible`, increase the `TickLength` to 4, and finally, set `Intervals.Count` to `1` - we only want one minor tick between the major ticks. Check the `Grid` settings - `Visible` should be `true`.
105105
106106This leads to the final result. Final? Not quite! There is an annoying little gap underneath the bars. This originates from the chart's `Margins` property which leaves some distance between the series and the axes. Just set `Chart.Margins.Bottom` to `0` to remove the gap.
107107
108108![](/wiki-images/3/3a/BarSeries_no_bottom_margins.png)
109109
110110## Horizontal bar series
111111
112112Before closing this lesson we'd like to quickly modify this project and create a plot with horizontal bars. This kind of diagram is often preferred when the axis labels consist of lengthy texts, and the chart is in a landscape orientation.
113113
114114`TAChart` does not offer a dedicated "`THorizontalBarSeries`", but the standard `TBarSeries` can easily be modified to obtain horizontal bars. Like any other descendant of `TChartSeries` it has properties `AxisIndexX` and `AxisIndexY` to indicate which axis is responsible for `x` and `y` coordinates. Just set `AxisIndexX` to the index of the `LeftAxis` (usually `0`) and `AxisIndexY` to that of the `BottomAxis` in order to rotate the bar direction.
115115
116116And, of course, the `LabelsChartSource` has to be linked to the `Marks.Source` of the `LeftAxis` this time. And the minor axis has to be handled accordingly.
117117
118118Essentially, that's all that's needed to create a chart with horizontal bars.
119119
120120![](/wiki-images/9/9b/Horizontal_BarSeries.png%E2%80%8E)
121121
122122## Summary
123123
124124Steps to create a side-by-side bar chart:
125125
126126- Every bar requires a separate BarSeries.
127127- Use the BarSeries' properties `BarWidthPercent` and `BarOffsetPercent` to arrange the bars side-by-side with or without overlapping. The percentages refer to the distance between the center of the bar groups.
128128- For horizontal bar series, set the series' `AxisIndexX` to the index of the chart's `LeftAxis` (usually `0`) and `AxisIndexY` to the index of the `BottomAxis` (usually `1`).
129129
130130## Source code
131131
132132The source code of this tutorial is available in the folder `components/tachart/tutorials/bar_series` of your TAChart installation of newer Lazarus versions.
133133
134134### Project file
135135
136136``` pascal
137137program project1;
138138
139139{$mode objfpc}{$H+}
140140
141141uses
142142 {$IFDEF UNIX}{$IFDEF UseCThreads}
143143 cthreads,
144144 {$ENDIF}{$ENDIF}
145145 Interfaces, // this includes the LCL widgetset
146146 Forms, tachartlazaruspkg, Unit1
147147 { you can add units after this };
148148
149149{$R *.res}
150150
151151begin
152152 RequireDerivedFormResource := True;
153153 Application.Initialize;
154154 Application.CreateForm(TForm1, Form1);
155155 Application.Run;
156156end.
157157```
158158
159159### Unit1.pas
160160
161161``` pascal
162162unit Unit1;
163163
164164{$mode objfpc}{$H+}
165165
166166interface
167167
168168uses
169169 Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, TAGraph,
170170 TASeries, TASources;
171171
172172type
173173
174174 { TForm1 }
175175
176176 TForm1 = class(TForm)
177177 Chart1: TChart;
178178 LabelsChartSource: TListChartSource;
179179 RedBarSeries: TBarSeries;
180180 BlueBarSeries: TBarSeries;
181181 YellowBarSeries: TBarSeries;
182182 RedChartSource: TRandomChartSource;
183183 BlueChartSource: TRandomChartSource;
184184 YellowChartSource: TRandomChartSource;
185185 private
186186 { private declarations }
187187 public
188188 { public declarations }
189189 end;
190190
191191var
192192 Form1: TForm1;
193193
194194implementation
195195
196196{$R *.lfm}
197197
198198end.
199199```
200200
201201### Unit1.lfm (vertical bars)
202202
203-``` pascal
203+``` lfm
204204object Form1: TForm1
205205 Left = 381
206206 Height = 272
207207 Top = 444
208208 Width = 429
209209 Caption = 'Form1'
210210 ClientHeight = 272
211211 ClientWidth = 429
212212 LCLVersion = '1.3'
213213 object Chart1: TChart
214214 Left = 0
215215 Height = 272
216216 Top = 0
217217 Width = 384
218218 AxisList = <
219219 item
220220 Minors = <>
221221 Title.LabelFont.Orientation = 900
222222 end
223223 item
224224 Grid.Visible = False
225225 TickLength = 0
226226 Alignment = calBottom
227227 Marks.Format = '%2:s'
228228 Marks.Source = LabelsChartSource
229229 Marks.Style = smsLabel
230230 Minors = <
231231 item
232232 Intervals.Count = 1
233233 Intervals.MinLength = 5
234234 Intervals.Options = [aipUseCount, aipUseMinLength]
235235 TickLength = 4
236236 end>
237237 end>
238238 Foot.Brush.Color = clBtnFace
239239 Foot.Font.Color = clBlue
240240 Legend.Visible = True
241241 Margins.Bottom = 0
242242 Title.Brush.Color = clBtnFace
243243 Title.Font.Color = clBlue
244244 Title.Text.Strings = (
245245 'TAChart'
246246 )
247247 ParentColor = False
248248 object RedBarSeries: TBarSeries
249249 Title = 'red'
250250 BarBrush.Color = clRed
251251 BarOffsetPercent = -25
252252 BarWidthPercent = 25
253253 Source = RedChartSource
254254 end
255255 object BlueBarSeries: TBarSeries
256256 Title = 'blue'
257257 BarBrush.Color = clBlue
258258 BarWidthPercent = 25
259259 Source = BlueChartSource
260260 end
261261 object YellowBarSeries: TBarSeries
262262 Title = 'yellow'
263263 BarBrush.Color = clYellow
264264 BarOffsetPercent = 25
265265 BarWidthPercent = 25
266266 Source = YellowChartSource
267267 end
268268 end
269269 object RedChartSource: TRandomChartSource
270270 PointsNumber = 4
271271 RandSeed = 1
272272 XMax = 4
273273 XMin = 1
274274 YMax = 100
275275 YMin = 0
276276 left = 360
277277 top = 72
278278 end
279279 object BlueChartSource: TRandomChartSource
280280 PointsNumber = 4
281281 RandSeed = 2
282282 XMax = 4
283283 XMin = 1
284284 YMax = 100
285285 YMin = 0
286286 left = 360
287287 top = 120
288288 end
289289 object YellowChartSource: TRandomChartSource
290290 PointsNumber = 4
291291 RandSeed = 3
292292 XMax = 4
293293 XMin = 1
294294 YMax = 100
295295 YMin = 0
296296 left = 360
297297 top = 168
298298 end
299299 object LabelsChartSource: TListChartSource
300300 DataPoints.Strings = (
301301 '1|1|?|Q1'
302302 '2|2|?|Q2'
303303 '3|3|?|Q3'
304304 '4|4|?|Q4'
305305 )
306306 left = 361
307307 top = 220
308308 end
309309end
310310```
311311
312312### Unit1.lfm (horizontal bars)
313313
314-``` pascal
314+``` lfm
315315object Form1: TForm1
316316 Left = 381
317317 Height = 272
318318 Top = 444
319319 Width = 429
320320 Caption = 'Form1'
321321 ClientHeight = 272
322322 ClientWidth = 429
323323 LCLVersion = '1.3'
324324 object Chart1: TChart
325325 Left = 0
326326 Height = 272
327327 Top = 0
328328 Width = 384
329329 AxisList = <
330330 item
331331 Grid.Visible = False
332332 TickLength = 0
333333 Marks.Format = '%2:s'
334334 Marks.Source = LabelsChartSource
335335 Marks.Style = smsLabel
336336 Minors = <
337337 item
338338 Intervals.Count = 1
339339 Intervals.MinLength = 5
340340 Intervals.Options = [aipUseCount, aipUseMinLength]
341341 TickLength = 4
342342 end>
343343 Title.LabelFont.Orientation = 900
344344 end
345345 item
346346 Alignment = calBottom
347347 Minors = <>
348348 end>
349349 Foot.Brush.Color = clBtnFace
350350 Foot.Font.Color = clBlue
351351 Legend.Visible = True
352352 Margins.Bottom = 0
353353 Title.Brush.Color = clBtnFace
354354 Title.Font.Color = clBlue
355355 Title.Text.Strings = (
356356 'TAChart'
357357 )
358358 ParentColor = False
359359 object RedBarSeries: TBarSeries
360360 Title = 'red'
361361 AxisIndexX = 0
362362 AxisIndexY = 1
363363 BarBrush.Color = clRed
364364 BarOffsetPercent = -25
365365 BarWidthPercent = 25
366366 Source = RedChartSource
367367 end
368368 object BlueBarSeries: TBarSeries
369369 Title = 'blue'
370370 AxisIndexX = 0
371371 AxisIndexY = 1
372372 BarBrush.Color = clBlue
373373 BarWidthPercent = 25
374374 Source = BlueChartSource
375375 end
376376 object YellowBarSeries: TBarSeries
377377 Title = 'yellow'
378378 AxisIndexX = 0
379379 AxisIndexY = 1
380380 BarBrush.Color = clYellow
381381 BarOffsetPercent = 25
382382 BarWidthPercent = 25
383383 Source = YellowChartSource
384384 end
385385 end
386386 object RedChartSource: TRandomChartSource
387387 PointsNumber = 4
388388 RandSeed = 1
389389 XMax = 4
390390 XMin = 1
391391 YMax = 100
392392 YMin = 0
393393 left = 360
394394 top = 72
395395 end
396396 object BlueChartSource: TRandomChartSource
397397 PointsNumber = 4
398398 RandSeed = 2
399399 XMax = 4
400400 XMin = 1
401401 YMax = 100
402402 YMin = 0
403403 left = 360
404404 top = 120
405405 end
406406 object YellowChartSource: TRandomChartSource
407407 PointsNumber = 4
408408 RandSeed = 3
409409 XMax = 4
410410 XMin = 1
411411 YMax = 100
412412 YMin = 0
413413 left = 360
414414 top = 168
415415 end
416416 object LabelsChartSource: TListChartSource
417417 DataPoints.Strings = (
418418 '1|1|?|Q1'
419419 '2|2|?|Q2'
420420 '3|3|?|Q3'
421421 '4|4|?|Q4'
422422 )
423423 left = 361
424424 top = 220
425425 end
426426end
427427```
428428
429429---
430430*From the Free Pascal wiki, page "TAChart Tutorial: BarSeries/ru", as it stood on 2021-09-26 after a change by Almuhandis, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history