Произвольные подписи на оси в AСhart

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Произвольные подписи на оси в AСhart

Сообщение Nik » 05.09.2010 23:27:20

Использую TAchart для вывода статистических данных, привязанных к датам. С формированием самой диаграммы (BarSeries) проблем нет - там всё проще некуда. Но вот с подписями возникла проблема. Никак не могу понять, можно ли сделать произвольные подписи на оси Y (например так, как на нижнем рисунке во вложении). В идеале каждая подпись должна жёстко привязываться к "своей" линейке на диаграмме.
Кто-нибудь делал подобные вещи?
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
Nik
энтузиаст
 
Сообщения: 573
Зарегистрирован: 04.02.2006 00:08:09
Откуда: Киров

Re: Произвольные подписи на оси в AСhart

Сообщение dunin » 07.09.2010 08:42:27

Ну вот вроде что-то подобное
1.jpg

У диаграммы есть оси. У оси событие OnMarkToText как-то так...
Код: Выделить всё
...
DataChart.AxisList.Axes[1].OnMarkToText...
...
procedure TFulForm.DataChartAxisList1MarkToText(var AText: String; AMark: Double);
begin
  AText:= DateToStr(AMark);
end;
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
dunin
энтузиаст
 
Сообщения: 634
Зарегистрирован: 02.05.2007 13:18:11
Откуда: Тољя††и

Re: Произвольные подписи на оси в AСhart

Сообщение Nik » 07.09.2010 19:34:42

dunin писал(а):Ну вот вроде что-то подобное
У диаграммы есть оси. У оси событие OnMarkToText как-то так...
Код: Выделить всё
...
...
  AText:= DateToStr(AMark);


Самое оно. Спасибо за наводку! :)
Аватара пользователя
Nik
энтузиаст
 
Сообщения: 573
Зарегистрирован: 04.02.2006 00:08:09
Откуда: Киров

Re: Произвольные подписи на оси в AСhart

Сообщение Ask » 09.09.2010 18:13:02

Для частного случая работы с датами можно использовать также свойство Axis.Marks.Source и компонент DateTimeIntervalChartSource,
пример см. в axisdemo, закладки "Customized marks" и "Date and time".

Конечно, OnMarkToText -- это самый общий случай, хоть обработчик и не сохраняется :)
Ask
постоялец
 
Сообщения: 163
Зарегистрирован: 25.12.2008 03:51:37

Re: Произвольные подписи на оси в AСhart

Сообщение Nik » 09.09.2010 21:32:04

DateTimeIntervalChartSource пытался приспособить, но больно он мутный - а лишний огород городить я не люблю, баги потом ловить геморнее :) OnMarkToText идеально подошёл - всего пару строк кода дописать понадобилось (не считая ручного присвоения функции OnMarkToText в RunTime :) )
Аватара пользователя
Nik
энтузиаст
 
Сообщения: 573
Зарегистрирован: 04.02.2006 00:08:09
Откуда: Киров

Re: Произвольные подписи на оси в AСhart

Сообщение VAshot » 23.01.2011 15:29:45

OnMarkToText нормальный вариант, но возникают проблемы, когда шаг между подписями меньше в пикселях, чем ширина самой подписи.
В своё время, еще на очень старой реализации сделал модифицированные чарты для специфических задач. Примерно вот так (для даты):

формирование самой подписи к значению
Код: Выделить всё
                        if FBottomAxis.Title.AxisType = atDateTime then begin     
                          if (FXGraphMax-FXGraphMin) < 3600 then       
                            DateTimeToString(MyText, 'dd.mm.yy hh:mm:ss', CalcDateTime(Marque))
                          else                                                             
                            DateTimeToString(MyText, 'dd.mm.yy hh:mm', CalcDateTime(Marque));
                        end;
                        if FBottomAxis.Title.AxisType = atDate then           
                          DateTimeToString(MyText, 'dd.mm.yyyy', CalcDateTime(Marque));

                        if FBottomAxis.Title.AxisType = atTime then
                          DateTimeToString(MyText, 'hh:mm:ss', CalcDateTime(Marque));

                        if FBottomAxis.Title.AxisType = atNormal then
                          MyText:=Trim(FloatToStr(Marque));


и изменения шага для аккуратности
Код: Выделить всё
      ACanvas.Pen.Assign(FBottomAxis.Grid);                                         
         XGraphToImage(Debut+Pas,   tP1);                                           
         XGraphToImage(Debut+2*Pas, tP2);                                             
         if FBottomAxis.Title.AxisType = atDateTime then                           
           if (FXGraphMax-FXGraphMin) < 3600 then                                 
             dt := ACanvas.TextWidth('00.00.00 00:00:00')                             
           else                                                                       
             dt := ACanvas.TextWidth('00.00.00 00:00');                               
         if FBottomAxis.Title.AxisType = atDate then                                 
           dt := ACanvas.TextWidth('00.00.00');                                     
         if FBottomAxis.Title.AxisType = atTime then                                 
           dt := ACanvas.TextWidth('00:00:00');                                     
         if FBottomAxis.Title.AxisType <> atNormal then                           
           if dt > (tP2-tP1)*0.8 then                                               
              while dt > (tP2-tP1)*0.8 do begin                                       
                Pas := Pas*1.5;                                                       
                XGraphToImage(Debut+Pas,   tP1);                                 
                XGraphToImage(Debut+2*Pas, tP2);                                     
              end;                                     
         Marque:=Debut;


В современной реализации компонента как-то можно повлиять на шаг между подписями?

И что касается подписей, было бы не плохо иметь возможность двухстрочных...

Добавлено спустя 3 часа 34 минуты 22 секунды:
Нашел OverlapPolice.... Актуальность вопроса резко уменьшилась, но не отпала.
Аватара пользователя
VAshot
постоялец
 
Сообщения: 128
Зарегистрирован: 01.11.2007 12:31:21
Откуда: Пермь

Re: Произвольные подписи на оси в AСhart

Сообщение Ask » 24.01.2011 06:38:22

VAshot писал(а):В современной реализации компонента как-то можно повлиять на шаг между подписями?


Напрямую влиять на шаг в пикселях нельзя, хотя мысль, конечно, правильная.
Надо подумать над интерфейсом и реализацией, если есть предложения -- welcome.
Можно произвольно привязать метки к значениям координаты (в мировой системе)
с помощью свойства Source.
Можно воспользоваться TDateTimeIntervalChartSource, который автоматически
подбирает шаг изменения даты в соответствии с текущим масштабом, см. axisdemo.
Правда, он тоже пиксели не учитывает.

VAshot писал(а):И что касается подписей, было бы не плохо иметь возможность двухстрочных..


Добавлю, надо только придумать интерфейс -- как указать, сколько в подписи строк и где её разбивать?
Например, как это сделно в Delphi?
Для axis.Title можно сделать из Caption StringList, хотя это нарушит совместимость,
а вот что для Marks делать?
Ask
постоялец
 
Сообщения: 163
Зарегистрирован: 25.12.2008 03:51:37

Re: Произвольные подписи на оси в AСhart

Сообщение VAshot » 24.01.2011 07:10:13

Можно воспользоваться TDateTimeIntervalChartSource, который автоматически
подбирает шаг изменения даты в соответствии с текущим масштабом, см. axisdemo.

Смотрел его, даже не учитывая, что проблема эта и там, уж очень для специфических задач штука, для обычных - показалось бредовым вариантом)
OnMarkToText гибче, всё равно писать ручками.

Можно произвольно привязать метки к значениям координаты (в мировой системе)
с помощью свойства Source.

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

а вот что для Marks делать?

На мой взгляд, всё очень просто, разбивать по общепринятым "#13#10" или "\n".
Сложнее с реализацией, осей-то сейчас может быть несколько рядом, и высота их может быть разная.
Title можно так же. Для простоты, можно ограничится одним или двумя разрывами, хотя не суть.

Например, как это сделно в Delphi?

Не могу сказать, последний раз с ним работа года три назад, а с графиками лет 6-7 и то примитивными.


Да, маленький глюк нашел: http://bugs.freepascal.org/view.php?id=18594.
Аватара пользователя
VAshot
постоялец
 
Сообщения: 128
Зарегистрирован: 01.11.2007 12:31:21
Откуда: Пермь

Re: Произвольные подписи на оси в AСhart

Сообщение Ask » 24.01.2011 13:06:11

VAshot писал(а):
...TDateTimeIntervalChartSource...
Смотрел его, даже не учитывая, что проблема эта и там, уж очень для специфических задач штука, для обычных - показалось бредовым вариантом)
OnMarkToText гибче, всё равно писать ручками.


Основная задача -- сделать, чтобы разумно работало масштабирование на оси с датами, особенно при широком интервале значений масштаба.

VAshot писал(а):
...свойства Source...
Не совсем понял, поясните пожалуйста.


Можно конкретно указать координаты (не в пикселях, а на оси), где будут расположены метки.
См. axisdemo, страницу Customized marks.

VAshot писал(а):
На мой взгляд, всё очень просто, разбивать по общепринятым "#13#10" или "\n".
Сложнее с реализацией, осей-то сейчас может быть несколько рядом


Да нет, у меня там сейчас всё модульно, так что реализация элементарная.
Я не уверен, насколько переносимо разбиение на строки с помощью DrawText,
так что разбил руками. См. закладку Multiline в labelsdemo начиная с ревизии 29184.
Должно сразу работать и на axis, и на series, и на title.

VAshot писал(а):
Да, маленький глюк нашел: http://bugs.freepascal.org/view.php?id=18594.


Исправил. Please test and close if ok -- Я его номинирую для бэкпорта в 0.9.30.
Ask
постоялец
 
Сообщения: 163
Зарегистрирован: 25.12.2008 03:51:37

Re: Произвольные подписи на оси в AСhart

Сообщение VAshot » 24.01.2011 14:58:29

Ask писал(а):Основная задача -- сделать, чтобы разумно работало масштабирование на оси с датами, особенно при широком интервале значений масштаба.

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

Ask писал(а):Можно конкретно указать координаты (не в пикселях, а на оси), где будут расположены метки.

Полезно, но как быть с перекрывающими друг друга записями, исключать?
Аватара пользователя
VAshot
постоялец
 
Сообщения: 128
Зарегистрирован: 01.11.2007 12:31:21
Откуда: Пермь

Re: Произвольные подписи на оси в AСhart

Сообщение Little_Roo » 28.01.2011 16:48:49

Ask писал(а):Конечно, OnMarkToText -- это самый общий случай, хоть обработчик и не сохраняется :)

А как можно вывести из базы данных столбчатую диаграмму (желательно горизонтальную), чтобы на оси Y выводились фамилии (...FieldByName('FAM').AsString, а по Х - число (...FieldByName('BALL').AsFloat ?
Пробовал DbChartSource, но он ругается на строковое поле ...Да и получилось только вертикальную диаграмму, и на каждый столбец диаграммы выводил последнюю фамилию из выборки :(
Я понимаю, что у меня и лыжи не едут, и.... :oops:
Ткните носом - в Delphi это легко реализовывалось....

Lazarus 0.9.31 r29190 FPC 2.4.3 i386-win32-win32/win64
Аватара пользователя
Little_Roo
энтузиаст
 
Сообщения: 639
Зарегистрирован: 27.02.2009 19:56:36
Откуда: Санкт-Петербург

Re: Произвольные подписи на оси в AСhart

Сообщение Ask » 28.01.2011 19:14:06

Little_Roo писал(а):столбчатую диаграмму (желательно горизонтальную)


См. rotatedemo

Little_Roo писал(а):чтобы на оси Y выводились фамилии ...FieldByName('FAM').AsString


Установи FieldText='FAM', ну и дальше стиль меток smsLabel или аналогичный

Добавлено спустя 3 минуты 14 секунд:
VAshot писал(а):Возможно не разобрался, но при увеличении видны только дни, а в каком месяце и году? Не хватает настроек по формату отображения для каждого этапа увеличения.

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

VAshot писал(а):
Ask писал(а):Можно конкретно указать координаты (не в пикселях, а на оси), где будут расположены метки.

Полезно, но как быть с перекрывающими друг друга записями, исключать?


Пока да. В перспективе есть план сделать опцию "сдвинуть", но это требует существенных архитектурных изменений.
Ask
постоялец
 
Сообщения: 163
Зарегистрирован: 25.12.2008 03:51:37

Re: Произвольные подписи на оси в AСhart

Сообщение Little_Roo » 29.01.2011 01:00:25

Ask писал(а):
Little_Roo писал(а):столбчатую диаграмму (желательно горизонтальную)

См. rotatedemo


За подсказку БОЛЬШОЙ тнх :D
Но поворот диаграммы пока не прошел - ну это видимо Я дурак...
А вот для придурков :oops: типа меня - в опциях чарта можно ли сделать галку - вертикальная диаграмма (по дефолту) или горизонтальная ?
Прошу пардону, но наследия дельфей за штаны кусают :(
Аватара пользователя
Little_Roo
энтузиаст
 
Сообщения: 639
Зарегистрирован: 27.02.2009 19:56:36
Откуда: Санкт-Петербург

Re: Произвольные подписи на оси в AСhart

Сообщение Ask » 29.01.2011 05:33:01

Little_Roo писал(а):Но поворот диаграммы пока не прошел

Установи у BarSeries свойства:
AxisIndexX = 0
AxisIndexY = 1

Little_Roo писал(а):в опциях чарта можно ли сделать галку - вертикальная диаграмма

В принципе можно, но не хочется -- избыточно и может привести к путанице.
Лучше сделать что-то типа Wizard с наиболее частыми задачами.
Или написать наконец документацию :-)

P.S. Сорри за поучение, но Я преподаватель, удержаться трудно:
сообщать "Я дурак" бесполезно, лучше скажи конкретно, что пробовал сделать и что не получилось.
Ask
постоялец
 
Сообщения: 163
Зарегистрирован: 25.12.2008 03:51:37

Re: Произвольные подписи на оси в AСhart

Сообщение Little_Roo » 29.01.2011 20:17:54

Ask писал(а):
Little_Roo писал(а):в опциях чарта можно ли сделать галку - вертикальная диаграмма

В принципе можно, но не хочется -- избыточно и может привести к путанице.
Лучше сделать что-то типа Wizard с наиболее частыми задачами.
Или написать наконец документацию :-)

Сделать Wizard - по принципу и по подобию TeeChart - это великая вещь - особенно если часть настроек под выбранную тему сразу ставить по нужному дефолту, а не нужные скрывать нафиг :D
Вот тогда AChart станет просто супер компонентом (главное, чтоб НЕ стал коммерческим) :D

Ask писал(а):P.S. Сорри за поучение, но Я преподаватель, удержаться трудно:
сообщать "Я дурак" бесполезно, лучше скажи конкретно, что пробовал сделать и что не получилось.

Увы мне, я тоже учитель :oops: И из семьи оных :shock: И отец, и мама, и жена....
Вот мой папа и заявляет - "Тот, кто говорит, что он дурак, то он уже не дурак, а самокритичная личность" :D :D :D

А вот как сделать бы клонирование серии - т.е. настроил одну серию (а их нужно штук ...дцать) - и менять только те свойства, которые только в данной серии меняются....
(ну это я уж в будущее смотрю) :D
Аватара пользователя
Little_Roo
энтузиаст
 
Сообщения: 639
Зарегистрирован: 27.02.2009 19:56:36
Откуда: Санкт-Петербург

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 42

Рейтинг@Mail.ru
cron