AlexKoblov 0 18 сентября, 2018 Опубликовано 18 сентября, 2018 · Жалоба Всем Привет! Есть ли стандартные средства перемещения и масштабирования отдельных графиков в ТеeChart? С масштабированием группы графиков (например графики Series1, Series2, Series3 входящих в один Chart1) , проблем нет, меняются минимумы и максимумы по оси-Y у Chart1, и они и двигаются и масштабируются быстро. Но нужно сдвинуть только один, например красный сдвинуть вверх, но чтобы зеленый остался на месте: Понятно что можно математически: for(int i=0;i<Chart1->Series[1]->Count()-1;i++) Chart1->Series[1]->YValues->Value[i]+=Y; Но при больших графиках, например по оси-X 690тысяч точек, такой алгоритм откровенно тормозит. А если масштабировать, т.е. умножать на какойто коэффициент, то могут начальные данные портится (исходные значения не сохраняются), а очищать Series1 заполнять его из какого-то массива с умножением на коэффициент тоже не быстро будет. Уже два дня копаю TeeChart на эту тему, в нем много всего, но нужное не могу найти. Может типа какая нибудь локальная система координат для каждого отдельного Series? Есть еще один вопрос, по поводу стандартного масштабирования в TeeChart, например есть такой график: он имеет пики 1,2,3, они очень тоненькие, но при отдалении зума они сохраняются, видно на нижнем графике, и изза этого создается впечатление что сигнал на нижнем графике сильно зашумлен, хотя там всего маленькие иголочки были. Это похоже как в осциллографе есть режим PeakDetected, но его в осциллографе можно выключить и эти тонкие пики на отдаленном по зуму сигнале отображаться не будут. Вот вопрос: как в TeeChart тоже отключить этот режим PeakDetected, т.е. чтобы на отдаленном отображении графика эти иголочки вообще не отображались ? Вот еще картинка для примера: Может нестандартными средствами можно такое скрыть (без использования фильтра LowPass) ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 18 сентября, 2018 Опубликовано 18 сентября, 2018 · Жалоба Но при больших графиках, например по оси-X 690тысяч точек, такой алгоритм откровенно тормозит. Тормоз появляется при большом объеме данных, которые надо постоянно обрабатывать при отображении на экране. Вопрос, зачем их обрабатывать постоянно, ведь они не изменяются ? (по крайней мере основная подавляющая их часть) Перед отображением информации сделайте ее предв. обработку, наподобие индексации и фильтрации с формированием файлов "ускоренных" индексов, меток итд . (например, для каждого значения масштаба отображения). Тогда "тормоз" будет один раз, при первой загрузке и сканировании массива, а при масштабировании можно пользоваться ускряющими сформированными "индексными" файлами. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexKoblov 0 31 мая, 2019 Опубликовано 31 мая, 2019 · Жалоба Вот сделал отображение графика как хотел, лишние иголочки не отображаются: Сверху как было, снизу как стало: Для вывода использовал компонент TeeChart - Color Grid - Color Range (у него обнаружилось ограничение в 32768 точек по горизонтали, поэтому мои 500тысяч точек пришлось сжимать под это размер, или в с случае pBitmap до ширины картинки, и именно 890точек) Но предварительно данные подготавливаются, сжимаются по горизонтали и вертикали в массив Map. В принципе можно выводить и в pBitmap->Canvas->Pixels[x][y] = RGB (Map[x][255-y], Map[x][255-y], Map[x][255-y]); а потом PaintBox1->Canvas->Draw(0,0,pBitmap); Вот отладочные куски может кому пригодится: первый это сжатие: Spoiler void __fastcall TForm1::Button4Click(TObject *Sender) { TColor Color; Color=RGB (128, 128, 128); AnsiString astr; int index; int CanvMaxX; int CanvMaxY; int col, ColorMax,ColorMin,ColorRange; double ColorStep; double SumArray[65536]; double data_in; //double Arr256[256]; double Val256; //signed short map[890][256]; //int *arr = new int [100000]; //double *map = new double [890][256]; /* // этот фрагмент выполняется при создании формы, вставил сюда для общего понимания n=890; m=256; Map = new double *[n]; for (int i = 0; i < n; ++i) Map[i] = new double [m]; pBitmap = new Graphics::TBitmap(); // здесь будет рисоваться картинка, а потом перерисовываться в PaintBox1 pBitmap->Height=PaintBox1->Height; pBitmap->Width=PaintBox1->Width; */ int flag_init=0; CanvMaxX=PaintBox1->Width; CanvMaxY=PaintBox1->Height; ColorMin=TrackBar1->Position;//=128; ColorMax=TrackBar2->Position;//255; ColorRange=ColorMax-ColorMin; ColorStep=(double)ColorRange/CanvMaxY; astr="CanvMaxX="; astr+=CanvMaxX; astr+=" CanvMaxY="; astr+=CanvMaxY; astr+=" ColorMin="; astr+=ColorMin; astr+=" ColorMax="; astr+=ColorMax; Label3->Caption=astr; ProgressBar1->Max=890; for (int len=0;len<890;len++) //890 это кол-во точек на отображаемом экране { // обнуляем массив SumArray for(int k=0;k<65536;k++) SumArray[k]=0; // сжимаем по горизонтали в один столбец N значений графика for (int i = 0; i < 584; i++) { data_in=Chart1->Series[0]->YValues->Value[len*584+i]; for (int j = 0; j < 65536; j++) { if(j<data_in) SumArray[j]+=1; } } // обнуляем Val256 Val256=0; // сжимаем по вертикали в 256 раз for (int i = 0; i < 256; i++) { for (int j = 0; j < 256; j++) { index=i*256+j; Val256+=SumArray[index]; if(index>65533) int g=0; } Val256/=256; Map[len][i]=Val256; // Map[890][256] if(flag_init==0) { max_val=Val256; min_val=Val256; flag_init=1;} else{ if (Val256<min_val) {min_val=Val256;} if (Val256>max_val) {max_val=Val256;} } } ProgressBar1->Position=len; } astr="Min="; astr+=min_val; astr+=" Max="; astr+=max_val; Label6->Caption=astr; ProgressBar1->Position=0; // ---------- копируем из Map в pBitmap --------------- for(int x=0;x<890;x++) for (int y=0;y<256;y++) { pBitmap->Canvas->Pixels[x][y] = RGB (Map[x][255-y], Map[x][255-y], Map[x][255-y]); } PaintBox1->Canvas->Draw(0,0,pBitmap); } второй это вывод на экран в двух видах, в картинку BitmapCanvas и в SeriesTeeChart: Spoiler void __fastcall TForm1::Button5Click(TObject *Sender) { double val_from_map,new_delta,old_delta,val_from,val_to; if (TrackBar2->Position > TrackBar1->Position) { val_from=TrackBar1->Position; val_to=TrackBar2->Position; } else { val_from=TrackBar2->Position; val_to=TrackBar1->Position; } //Series3->Clear(); // ---------- копируем из Map в pBitmap, переворачивая верх с низом --------------- for(int x=0;x<890;x++) for (int y=0;y<256;y++) { // double max_val, min_val; val_from_map=Map[x][y]; // нормирование цвета в диапазон val_from_map-=min_val; new_delta=val_to-val_from; old_delta=max_val-min_val; val_from_map=val_from_map*new_delta/old_delta; val_from_map+=val_from; pBitmap->Canvas->Pixels[x][255-y] = RGB (255-val_from_map, 255-val_from_map, 255-val_from_map); Series3->AddXYZ(x,RGB (val_from_map, val_from_map, val_from_map),y); } Label5->Caption=Map[10][TrackBar3->Position]; PaintBox1->Canvas->Draw(0,0,pBitmap); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexKoblov 0 4 июня, 2019 Опубликовано 4 июня, 2019 · Жалоба Заменил сжатие по горизонтали более простым алгоритмом, и время обработки сократилось с 56сек до 4сек То что закомментарено, это так было, а ниже как стало: // for (int j = 0; j < 65536; j++) { // if(j<data_in) SumArray[j]+=1; // } for (int j = 0; j < data_in; j++) { SumArray[j]+=1; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться