Форум программистов, компьютерный форум, киберфорум
Наши страницы
Lazarus
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/7: Рейтинг темы: голосов - 7, средняя оценка - 5.00
shyub
344 / 144 / 39
Регистрация: 11.07.2013
Сообщений: 791
1

Как построить прерывестый график c использованием TChart?

08.07.2015, 21:41. Просмотров 1287. Ответов 5
Метки нет (Все метки)

Уважаемые форумчане, здравствуйте!
Вопрос, на мой взгляд, интересный и, простите, не для новичков.
Необходимо на графике отображать во времени уровень, допустим, воды в водонапорной башне. При снижении уровня насос включается, а при достижении максимума - выключается. Здесь всё понятно (в прилагаемом коде это "Показать график"). Теперь, допустим, какое-то время не было электроэнергии, т.е линия графика должна прерваться, а затем вновь начаться (в прилагаемом коде это "Прерывестый график"). (Для эксперемента я пытался изменить цвет с clLime на ClRed. "Изменить параметр линии графика". Это, конечно абсолютная "туфта")
На подобный вопрос я как-то отвечал на форуме и предложил после прерывания линии использовать новую, допустим, вместо Chart1LineSeries4 использовать Chart1LineSeries5. В принципе, здесь можно так же динамически создать новую TChart1LineSeries, но это будет как-то "коряво".
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Координата X, число заменить на строку.
procedure TForm1.Chart1AxisList1MarkToText(var AText: String; AMark: Double);
begin
  DateTimeToString(AText,'t',AMark);
end;
// Показать график
procedure TForm1.Button1Click(Sender: TObject);
var
  i : Integer;
  m: double;
  f: double;
  s: string;
  flag: boolean;
begin
  m:=0;
  flag:=true;
  //f:=EncodeTime(0,1,0,0)-EncodeTime(0,0,0,0); // Интервал 1 минутa (чтобы узнать и закоментировать).
  f:=0;
  // Очистить.
  Chart1.Extent.UseXMax:=false;
  Chart1.Extent.UseXMin:=false;
  Chart1LineSeries1.Clear;
  Chart1LineSeries2.Clear;
  Chart1LineSeries3.Clear;
  // Размер и цвет.
  Chart1LineSeries1.LinePen.Color:=ClBlue;
  Chart1LineSeries1.LinePen.Width:=2;
  Chart1LineSeries2.LinePen.Color:=ClRed;
  Chart1LineSeries2.LinePen.Width:=2;
  Chart1LineSeries3.LinePen.Color:=clGreen;;
  Chart1LineSeries3.LinePen.Width:=2;
  // Вывод графика.
  for i := 1 to 30 do begin
    DateTimeToString(s,'t',f);
    Chart1LineSeries1.AddXY(StrToTime(s), m, '', clRed);
    Chart1LineSeries2.AddXY(StrToTime(s), 60, '', clRed);
    Chart1LineSeries3.AddXY(StrToTime(s), 10);
    f:=f+0.00069444444444444447; // Плюс минута (как вариант - добавление константы).
    if flag then begin
      m:=m+17;
      if m>100 then begin
        m:=100;
        flag:=false;
      end;
    end else begin
      m:=m-12.3;
      if m<0 then begin
        m:=0;
        flag:=true;
      end;
    end;
  end;
end;
// Прерывестый график.
procedure TForm1.Button3Click(Sender: TObject);
var
  i : Integer;
  m: double;
  f: double;
  s: string;
  flag: boolean;
begin
  m:=0;
  f:=0;
  flag:=true;
  // Очистить.
  Chart1.Extent.UseXMax:=false;
  Chart1.Extent.UseXMin:=false;
  Chart1LineSeries4.Clear;
  // Размер и цвет.
  Chart1LineSeries4.LinePen.Color:=clLime;
  Chart1LineSeries4.LinePen.Width:=2;
  // Вывод графика.
  for i := 1 to 30 do begin
    DateTimeToString(s,'t',f);
    Chart1LineSeries4.AddXY(StrToTime(s), m);
    f:=f+0.00069444444444444447; // Плюс минута.
    //***************************************
    // Изменить параметр линии графика.
    if ((i>10)and(i<20)) then begin
      Chart1LineSeries4.LinePen.Color:=ClRed;
    end else begin
      Chart1LineSeries4.LinePen.Color:=clLime;
    end;
    //***************************************
    if flag then begin
      m:=m+10;
      if m>=100 then begin
        m:=100;
        flag:=false;
      end;
    end else begin
      m:=m-10;
      if m<=0 then begin
        m:=0;
        flag:=true;
      end;
    end;
  end;
end;
// Очистить.
procedure TForm1.Button2Click(Sender: TObject);
begin
  Chart1LineSeries1.Clear;
  Chart1LineSeries2.Clear;
  Chart1LineSeries3.Clear;
  Chart1.Extent.XMax:=30;
  Chart1.Extent.XMin:=0;
  Chart1.Extent.UseXMax:=true;
  Chart1.Extent.UseXMin:=true;
end;
Вопрос: как начертить график, в котором на каком-то промежутке линия отсутствует (или меняет свой цвет, толщину - не важно), а далее продолжается (с первоначально заданными свойствами: толщина, цвет)? Вариант с динамическим созданием новой линии не рассматривается - как-то "не красиво это", хотелось бы получить такой эффект, используя возможности самого TChart.
Вот исходник Grafik_Time.rar
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.07.2015, 21:41
Ответы с готовыми решениями:

C использованием TChart построить график функции
C использованием TChart построить график у=ctg(x)/sin(3x)

Построить график TChart
Ребят, в зипе архив с программой. В ней нужно сделать для каждого значения А...

Построить график заданной функции с помощью компонента TChart
Создать в среде Lazarus проект, позволяющий строить график функции с помощью...

Не рисует график по точкам в TChart
В свойствах LineSeries1 выставлен цвет синий, ShowPoint - true, for i:=0 to...

Как построить график от 3-х переменных
Доброго всем время суток!!! Может кто подскажет как построить график...

5
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
26149 / 17526 / 6950
Регистрация: 22.10.2011
Сообщений: 30,864
Записей в блоге: 6
09.07.2015, 10:51 2
Рисуй поточечно, задавая цвет каждой точки, а не линиями.

P.S. Вот этот ужас: 0.00069444444444444447 можно заменить на более приятное глазу: 1 / MinsPerDay
2
shyub
344 / 144 / 39
Регистрация: 11.07.2013
Сообщений: 791
09.07.2015, 14:21  [ТС] 3
Спасибо, про
Цитата Сообщение от volvo Посмотреть сообщение
1 / MinsPerDay
не знал.
Попытался воспользоваться Вашим советом - не получается. Не моглм бы Вы показать пример с апроксимацией точек, но только на интервалах, где нет разрыва графика.
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
26149 / 17526 / 6950
Регистрация: 22.10.2011
Сообщений: 30,864
Записей в блоге: 6
09.07.2015, 14:32 4
Не надо никакой аппроксимации, просто для серии выставляется:
ShowPoints = true
LineType = ltNone
, и добавляются точки нужного цвета:
Pascal
1
Chart1LineSeries4.AddXY(StrToTime(s), m, '', currColor);
не с интервалом в минуту, а с интервалом, например, в 15 секунд...
0
shyub
344 / 144 / 39
Регистрация: 11.07.2013
Сообщений: 791
09.07.2015, 14:41  [ТС] 5
Пока нашел вот такое решение:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// Прерывестый график.
procedure TForm1.Button3Click(Sender: TObject);
var
  i : Integer;
  m: double;
  f: double;
  s: string;
  flag: boolean;
begin
  m:=0;
  flag:=true;
  f:=0;
  // Очистить.
  Chart1.Extent.UseXMax:=false;
  Chart1.Extent.UseXMin:=false;
  Chart1LineSeries1.Clear;
  Chart1LineSeries2.Clear;
  Chart1LineSeries3.Clear;
  // Размер и цвет.
  Chart1LineSeries1.LinePen.Color:=ClBlue;
  Chart1LineSeries1.LinePen.Width:=2;
  Chart1LineSeries2.LinePen.Color:=ClRed;
  Chart1LineSeries2.LinePen.Width:=2;
  Chart1LineSeries3.LinePen.Color:=clGreen;;
  Chart1LineSeries3.LinePen.Width:=2;
  // Вывод графика.
  for i := 1 to 30 do begin
    DateTimeToString(s,'t',f);
    if ((i>10)and(i<20)) then Chart1LineSeries1.AddXY(StrToTime(s), -1000000)
    else Chart1LineSeries1.AddXY(StrToTime(s), m);
    Chart1LineSeries2.AddXY(StrToTime(s), 60);
    Chart1LineSeries3.AddXY(StrToTime(s), 10);
    f:=f+1/MinsPerDay; // Плюс минута.
    if flag then begin
      m:=m+17;
      if m>60 then begin
        m:=60;
        flag:=false;
      end;
    end else begin
      m:=m-12.3;
      if m<10 then begin
        m:=10;
        flag:=true;
      end;
    end;
  end;
end;
Как построить прерывестый график c использованием TChart?
Как построить прерывестый график c использованием TChart?

Но это не выход из положения...
0
shyub
344 / 144 / 39
Регистрация: 11.07.2013
Сообщений: 791
09.07.2015, 20:21  [ТС] 6
Цитата Сообщение от volvo Посмотреть сообщение
Не надо никакой аппроксимации
Проблема в том, что я "перевожу" свои старые программы на Lazarus, хотелось бы сохранить приемственность.
Провозился весь день, но ничего лучшего, чем динамическое создание TChart1LineSeries так и не вышло...
Как построить прерывестый график c использованием TChart?

Вот код, может кому-нибудь ещё будет полезен:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// Динамическое добавление TChartLineSeries
procedure TForm1.Button6Click(Sender: TObject);
var
  i : Integer;
  m: double;
  f: double;
  s: string;
  flag: boolean;
  ML: array[0..3] of TLineSeries;
  MXY: array [1..2,1..30] of double;  // Данные (при Y<0 считается, что учёт не вёлся.
begin
  m:=0;
  f:=0;
  flag:=true;
  // Подготовка координат X и Y ().
  for i := 1 to 30 do begin
    MXY[1][i]:=f;
    f:=f+1/MinsPerDay; // Плюс минута.
    MXY[2][i]:=m;
    if flag then begin
      m:=m+17;
      if m>=60 then begin
        m:=60;
        flag:=false;
      end;
    end else begin
      m:=m-12;
      if m<=20 then begin
        m:=20;
        flag:=true;
      end;
    end;
    if(((i>8)and(i<13))or((i>21)and(i<26))) then begin // Имитация прерывания графика.
      MXY[2][i]:=-1;
    end;
  end;
  // Очистить.
  Button7Click(Sender);
  // Разрешить построение вне установленных по X координат.
  Chart2.Extent.UseXMax:=false;
  Chart2.Extent.UseXMin:=false;
//  for i:=1 to Chart2.SeriesCount-1 do Chart2.Series[i].Free;
  // Рисовать невидимую линию (чтобы не прерывалась шкала времени.).
  ML[0]:=TLineSeries.Create(Chart2);
  ML[0].ShowPoints:=false;
  ML[0].LineType:=ltNone;
  Chart2.AddSeries(ML[0]);
  // Вывод графика.
  flag:=true;
  for i := 1 to 30 do begin
    DateTimeToString(s,'t',MXY[1][i]);
    if MXY[2][i]>=0 then begin
      if flag then begin // Динамическое создание Chart2LineSeries
        ML[1]:=TLineSeries.Create(Chart2);
        ML[1].LinePen.Width:=2;
        ML[1].LinePen.Color:=ClRed;
        Chart2.AddSeries(ML[1]);
        ML[2]:=TLineSeries.Create(Chart2);
        ML[2].LinePen.Width:=2;
        ML[2].LinePen.Color:=ClBlue;
        Chart2.AddSeries(ML[2]);
        ML[3]:=TLineSeries.Create(Chart2);
        ML[3].LinePen.Width:=2;
        ML[3].LinePen.Color:=clGreen;
        Chart2.AddSeries(ML[3]);
        flag:=false;
      end;
      ML[1].AddXY(StrToTime(s), 60, '', ClRed); // Построение графика.
      ML[2].AddXY(StrToTime(s), MXY[2][i], '', ClBlue);
      ML[3].AddXY(StrToTime(s), 20, '', clGreen);
    end else flag:=true;
    ML[0].AddXY(StrToTime(s), 0); // Нужна, если график начинается с разрыва.
  end;
end;
// Очистка и удаление динамически созданных TChartLineSeries.
procedure TForm1.Button7Click(Sender: TObject);
var
  i: integer;
begin
  Chart2.Series.Clear;
  for i:=1 to Chart2.SeriesCount-1 do begin
    Chart2.Series[i].Free;
  end;
end;
0
09.07.2015, 20:21
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.07.2015, 20:21

как то график построить надо...
составить модель сложной последовательно-параллельной гомогенной каталитической...

Tchart, прямые цветные линии через весь график
Привет Всем! Помогите кто знает как на графике TChart нарисовать прямые линии...

Tchart и StringGrid: построить гистограмму номеров города
Всем привет,столкнулся с заданием: Есть некая электронная книга с разделами в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru