Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.95/21: Рейтинг темы: голосов - 21, средняя оценка - 4.95
5 / 7 / 5
Регистрация: 13.11.2015
Сообщений: 267
1

Гистограмма. Отображение столбцов

12.03.2016, 00:16. Показов 4095. Ответов 34
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток, уважаемые форумчане! Этот форум уже несколько лет помогал мне с решением многих проблем программирования. Вот и я застопорился....
Задача заключается в следующем. Берется максимальное и минимальное значения, выбирается количество классов от 5 до 15. Вычитая MAX и MIN значения,делим разность на число классов получаем шаг класса. Например, берем рост человека от 160 до 190 см, находим шаг класса и получаем промежутки. Допустим при шаге 2, получаем промежутки 160-162,162-164,..., 188-190. В каждый такой промежуток входят произвольное число человек. Необходимо постороить гистограмму. Гистограмму получилось построить, но неправильно.

Вот код:
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
unit Unit1;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.StdCtrls,
  VCLTee.TeEngine, VCLTee.Series, Vcl.ExtCtrls, VCLTee.TeeProcs, VCLTee.Chart;
 
type
  TForm1 = class(TForm)
    XMM: TEdit;        //X max
    XMN: TEdit;        //X min
    NCL: TEdit;        //chislo classov
    SHAG: TEdit;       //vivod shaga classa
    Start: TButton;
    TABLE: TStringGrid;      // tblicha dlya dannih
    DRAW: TButton;
    TABLE2: TStringGrid;     //таблица для колличества чего-то, входящего в данный промежуток
    HISTO: TChart;
    HISTOSer: TBarSeries;
    procedure StartClick(Sender: TObject);      //расчет по формуле
    procedure DRAWClick(Sender: TObject);      //построение гистограммы
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
  XMAX,XMIN,CLASSNUM: Integer;
  DELTA: Real;
  l,m: Integer;
  NUM: array of Integer;
  MAS: array of Real;
  MAS2: array of Real;
implementation
 
{$R *.dfm}
 
procedure TForm1.FormCreate(Sender: TObject);
begin
 with HISTOSer do
  clear;
end;
 
procedure TForm1.StartClick(Sender: TObject);
var
i:Real;
begin
 XMAX:= StrToInt(Form1.XMM.Text);
 XMIN:=StrToInt(Form1.XMN.Text);
 CLASSNUM:= StrToInt(Form1.NCL.Text); // число классов 5-15
 Form1.TABLE.RowCount:=CLASSNUM+2;   // задаем чсило строк (число классов)+ 2
 Form1.TABLE2.RowCount:=CLASSNUM+1;
 Form1.TABLE.Cells[0,0]:='Классы';
 Form1.TABLE.Cells[0,1]:=IntToStr(XMIN);
 Form1.TABLE2.Cells[0,0]:='N';
 SetLength(MAS,CLASSNUM);       // длина массива
 DELTA:= (XMAX-XMIN) div CLASSNUM;   // находим шаг класса
 Form1.SHAG.Text:= FloatToStr(DELTA);   // выводим шаг классов
 i:=XMIN;
  for m := 1 to CLASSNUM do
    begin
      while i <= XMAX do
        begin
       for l := 2 to TABLE.RowCount do
         begin
           i:=i+DELTA;            // суммируем минимальное+ шаг
           MAS[m]:=i;           // заполняем массив
           TABLE.Cells[0,l]:=FloatToStr(MAS[m]);         //выводим в таблицу
        end;
 
      end;
    end;
end;
 
procedure TForm1.DRAWClick(Sender: TObject);
begin
  Form1.HISTOSer.Clear;
  CLASSNUM:= StrToInt(Form1.NCL.Text);
  //SetLength(MAS2,CLASSNUM);
  for m := 1 to CLASSNUM do
    begin
       for l := 1 to TABLE2.RowCount-1 do
        begin
         for l:=1 to TABLE.RowCount-1 do
           begin
          MAS[m]:=StrToFloat(TABLE.Cells[0,l]);
          Form1.HISTOSer.AddXY(MAS[m],StrToInt(TABLE2.Cells[0,l]),FloatToStr(MAS[m]) ,clGreen );
          end;
        end;
    end;
end;
Прикладываю скриншоты. Как сделать так, чтобы гистограмма имела вид, как на втором скриншоте(правда последнее значение не отобразило, знаю почему)? Заранее спасибо за любую подсказку.
Миниатюры
Гистограмма. Отображение столбцов   Гистограмма. Отображение столбцов  
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.03.2016, 00:16
Ответы с готовыми решениями:

StringGrid отображение первых столбцов
Здравствуйте. Помогите пожалуйста. Я где только не лазил, учебники, гугл и искал на вашем форуме но...

Гистограмма. Точки и их соединение
Доброго времени суток! Залип, не знаю уже как сделать. Необходимо на гистограмме обозначить точки...

Нестандартная гистограмма TChart
Здравствуйте. Решается задача: по полученным данным построить гистограмму. С чем работаю: Среда...

Гистограмма оценок в классе
Нужно сделать так чтоб в edit вводились числа от 2 до 5 ( зависит от количества учеников если их 15...

34
пофигист широкого профиля
4732 / 3167 / 858
Регистрация: 15.07.2013
Сообщений: 18,250
12.03.2016, 00:36 2
А чем вторая гистограмма правильнее первой?
0
5 / 7 / 5
Регистрация: 13.11.2015
Сообщений: 267
12.03.2016, 00:38  [ТС] 3
В промежуток между 31 и 32 вмещается N=2 и так далее.
0
пофигист широкого профиля
4732 / 3167 / 858
Регистрация: 15.07.2013
Сообщений: 18,250
12.03.2016, 00:52 4
Цитата Сообщение от Krutko Посмотреть сообщение
В промежуток между 31 и 32 вмещается N=2 и так далее.
А нормальным языком никак не объяснить? Что есть 31 и 32? Что значит "вмещается N=2". Про "и так далее" пока молчу.
0
5 / 7 / 5
Регистрация: 13.11.2015
Сообщений: 267
12.03.2016, 03:05  [ТС] 5
Прошу прощения. Определив число и ширину интервалов (См скриншот, число интервалов=10, а ширина интервала=1), заполняем таблицу класс-интервалов(См. скриншот таблица "Классы", те самые 31-32), определяем какое число данных входят в этот интервал(См. скриншоты, таблица "N"). Итого "столбик" гистограммы имеет ширину интервала, а его высота равна числу данных, входящих в него. Так понятнее, или я в силу своего косноязычия опять что-то не так сказал?

Добавлено через 2 часа 2 минуты
Цитата Сообщение от northener Посмотреть сообщение
А нормальным языком никак не объяснить? Что есть 31 и 32? Что значит "вмещается N=2". Про "и так далее" пока молчу.
Цитата Сообщение от Krutko Посмотреть сообщение
Прошу прощения. Определив число и ширину интервалов (См скриншот, число интервалов=10, а ширина интервала=1), заполняем таблицу класс-интервалов(См. скриншот таблица "Классы", те самые 31-32), определяем какое число данных входят в этот интервал(См. скриншоты, таблица "N"). Итого "столбик" гистограммы имеет ширину интервала, а его высота равна числу данных, входящих в него. Так понятнее, или я в силу своего косноязычия опять что-то не так сказал?
По сути необходимо сместить отрисовку графика на точку по оси X, равную минимальному значению.
0
Почетный модератор
64300 / 47595 / 32743
Регистрация: 18.05.2008
Сообщений: 115,181
12.03.2016, 09:44 6
Можно написать
Delphi
1
series1.Offsetpercent:=50;//сдвиг столбцов вправо
или
Delphi
1
series1.Offsetpercent:=-50;//сдвиг столбцов влево
Миниатюры
Гистограмма. Отображение столбцов   Гистограмма. Отображение столбцов  
1
5 / 7 / 5
Регистрация: 13.11.2015
Сообщений: 267
12.03.2016, 13:02  [ТС] 7
Цитата Сообщение от Puporev Посмотреть сообщение
Можно написать
Спасибо! Но возникла следующая проблемка. Все сместило правильно, но в Chart'е не отображается последнее значение (См. скриншот). Как исправить?
Миниатюры
Гистограмма. Отображение столбцов  
0
Почетный модератор
64300 / 47595 / 32743
Регистрация: 18.05.2008
Сообщений: 115,181
12.03.2016, 13:05 8
Поставьте значение maximum по оси Bottom =15, ну если оно меняется, то =максимуму по классам.
0
Почетный модератор
64300 / 47595 / 32743
Регистрация: 18.05.2008
Сообщений: 115,181
12.03.2016, 13:43 9
Добавил нулевой столбец в конец
Delphi
1
2
3
for i:=0 to m-1 do
series1.Add(b[i],Inttostr(i+1),rgb(random(255),random(255),random(255)));
series1.Add(0,Inttostr(m),rgb(random(255),random(255),random(255)));
И получил
Миниатюры
Гистограмма. Отображение столбцов  
1
5 / 7 / 5
Регистрация: 13.11.2015
Сообщений: 267
12.03.2016, 13:56  [ТС] 10
Цитата Сообщение от Puporev Посмотреть сообщение
Добавил нулевой столбец в конец
Такс... А что у Вас есть i-число столбцов ,без нулевого,а m-их общее число?
Просто лишняя "6" мне не нужна.
Получается, что столбцов у меня на один меньше, чем значений в таблице классы. Попробовал задать максимальное значение по оси оХ вот таким образом:
Delphi
1
2
3
4
5
6
7
8
9
10
11
Form1.HISTOSer.Clear;
 HISTO.RightAxis.Automatic:=false;
 HISTO.RightAxis.AutomaticMaximum:= false;
 HISTO.RightAxis.AutomaticMinimum:= false;
 Form1.HISTOSer.OffsetPercent:=50;
 XMAX:= StrToInt(Form1.XMM.Text);
 XMIN:=StrToInt(Form1.XMN.Text);
 CLASSNUM:= StrToInt(Form1.NCL.Text);
 HISTO.RightAxis.Minimum:=0;
 HISTO.RightAxis.Maximum:= XMAX;
  //SetLength(MAS2,CLASSNUM);
Вышло все тоже самое. И да, значение XMAX у меня меняется. Как тогда программно задается этот самый Bottom? Просто я с графикой раньше не работал. Спасибо, Puporev, за то , что отозвались на помощь!
0
Почетный модератор
64300 / 47595 / 32743
Регистрация: 18.05.2008
Сообщений: 115,181
12.03.2016, 14:01 11
Я смотрю, все все в false загнали, по моему зря. У меня все стоит по умолчанию, кроме
Delphi
1
2
3
series1.BarWidthPercent:=100;
series1.Offsetpercent:=50;
series1.Marks.Visible:=false;
Изменения о которых я говорил раньше не пригодились.

Добавлено через 53 секунды
Я смотрю, все все в false загнали, по моему зря. У меня все стоит по умолчанию, кроме
Delphi
1
2
3
series1.BarWidthPercent:=100;
series1.Offsetpercent:=50;
series1.Marks.Visible:=false;
Изменения о которых я говорил раньше не пригодились.

Добавлено через 1 минуту
Я смотрю, все все в false загнали, по моему зря. У меня все стоит по умолчанию, кроме
Delphi
1
2
3
series1.BarWidthPercent:=100;
series1.Offsetpercent:=50;
series1.Marks.Visible:=false;
Изменения о которых я говорил раньше не пригодились.
0
5 / 7 / 5
Регистрация: 13.11.2015
Сообщений: 267
12.03.2016, 14:22  [ТС] 12
Д
Цитата Сообщение от Puporev Посмотреть сообщение
Я смотрю, все все в false загнали, по моему зря. У меня все стоит по умолчанию, кроме
Да, видимо зря. Сделал эти три строчки, результат то же, что и был у меня ранее.
Привожу код целиком. Я видимо где-то ранее накосячил... Скорей всего проблема в кнопке DRAW.
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
unit Unit1;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.StdCtrls,
  VCLTee.TeEngine, VCLTee.Series, Vcl.ExtCtrls, VCLTee.TeeProcs, VCLTee.Chart;
 
type
  TForm1 = class(TForm)
    XMM: TEdit;        //X max
    XMN: TEdit;        //X min
    NCL: TEdit;        //chislo classov
    SHAG: TEdit;       //vivod shaga classa
    Start: TButton;
    TABLE: TStringGrid;      // tblicha dlya dannih
    DRAW: TButton;
    TABLE2: TStringGrid;     //таблица для колличества чего-то, входящего в данный промежуток
    HISTO: TChart;
    HISTOSer: TBarSeries;
    procedure StartClick(Sender: TObject);      //расчет по формуле
    procedure DRAWClick(Sender: TObject);      //построение гистограммы
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
  XMAX,XMIN,CLASSNUM: Integer;
  DELTA: Real;
  s,l,m: Integer;
  NUM: array of Integer;
  MAS: array of Real;
  MAS2: array of Real;
implementation
 
{$R *.dfm}
 
procedure TForm1.FormCreate(Sender: TObject);
begin
 with HISTOSer do
  clear;
end;
 
procedure TForm1.StartClick(Sender: TObject);
var
i:Real;
begin
 XMAX:= StrToInt(Form1.XMM.Text);
 XMIN:=StrToInt(Form1.XMN.Text);
 CLASSNUM:= StrToInt(Form1.NCL.Text); // число классов 5-15
 Form1.TABLE.RowCount:=CLASSNUM+2;   // задаем чсило строк (число классов)+ 2
 Form1.TABLE2.RowCount:=CLASSNUM+1;
 Form1.TABLE.Cells[0,0]:='Классы';
 Form1.TABLE.Cells[0,1]:=IntToStr(XMIN);
 Form1.TABLE2.Cells[0,0]:='N';
 SetLength(MAS,CLASSNUM);       // длина массива
 DELTA:= (XMAX-XMIN) div CLASSNUM;   // находим шаг класса
 Form1.SHAG.Text:= FloatToStr(DELTA);   // выводим шаг классов
 i:=XMIN;
  for m := 1 to CLASSNUM do
    begin
      while i <= XMAX do
        begin
       for l := 2 to TABLE.RowCount do
         begin
           i:=i+DELTA;            // суммируем минимальное+ шаг
           MAS[m]:=i;           // заполняем массив
           TABLE.Cells[0,l]:=FloatToStr(MAS[m]);         //выводим в таблицу
        end;
 
      end;
    end;
end;
 
procedure TForm1.DRAWClick(Sender: TObject);
begin
 Form1.HISTOSer.Clear;
 Form1.HISTOSer.BarWidthPercent:=100;
 Form1.HISTOSer.OffsetPercent:=50;
 Form1.HISTOSer.Marks.Visible:=False;
 XMAX:= StrToInt(Form1.XMM.Text);
 XMIN:=StrToInt(Form1.XMN.Text);
 CLASSNUM:= StrToInt(Form1.NCL.Text);
  //SetLength(MAS2,CLASSNUM);
  for m := 1 to CLASSNUM do
    begin
       for l := 1 to TABLE2.RowCount-1 do
        begin
         for l:=1 to TABLE.RowCount-1 do
           begin
               //MAS[m]:=StrToFloat(TABLE.Cells[0,l]);
               Form1.HISTOSer.AddXY(StrToInt(TABLE.Cells[0,l]),StrToInt(TABLE2.Cells[0,l]),FloatToStr(MAS[m]) ,clGreen );
        end;
    end;
   end;
end;
 
end.
Добавлено через 9 минут
Ой, 96 строка надо раскомментировать
0
Почетный модератор
64300 / 47595 / 32743
Регистрация: 18.05.2008
Сообщений: 115,181
12.03.2016, 14:25 13
Вы серьезно думаете что я буду лепить проект?
0
5 / 7 / 5
Регистрация: 13.11.2015
Сообщений: 267
12.03.2016, 14:26  [ТС] 14
Нет, ни в коем случае)
Цитата Сообщение от Puporev Посмотреть сообщение
Поставьте значение maximum по оси Bottom =15, ну если оно меняется, то =максимуму по классам.
Как сие сделать или все таки не стоит?
0
Почетный модератор
64300 / 47595 / 32743
Регистрация: 18.05.2008
Сообщений: 115,181
12.03.2016, 14:34 15
Нет,это не стоит делать, никак не влияет, Сдвинуть
Delphi
1
series1.Offsetpercent:=50;
и добавить в конец столбец со значением = 0.
0
Почетный модератор
64300 / 47595 / 32743
Регистрация: 18.05.2008
Сообщений: 115,181
12.03.2016, 15:30 16
Вот набросал быстро, получилось такое, может поможет.
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
var
  Form1: TForm1;
  a:array of array[1..2] of byte;
  n:integer;
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
var i:byte;
begin
n:=8;
with StringGrid1 do
 begin
  fixedrows:=1;
  fixedcols:=0;
  colcount:=2;
  rowcount:=n+1;
  cells[0,0]:='Классы';
  cells[1,0]:='Количество';
 end;
randomize;
setlength(a,n);
for i:=0 to n-1 do
 begin
  a[i,1]:=i+10;//классы
  a[i,2]:=5+random(20);//количество в классе
  StringGrid1.Cells[0,i+1]:=inttostr(a[i,1]);
  StringGrid1.Cells[1,i+1]:=inttostr(a[i,2]);
 end;
series1.BarWidthPercent:=100;
series1.Offsetpercent:=50;
series1.Marks.Visible:=false;
for i:=0 to n-1 do
series1.Add(a[i,2],Inttostr(a[i,1]),rgb(random(255),random(255),random(255)));
series1.Add(0,Inttostr(n+10),rgb(random(255),random(255),random(255)));
end;
Миниатюры
Гистограмма. Отображение столбцов  
0
Почетный модератор
64300 / 47595 / 32743
Регистрация: 18.05.2008
Сообщений: 115,181
12.03.2016, 15:31 17
Ничего кроме строк 31-33 в Чарте не менял.
1
5 / 7 / 5
Регистрация: 13.11.2015
Сообщений: 267
12.03.2016, 16:03  [ТС] 18
А как будет выглядеть добавление нулевого столбца через AddXY?
Цитата Сообщение от Puporev Посмотреть сообщение
Вот набросал быстро, получилось такое, может поможет.
Спасибо за код!
Просто я вывожу данные с таблиц. При нажатии START-посчитал по формуле шаг/классы. Потом ввожу данные в таблицу N, жму DRAW-рисую. Применяю AddXY
Delphi
1
Form1.HISTOSer.AddXY(StrToInt(TABLE.Cells[0,l]),StrToInt(TABLE2.Cells[0,l]),TABLE.Cells[0,l],clGreen );
А при добавлении вот такого нулевого столбца
Delphi
1
Form1.HISTOSer.AddXY(XMAX+1,0,IntToStr(XMAX+1));
Столбики накладываются друг на друга. Но гистограмма отрисовывается верно.
0
Почетный модератор
64300 / 47595 / 32743
Регистрация: 18.05.2008
Сообщений: 115,181
12.03.2016, 16:05 19
Цитата Сообщение от Krutko Посмотреть сообщение
Просто я вывожу данные с таблиц.
Так в таблицы-то они попадают из массивов? Ну и бери массивы чтобы с индексами не путаться.
0
5 / 7 / 5
Регистрация: 13.11.2015
Сообщений: 267
12.03.2016, 16:10  [ТС] 20
Цитата Сообщение от Puporev Посмотреть сообщение
Так в таблицы-то они попадают из массивов? Ну и бери массивы чтобы с индексами не путаться.
В таблицу "классы" я впиндяриваю массив. А таблице "N" данные ввожу от руки. Данные из таблиц "Классы" и "N" отрисовываю в виде гистограммы. Убрал массив MAS[m] Из отрисовщика, т.к. оказалось можно и без него обойтись
0
12.03.2016, 16:10
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.03.2016, 16:10
Помогаю со студенческими работами здесь

Сегментированная гистограмма (Bar) в TChart.
Скажите как построить сегментированную гистограмму наподобие этой: ...

Передвижение анимации, тест, гистограмма
ребята нужна ваша помощь нужно сделать так как на этих готовых файлах очень нужно срочно там...

Построить столбчатую диаграмму (гистограмма)
(Консольное приложение) Столбчатая диаграмма(гистограмма) представляет собой набор...

Гистограмма, в которой высота столбцов зависит от одного диапазона, а ширина столбцов от другого
Доброго времени суток! Прошу помочь вас, в сложной для меня проблеме. не могу &quot;нарисовать&quot;...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru