Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/9: Рейтинг темы: голосов - 9, средняя оценка - 5.00
7 / 5 / 2
Регистрация: 25.05.2013
Сообщений: 112
1

Построение графиков

16.10.2018, 18:19. Показов 1793. Ответов 7

Всем привет!

Есть необходимость построить несколько графиков по точкам так, чтобы у них была одна общая ось X и разные оси Y, и чтобы графики шли друг под другом, чтобы их можно было перетаскивать мышью по вертикале и объединять шкалы Y.

Выглядеть это должно примерно так:
Графики друг под другом, слева обозначения и значения в точке курсора, справа скролл.
Построение графиков


Один график натянут на другой
Построение графиков


Совмещенные шкалы
Построение графиков




Вопрос заключается в том, в какую сторону гуглить?

tChart pro поковырял, но как мне показалось, там нет таких возможностей
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.10.2018, 18:19
Ответы с готовыми решениями:

Построение графиков
Помогите пожалуйста построить график функции при помощи компонента Image

построение графиков
здраствуйте, сразу прошу прощенья за глупый вопрос Я пытаюсь построить график по значениям из...

Построение Графиков.
Затруднения возникла с кодом где строю графики... и я построил деления для оси абсцисс (Х), но не...

Построение графиков
Добрый день, мне сказали написать программу, которая строила бы график по точкам. После...

7
случайный прохожий
1511 / 1013 / 373
Регистрация: 20.07.2013
Сообщений: 2,943
16.10.2018, 20:07 2
Какие-либо наработки имеются? Если нет, то можно начать с этой темы: Краткое руководство по работе с классом TCanvas для начинающих

По мне самое сложное тут перемещать графики. Так как после перемещения они просто накладываются друг на друга, а не суммируются, то задача в остальных моментах вполне тривиальна.
В качестве примера (на название темы обращать внимание не стоит) - движущийся график с возможностью его видоизменять: Компонент UpDown
0
7 / 5 / 2
Регистрация: 25.05.2013
Сообщений: 112
17.10.2018, 11:02  [ТС] 3
Цитата Сообщение от gunslinger Посмотреть сообщение
Какие-либо наработки имеются?
Спасибо за ответ!

Вот эти скриншоты и есть наработки, там на канве нарисовано, но реализация не очень и вопросов по допиливанию еще больше. А при перетаскивании они и должны накладываться чисто для визуального сравнения.
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
31187 / 20385 / 7940
Регистрация: 22.10.2011
Сообщений: 35,347
Записей в блоге: 6
18.10.2018, 15:18 4
Лучший ответ Сообщение было отмечено Fastex007 как решение

Решение

Цитата Сообщение от gunslinger Посмотреть сообщение
самое сложное тут перемещать графики
В чем, интересно, оно самое сложное? Эту задачу вполне можно скормить Windows (через Drag&Drop)... Все, что нужно - пишем класс-перехватчик (да, да, опять перехватчик, я считаю, что проще всего написать такой класс, а не назначать события одного компонента другим) :

C++
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
namespace Chart_DragDrop
{
    class TChart : public Vcltee::Chart::TChart
    {
        TPopupMenu *FPopup;
 
    public:
        inline __fastcall virtual TChart(TComponent* AOwner) : Vcltee::Chart::TChart(AOwner)
        {
            DragMode = dmAutomatic;
            FPopup = new TPopupMenu(this);
            TMenuItem *FItem = new TMenuItem(FPopup);
            FItem->Caption = "Clear";
            FItem->OnClick = ClearClick;
            FPopup->Items->Add(FItem);
            PopupMenu = FPopup;
        }
        DYNAMIC void __fastcall DragDrop(System::TObject* Source, int X, int Y)
        {
            TChart *src = static_cast<TChart*>(Source);
            // TChart *dst = static_cast<TChart*>(Sender);
            TChartSeries *src_serie = src->Series[0];
            // dst->AddSeries(CloneChartSeries(src_serie));
            AddSeries(CloneChartSeries(src_serie));
        }
 
    private:
        void __fastcall ClearClick(TObject *Sender)
        {
            for(int i = SeriesCount() - 1; i > 0; i--)
                delete Series[i];
        }
 
    protected:
        DYNAMIC void __fastcall DoContextPopup(const System::Types::TPoint &MousePos, bool &Handled)
        {
            if(PopupMenu)
            {
                PopupMenu->Items->Items[0]->Enabled = SeriesCount() > 1;
            }
        }
        DYNAMIC void __fastcall DragOver(System::TObject* Source, int X, int Y, System::Uitypes::TDragState State, bool &Accept)
        {
            Accept = Source->ClassNameIs("TChart");
        }
    };
};
#define TChart Chart_DragDrop::TChart
 
// тут класс формы без изменений
, положить на форму ScrollBox, в него несколько панелей (с Align = alTop), и в каждую панель - TChart (Align = alClient). Дальше все будет делать перехватчик. При захвате чарта и его перетягивании на другой чарт в приемник просто будет копироваться серия из источника. При этом, разумеется (поскольку они будут находиться на одном чарте), они будут правильно отмасштабированы. Когда сравнение закончено - жмем на чарте-приемнике правую кнопку мыши и выбираем единственный доступный пункт - "Очистить". Побочное явление этого решения - можно сравнивать гораздо больше двух серий.

А, да... Чтобы ScrollBox при Drag-е прокручивался, нужно еще написать обработчик события OnDragOver для формы, и таймер:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void __fastcall TForm1::FormDragOver(TObject *Sender, TObject *Source, int X, int Y,
          TDragState State, bool &Accept)
{
    Accept = false;
    Timer1->Enabled = (X > ScrollBox1->BoundsRect.Left) && (X < ScrollBox1->BoundsRect.Right) && 
                      ((Y < ScrollBox1->BoundsRect.Top) || (Y > ScrollBox1->BoundsRect.Bottom));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
    TPoint pt;
    ::GetCursorPos(&pt);
    pt = ScreenToClient(pt);
    TRect br = ScrollBox1->BoundsRect;
    
    if (pt.X > br.Left && pt.X < br.Right)
    {
        if(pt.Y < br.Top) ScrollBox1->Perform(WM_VSCROLL, SB_LINEUP, 0);
        else if (pt.Y > br.Bottom) ScrollBox1->Perform(WM_VSCROLL, SB_LINEDOWN, 0);
        else Timer1->Enabled = false;
    }
    else Timer1->Enabled = false;   
}
В результате имеем вот такую структуру контролов:
Построение графиков


, вот так выглядит форма в рантайме изначально:
Построение графиков


, вот так - после совмещения двух чартов:
Построение графиков


Сам проект нужен?
3
7 / 5 / 2
Регистрация: 25.05.2013
Сообщений: 112
18.10.2018, 15:41  [ТС] 5
Спасибо за подробное объяснение!

Цитата Сообщение от volvo Посмотреть сообщение
Сам проект нужен?
Да, пожалуйста
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
31187 / 20385 / 7940
Регистрация: 22.10.2011
Сообщений: 35,347
Записей в блоге: 6
18.10.2018, 15:59 6
Вот проект. Собиралось на XE4:
1
Вложения
Тип файла: zip chart_compare.zip (109.4 Кб, 33 просмотров)
случайный прохожий
1511 / 1013 / 373
Регистрация: 20.07.2013
Сообщений: 2,943
18.10.2018, 18:04 7
volvo, под сложностью перемещения графиков я подразумевал случай "моего любимого" рисования на канве (2-ой пост, 2-я ссылка), по возможности без использования вспомогательных компонентов для рисования.
Согласен, попахивает "велосипедофилией", но я такой, ничего с этим поделать не могу, люблю щупать все изнутри.
А твой вариант, как обычно
18+ (детям не смотреть)
[censored]

 Комментарий модератора 
gunslinger, пункт 5.2 Правил форума еще никто не отменял! Предупреждение!
0
7 / 5 / 2
Регистрация: 25.05.2013
Сообщений: 112
19.10.2018, 13:38  [ТС] 8
Цитата Сообщение от volvo Посмотреть сообщение
Вот проект. Собиралось на XE4:
Спасибо, очень помогло. Была мысль попробовать собрать свой компонент на основе TPaintBox или TImage, т.к. есть еще требования по синхронизации данных, вывода надписей общего вертикального курсора и прочих радостей, но нет уверенности в том, стоит ли велосипед изобретать.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.10.2018, 13:38

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

Построение графиков в Chart
Добрый день. Я программирую на Builder C++. Мне по Com-порту приходят пакеты 2-х типов. Первый...

Построение графиков f1book
Подскажите как реализовать следующую задачу. Имеется заполненная таблица excel. Необходимо...

Построение графиков функций
помогите пожалуйста, у меня есть программа построения графиков функций, но мне нужно ее переделать...

Построение графиков в Tchart
Работая в Borland Developer Studio,необходимо написать программу, чтобы при вводе любой функции в...

Построение графиков в Chart c помошью потоков
Добрый вечер уважаемые форумчане! В поисках информации по построению графиков с большим...


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

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

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