Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.06.2017, 13:10   #1
URQq
Пользователь
 
Регистрация: 31.05.2016
Сообщений: 11
Вопрос Проблема - 2 и более Chart`ов

Здравствуйте.

Столкнулся с проблемой отрисовки кривых на 2х и более Chart`ах.
Данные берутся из БД, в ней 780 строк - 17 столбцов. Если Chart один, кривые прорисовываются довольно быстро, работать можно. Проблема тормозов и долгой прорисовки появляются, если добавляю ещё Chart`ы.

Помогите решить проблему. Может я что не так делаю и с Chart`ом нужно работать по другому? Может код исправить или использовать другой компонент?

Код, который использую для прорисовки:

Код:
var
  i, j, n, m, Sck: integer;
  Rez: double;
  s: string;
  myDateTime: TDateTime;
begin
  s := Form1.ComboBox3.Text;
  Delete(s, 1, 2);
  Sck := 1;
  Rez := 0;
  for i := 1 to ColNam do     // Количество Chart`ов на форме
  begin
    if (FindComponent('ChartCol' + IntToStr(i)) as TChart).SeriesCount = 0 then Continue;
    for j := 0 to (FindComponent('JvDBGridCol' + IntToStr(i)) as TJvDBGrid).Columns.Count - 1 do
    begin
      if not (FindComponent('JvDBGridCol' + IntToStr(i)) as TJvDBGrid).Columns[j].Visible then Continue;
      for n := 0 to (FindComponent('ChartCol' + IntToStr(i)) as TChart).SeriesCount - 1 do
        if (FindComponent('ChartCol' + IntToStr(i)) as TChart).Series[n].Tag = j - 1 then
        begin
          Form1.ClientDataSet1.RecNo := Form1.ScrollBar1.Position * (StrToInt(s) * 5) + 1;
          (FindComponent('ChartCol' + IntToStr(i)) as TChart).Series[n].Active := false;
          (FindComponent('ChartCol' + IntToStr(i)) as TChart).SeriesList[n].Clear;
          for m := Form1.ClientDataSet1.RecNo to (Form1.ClientDataSet1.RecNo + 12 * (StrToInt(s) * 5)) do
          begin
            if m > Form1.ClientDataSet1.RecordCount then Break;
            Form1.ClientDataSet1.RecNo := m;
            Rez := Rez + Form1.ClientDataSet1.Fields[j].Value;
            if Sck = StrToInt(s) then
            begin
              Rez := Rez / StrToInt(s);
              Sck := 1;
              (FindComponent('ChartCol' + IntToStr(i)) as TChart).Series[n].AddXY(Rez,Form1.ClientDataSet1.Fields[0].Value,'');
              Rez := 0;
            end;
            Inc(Sck);
          end;
          (FindComponent('ChartCol' + IntToStr(i)) as TChart).Series[n].Active := true;
          (FindComponent('ChartCol' + IntToStr(i)) as TChart).Repaint;
        end;
    end;
  end;
  Form1.ClientDataSet1.Last;
end;

Последний раз редактировалось URQq; 22.06.2017 в 13:13.
URQq вне форума Ответить с цитированием
Старый 22.06.2017, 13:20   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Зачем FindComponent одного и того же повторять, да еще и в цикле? В нем самом цикл по Componets есть. Найди и запомни в переменную. Медленней точно не станет ))
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 22.06.2017, 13:34   #3
URQq
Пользователь
 
Регистрация: 31.05.2016
Сообщений: 11
По умолчанию

Хмм...

Имеется в виду так:
Код:
var
   MyComponent: TComponent;
Begin
   MyComponent := FindComponent('CheckBox1');
   TCheckBox(MyComponent).Checked := True;
end;
Или есть ещё способ? =)
URQq вне форума Ответить с цитированием
Старый 22.06.2017, 13:44   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Можно и так, а можно и сразу к нужному типу привести, что бы потом не было много раз TCheckBox(MyComponent)
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 22.06.2017, 13:47   #5
URQq
Пользователь
 
Регистрация: 31.05.2016
Сообщений: 11
По умолчанию

Примерчик можно?
Пожалуйста.

Так?
Код:
var
   MyComponent: TCheckBox;
Begin
   MyComponent := FindComponent('CheckBox1' as TCheckBox);
   MyComponent.Checked := True;
end;
И всё таки хотелось бы узнать способен ли Chart нормально работать с большим количеством точек (более 1000 например)?

Последний раз редактировалось URQq; 22.06.2017 в 13:53.
URQq вне форума Ответить с цитированием
Старый 22.06.2017, 14:14   #6
URQq
Пользователь
 
Регистрация: 31.05.2016
Сообщений: 11
По умолчанию

Переписал код, но это совсем не помогло.
Все также печально и медленно происходит прорисовка.

Есть ещё идеи? Потому как у меня нет.

Код:
var
  i, j, n, m, Sck: integer;
  Rez: double;
  s: string;
  ChartSelf: TChart;
  JvDBGridSelf: TJvDBGrid;
begin
  s := Form1.ComboBox3.Text;
  Delete(s, 1, 2);
  Sck := 1;
  Rez := 0;
  for i := 1 to ColNam do     // Количество Chart`ов на форме
  begin
    ChartSelf := FindComponent('ChartCol' + IntToStr(i)) as TChart;
    JvDBGridSelf := FindComponent('JvDBGridCol' + IntToStr(i)) as TJvDBGrid; 
    if ChartSelf.SeriesCount = 0 then Continue;
    for j := 0 to JvDBGridSelf.Columns.Count - 1 do
    begin
      if not JvDBGridSelf.Columns[j].Visible then Continue;
      for n := 0 to ChartSelf.SeriesCount - 1 do
        if ChartSelf.Series[n].Tag = j - 1 then
        begin
          Form1.ClientDataSet1.RecNo := Form1.ScrollBar1.Position * (StrToInt(s) * 5) + 1;
          ChartSelf.Series[n].Active := false;
          ChartSelf.SeriesList[n].Clear;
          for m := Form1.ClientDataSet1.RecNo to (Form1.ClientDataSet1.RecNo + 12 * (StrToInt(s) * 5)) do
          begin
            if m > Form1.ClientDataSet1.RecordCount then Break;
            Form1.ClientDataSet1.RecNo := m;
            Rez := Rez + Form1.ClientDataSet1.Fields[j].Value;
            if Sck = StrToInt(s) then
            begin
              Rez := Rez / StrToInt(s);
              Sck := 1;
              ChartSelf.Series[n].AddXY(Rez,Form1.ClientDataSet1.Fields[0].Value,'');
              Rez := 0;
            end;
            Inc(Sck);
          end;
          ChartSelf.Series[n].Active := true;
          ChartSelf.Repaint;
        end;
    end;
  end;
  Form1.ClientDataSet1.Last;
end;
URQq вне форума Ответить с цитированием
Старый 22.06.2017, 15:20   #7
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

А DBChart чего не устроил? Он адаптирован к построению графиков из датасетов
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 22.06.2017, 15:30   #8
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,515
По умолчанию

Первое. В какой такой процедуре писан данный код. А то случается пишут код в процедурах рисования и ТАМ же инициируют новый виток рисований.
Цитата:
Код:
          ChartSelf.Repaint;
Второе. Переходы по набору данных вещь затратная.
Код:
Form1.ClientDataSet1.RecNo := m;
а мы это делаем ColNam * DBGrid.ColCount {если считать что все колонки показаны}
А вот достать элемент массива не так долго.

попробуй поменять циклы местами ЧТОБЫ уменьшить число просмотров набора данных. А нужные тебе Chart и DBGrid занеси в массив и бери оттуда.

P.S. и отключи "визуальное" сопровождение прохода по DataSet, это тоже нагрузка.
Код:
DataSet.DisableControls; 
не забудь потом EnableControls;
можно начать с этого.

P.P.S. делать много-много-много раз Strtoint(s) тоже не комильфо. Заведи переменную, вычисли один раз и используй.
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 22.06.2017 в 15:40.
evg_m на форуме Ответить с цитированием
Старый 23.06.2017, 06:49   #9
URQq
Пользователь
 
Регистрация: 31.05.2016
Сообщений: 11
По умолчанию

1) Данный код прописан сейчас на нажатии кнопки. Зацикливания не происходит, если вы об этом =)

2) Действительно, так будет логичнее. Хорошее замечание.

3) Собственно проблема решилась благодаря этому совету ("отключи "визуальное" сопровождение прохода по DataSet").

4) Strtoint(s) - тоже переделал, эстетики ради =)

В общем Спасибо за советы, решение найдено и оно меня устраивает.
URQq вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с Chart илия67 Общие вопросы Delphi 1 13.09.2013 01:47
Проблема с chart'om Klyuka Общие вопросы Delphi 5 08.06.2013 15:50
Проблема с компонентом Chart kta87 Общие вопросы Delphi 3 12.03.2010 18:59
(проблема с курсовиком)Вопрос по компоненту Chart irk-daredevil Помощь студентам 0 18.12.2009 09:27
Проблема с Chart на Delphi 6 ( Georgios Помощь студентам 6 19.01.2009 14:54