Можно сказать, что данная статья является продолжением статьи про закрашивание ячеек в TStringGrid. Конечно мы в данной статье будем говорить не совсем о закрашивании ячеек, но связь с этим есть. В данной статье, я хотел бы поговорить, как можно построить разноцветный график с помощью стандартного компонента TChart. В свое время, я делал курсовой проект, который предназначен для анализа ассортимента методом XYZ. Другими словами, товар поставщиков необходимо было рассортировать по группам X, Y или Z. В зависимости от качества и расчета определенных параметров необходимо было сделать рассортировку по этим группам. Все данные и расчеты я отображал в TStringGrid. Для того, чтобы пользователю было понятно какие данные попадают в какие группы, я сделал пометку, что красный цвет — группа X, например, желтый — группа Y, зеленый — группа Z. После этого, как и в прошлой статье, я закрашивал ячейки в определенный цвет, которые удовлетворяют условию группам. Все данные я отсортировал в порядке возрастания и получилось так, после того, как я раскрасил группы, что вначале идет группа X, потом Y, затем Z, а не в разнобой все группы были в TStringGrid. На основе этого мне было легко построить график, который отображал все значения этих групп нужным цветом.
Ниже я привожу скриншот, как выглядели мои данные в TStringGrid.
Для того, чтобы получить что-то похожее, нам вначале необходимо будет отсортировать наши данные. На форме у меня следующие компоненты
- TStringGrid
- TChart
- TButton — 2 шт
- TCheckBox — 2 шт
TStringGrid я настроил следующим образом, в свойствах я указал:
- FixedCols — 0
- FixedRows — 0
- Options-goEditing — True
- Rowcount — 1
Теперь немного настроим TChart, необходимо для начала нам выбрать тип графика. Нажимаем двойным щелчком мыши по компоненту TChart и переходим во вкладку Series и в данной вкладке нажимаем на кнопку Add. После чего появится список всех доступных графиков, в нашем случае я выбрал самый первый тип графика (линейный) — Line. Если хотите сделать какие-то другие настройки, то пожалуйста, на остальных вкладках это можно сделать.
После того, как мы настроили наши 2 компонента, нам теперь необходимо придумать условие, по которому будут закрашиваться наши ячейки и строиться график. Как я уже говорил в программе XYZ, я делал определенные расчеты и относил их в нужные группы, перед этим сперва сортировал их. Пусть, значения от 1 до 10 закрашиваются в красный, от 11 до 20 в желтый цвет, а от 21 до бесконечности в зеленый цвет. Теперь, как и в прошлой статье, мы напишем условие, по которому будем закрашивать ячейки. На событие OnDrawCell напишем следующий код:
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
if StringGrid1.Cells[ACol,ARow]<>'' then
begin
if (StrToInt(StringGrid1.Cells[ACol,ARow])>=1) and
(StrToInt(StringGrid1.Cells[ACol,ARow])<=10) then
begin
StringGrid1.Canvas.Brush.Color:=clRed;
StringGrid1.Canvas.FillRect(Rect);
StringGrid1.Canvas.TextOut(Rect.Left,Rect.Top,StringGrid1.Cells[ACol,ARow]);
end;
if (StrToInt(StringGrid1.Cells[ACol,ARow])>=11) and
(StrToInt(StringGrid1.Cells[ACol,ARow])<=21) then
begin
StringGrid1.Canvas.Brush.Color:=clYellow;
StringGrid1.Canvas.FillRect(Rect);
StringGrid1.Canvas.TextOut(Rect.Left,Rect.Top,StringGrid1.Cells[ACol,ARow]);
end;
if (StrToInt(StringGrid1.Cells[ACol,ARow])>21) then
begin
StringGrid1.Canvas.Brush.Color:=clGreen;
StringGrid1.Canvas.FillRect(Rect);
StringGrid1.Canvas.TextOut(Rect.Left,Rect.Top,StringGrid1.Cells[ACol,ARow]);
end;
end;
end;
Мы уже разбирали данный код, как происходит закрашивание, поэтому тут останавливаться не будем. После того как у нас сформировано условие, по которому мы закрашиваем ячейки в определенный цвет, теперь как я и говорил, нам необходимо все эти данные отсортировать. Возьмем самый простой способ сортировки — минимальным элементом. Вот так мы отсортируем данные в TStringGrid по возрастанию:
for i:=0 to StringGrid1.ColCount-1 do
begin
min:=StrToInt(StringGrid1.Cells[i,0]);
for j:=i+1 to StringGrid1.ColCount-1 do
begin
if StrToInt(StringGrid1.Cells[j,0])<min then
begin
b:=StrToInt(StringGrid1.Cells[j,0]);
StringGrid1.Cells[j,0]:=IntToStr(min);
StringGrid1.Cells[i,0]:=IntToStr(b);
min:=b;
end;
end;
end;
Все переменные, что используются в данном коде имеют тип integer
Данные у нас готовы, отсортированы, теперь нам необходимо просто-напросто построить по тем же данным график и на определенных промежутках закрасить график, удовлетворяющий определенному условию, в нужный нам цвет. Для этого мы организуем цикл, и в данном цикле мы также будем проверять наше условие, и устанавливать цвет графику, в итоге у меня получилось что-то похожее, весь код с сортировкой:
procedure TForm1.Button1Click(Sender: TObject);
var
i,j,min,b,x,y:integer;
begin
try
for i:=0 to StringGrid1.ColCount-1 do
begin
min:=StrToInt(StringGrid1.Cells[i,0]);
for j:=i+1 to StringGrid1.ColCount-1 do
begin
if StrToInt(StringGrid1.Cells[j,0])<min then
begin
b:=StrToInt(StringGrid1.Cells[j,0]);
StringGrid1.Cells[j,0]:=IntToStr(min);
StringGrid1.Cells[i,0]:=IntToStr(b);
min:=b;
end;
end;
end;
for i:=0 to StringGrid1.ColCount-1 do
begin
x:=i;
y:=StrToInt(StringGrid1.Cells[i,0]);
if (StrToInt(StringGrid1.Cells[i,0])>=1) and
(StrToInt(StringGrid1.Cells[i,0])<=10) then
Chart1.Series[0].AddXY(x,y,'',clRed);
if (StrToInt(StringGrid1.Cells[i,0])>=11) and
(StrToInt(StringGrid1.Cells[i,0])<=21) then
Chart1.Series[0].AddXY(x,y,'',clYellow);
if (StrToInt(StringGrid1.Cells[i,0])>21) then
Chart1.Series[0].AddXY(x,y,'',clGreen);
end;
except
on e:Exception do
ShowMessage(e.Message);
end;
end;
Тут можно было обойтись и без таких условий, а организовать нужные нам циклы. Вот весь код, который сперва сортирует данные, а затем по ним строит график.
Ну и в концовке, сделаем небольше настройки для TChart, для этого мы и устанавливали на форму TCheckBox. Один TCheckBox будет отвечать за 3D-график, а второй за наличие нашей легенды. Вот код, который отвечает за 3D-график:
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
Chart1.View3D:=CheckBox1.Checked;
end;
А вот код, который отвечает за наличие легенды
procedure TForm1.CheckBox2Click(Sender: TObject);
begin
Chart1.Legend.Visible:=CheckBox2.Checked;
end;
Ну и в концовке скриншот, который у меня получился в курсовом проекте, при построении графика, что-то похожее и у нас получилось