| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C++ Builder > вопросы по графику |
| Автор: gordmiand 17.6.2009, 23:02 | ||
| 1. Задача следующая – вывести на графике в заданных точках определенный текст… Я для этого беру серию типа Point (например) и хочу вывести какой-то текст в заданной точке:
Предварительно установив в свойстве данной серии чарта Marks\Style=Label Метка выводится в заданной точке (10,5), но почему вместо 10 на оси Х выводится текст метки? Как это исправить? Или как по-другому выводить текст в заданном месте на графике (в масштабе текущих координат графика)? 2. Как можно считать значение координаты, например оси Х графика, находящейся в данный момент под курсором мыши? |
| Автор: Usya 17.6.2009, 23:28 | ||||
Посмотри последний пример http://www.delphikingdom.com/asp/answer.asp?IDAnswer=56244. Там с описанием. Можно использовать и другой способ - что-то вроде:
как приведено в предыдущем примере. Все от задачи зависит |
| Автор: gordmiand 18.6.2009, 05:57 |
| спасибо за ответ....а что по поводу п.1??? |
| Автор: Usper 18.6.2009, 14:57 |
| Надо установить значение LabelStyle нужной оси чарта в talValue: Chart1->BottomAxis->LabelStyle=talValue (или в визуальном редакторе найти эту опцию). |
| Автор: gordmiand 18.6.2009, 19:14 |
| спасибо, Usper, за ответ - все верно... |
| Автор: gordmiand 18.6.2009, 19:32 | ||||
| и еще подскажите: 1. как для серии(Series2) типа Point программно задать стиль точек (надо SmallDot и Cross)? 2. рисую линию на канве графика:
а какой самый простой способ ее затереть и как сделать так, чтобы она не исчезала при прокрутке/ зумировании графика? и как сделать так, чтобы текст (
|
| Автор: Usper 19.6.2009, 08:21 | ||
| По поводу п.1: Series1->Pointer->Style=psSmallDot; Series1->Pointer->Style=psCross; А по поводу п.2 вывод на канву чарта можно написать в обработчике события Chart1AfterDraw. Причём это решит все вопросы. Например так:
|
| Автор: gordmiand 19.6.2009, 20:10 | ||||
| но мне надо рисовать по одной линиии при каждом щелчке мыши в определенном месте графика, а не все сразу после прорисовки графика... и еще: 1. почему на одной серии типа Point точки не выводятся разным стилем (обе получаются последнего типа – в примере ниже это SmallDot)? Как это исправить?
2. необходимо, чтобы при масштабировании (в обе стороны) графика метка внутри прямоугольника (как изначально на рис. слева) оставалась в нем же, а не смещались (рис. справа) …
то есть наверное надо делать пересчет координаты Y метки (сейчас 10.8)….но вот где и как…Подскажите наиболее простой способ решения такой задачки….. 3. если можно - как задать цвет только рабочей зоны графика (где есть коор-ая сетка)? |
| Автор: gordmiand 19.6.2009, 22:37 |
| по поводу п.1 - я так изначально и думал...и уже сделал... а вот что по поводу п.2 и 3??? |
| Автор: gordmiand 21.6.2009, 19:10 |
| ну подскажите как задать цвет только рабочей зоны графика (где есть коор-ая сетка)? |
| Автор: Usper 21.6.2009, 20:48 |
| Не уверен в том, что это возможно. |
| Автор: gordmiand 21.6.2009, 22:51 |
| Usper: понятно...я об этом догадывался, но все-таки надежда была...ну и ладно...этот вопрос не главный... |
| Автор: gordmiand 23.6.2009, 20:49 |
| В серии1 типа Gantt в каких единицах задается размер (Height) у рисующихся фигур (прямоугольников) и как программно считать данное свойство? (это по поводу "необходимо, чтобы при масштабировании (в обе стороны) графика метка внутри прямоугольника оставалась в нем же, а не смещались…") |
| Автор: gordmiand 24.6.2009, 21:32 |
| ну ответьте пож-та.... |
| Автор: Usper 25.6.2009, 08:39 |
| Значение этого свойства программно считывать отсюда: Series1->Pointer->VertSize. Как написано в справке, это свойство задано в "логических пикселях" не знаю что это, но похоже что эти пиксели примерно равны процентам от высоты области куда выводится график. З.Ы. кстати говоря, практически ничего из того что я Вам наотвечал я не знал до того как был задан вопрос. Всё это или ищется в справке, или додумывается самостоятельно. З.З.Ы. а зачем Вы вообще используете чарт типа Gantt? Прямоугольник можно и просто на канве нарисовать. А если уж используете, то зачем Вам выводить текст отдельно? Gantt позволяет выводить метку внутри прямоугольника. |
| Автор: gordmiand 25.6.2009, 20:50 |
| я рисую прямоугольники с помощью серий gantt, так как рисованное на канве изображение пропадает при прокрутке графика (так как нужны координатыне оси и возможность зумирования) или его масштабировании + рисунок не прокручивается вместе с прокруткой графика....графиком проще и надежнее...а выводить мне надо несколько меток - по краям прямоугольника и над ним (при масштабировании и возникает проблема - надо, чтобы метка была строго над(на) прямоугольником и в нем слева и справа по краям)...поэтому использую серию типа Point с невидимыми точками и видимыми метками... |
| Автор: Usper 26.6.2009, 08:42 |
| Так проблема решена? Для вывода всяких геометрических фигур есть стиль чарта Shapes, он же позволяет выводить и текст внутри (слева, справа) фигуры. Да, кстати, цвет рабочей зоны графика, на самом деле, меняется элементарно: Chart1->BackColor=clRed. |
| Автор: gordmiand 26.6.2009, 19:04 |
| в принципе нет...см. рисунок - надо сделать так, чтобы при масштабировании/ прокрутке графика или изменении размеров формы метки не прыгали (см. справа) а оставались как на левом рисунке... и цвет методом Chart1->BackColor=clRed не меняется...вообще ничего не происходит.....может еще какие операции нужны..... |
| Автор: Usper 29.6.2009, 08:32 | ||
| Shapes или Gantt с текстом внутри не подходят? Для закраски рабочей зоны графика попробуйте в обработчик OnBeforeDrawAxes чарта написать это:
|
| Автор: gordmiand 1.7.2009, 15:49 |
| я и использую серии типа Gantt....но мне надо вставить текст по краям внутри прямоугольника и над ним....см. рисунок из пред... моего сообщения...поэтому все метки и делаю с помощью отдельной серии и получается описанная выше проблема.... |
| Автор: Usper 2.7.2009, 08:26 |
| Из рисунка как раз понятно, что текст должен быть один, и находится он должен внутри, по центру прямоугольника. Этот прямоугольник должен быть привязан к координатам или находится просто где-то области для вывода графика? Он должен изменять размеры при изменении масштаба? |
| Автор: gordmiand 2.7.2009, 15:17 |
| текст не обязательно один и не обязательно по центру...но это не суть...главное, чтобы при масштабировании (например увеличении) чарта (а соответственно и прямоугольника) текст находился строго внутри прямоугольника и над ним (т.е. текст выводится внутри прям-ка и над его верхней "границей")...прямоугольник конечно строится по координатам... + попутно подскажите как сделать так, чтобы вне зависимости от выводимых данных и текущего масштаба графика по оси (например левой) выводились только целые числа (например 1,2,3.....10) и не было дробных отметок на оси.... |
| Автор: Usper 2.7.2009, 15:37 |
| Отменить дробные отметки можно так: Chart1->LeftAxis->Increment=1; А по-поводу прямоугольника буду думать как это нарисовать на канве. |
| Автор: Usper 2.7.2009, 16:24 | ||
Ну вот например так:
Проект на всякий случай прилагаю Это просто пример, неплохо бы сделать всё это по-красивее. Избавится от глобальных переменных например. Вывод прямоугольника и текста не проверяется на выход за границы рабочей области. Так же не проверяются габариты внутреннего текста по высоте прямоугольника. Габариты прямоугольника тоже не проверяются: Х0 должен быть левее Х1, а Y0 ниже чем Y1. |
| Автор: gordmiand 3.7.2009, 15:01 | ||
| спасибо за ответ.... 1.Подскажите как программно узнать минимальное значение текущей метки по оси (например левой) графика (но это не Chart1->LeftAxis->Minimum (на рисунке в эдитах), так как я могу прокручивать по вертикали график и надо знать минимальное значение метки по оси в данный момент времени) – см. рисунок 2. Как можно, например по кнопке, зумировать в обе стороны изображение графика с заданным масштабным коэффициентом? 2. Как вывести текст на канву графика так, чтобы он не стирался при манипуляциях с графиком(прокрутка, зумирование) и прокручивался вместе с ним… Таким образом
не получается нужный эффект – при прокрутке графика текст стирается… |
| Автор: Usper 3.7.2009, 21:52 |
| Вы мои ответы как то проверяете или просто коллекционируете? В моём предыдущем посте осуществляется вывод прямоугольника и текста и текст при прокрутке/зуме не стирается. Вывод на канву надо делать в обработчиках AfterDraw или BeforeDraw чарта или сириеса и тогда они стираться не будут. Координаты для вывода текста осуществлять с помощью CalcXPosValue(), CalcYPosValue() соответствующей оси. По пункту 1 и 2 - отвечу в понедельник, так как билдера дома нет. |
| Автор: gordmiand 5.7.2009, 22:48 |
| Usper:Ваш последний пост ott просто не проверял...заранее спасибо... буду ждать Вашего ответа на п.п. 1 и 2.... |
| Автор: Usper 6.7.2009, 08:48 |
| Как пишут в справке к компоненту, есть два метода изменения масштаба: зум по прямоугольнику (неважно как задаётся прямоугольник: с помощью мыши или программно) и зум в процентах от текущего размера рабочей области. Соответственно Chart1->ZoomPercent(50) уменьшает масштаб в два раза от текущего мастштаба, а Chart1->ZoomPercent(200) увеличивает в два раза. Chart1->UndoZoom() - устанавливает исходный масштаб (100%). А по-поводу первого пункта, я честно говоря не понял, что требуется. Что такое минимальное значение метки? |
| Автор: gordmiand 6.7.2009, 13:52 |
| спасибо, Usper, за ответ... а под понятием "минимальное значение метки" я имел ввиду минимальное значение по оси (например левой), видимое в данный момент на экране (на рисунке ранее - это примерно 7.5)...как его программно определить? (это не минимальное значение по всей оси в принципе, а минимальное в данный момент времени - то, которое видно на экране сейчас...)... |
| Автор: Usper 6.7.2009, 20:51 |
| Это именно Chart1->LeftAxis->Minimum. По-крайней мере в 2009 билдере после изменения масштаба, это значение примерно соответствует отображаемой картине. |
| Автор: gordmiand 7.7.2009, 19:15 |
| подскажите еще пож-та по чарту: 1. Как программно узнать размер (длину) выбранного пользователем участка (прямоугольника) зумирования? 2. Как программно добраться до цвета текста метки СЕРИИ (в свойствах графика- это Series_n-вкладки Marks-Text-Font-Color)? 3. Каким образом можно(?) программно поменять цвет какой-либо ОДНОЙ имеющейся метки (например метки “5”) на ОСИ графика и как их ВСЕ можно перекрасить в один цвет? (в свойствах это Chart-Axis (например TopAxis)-Labels-Text-Font-Color) |
| Автор: gordmiand 8.7.2009, 06:00 |
| очень надо...помогите плиз ответами на вопросы из моего предыдущего сообщения в данной теме....заранее спасибо всем ответившим.... |
| Автор: Usper 8.7.2009, 08:17 |
| 2. Series1->Marks->Font->Color=clGreen. 3. Покраска всех меток оси Chart1->LeftAxis->LabelsFont->Color=clGreen. |
| Автор: gordmiand 8.7.2009, 10:57 | ||
| спасибо, Usper, за ответы...еще хотелось бы получить ответ на первую часть п.3 (про цвет ОДНОЙ конкретной метки)...... но мне главное решить п.1 (про программное определение длины прям-ка зумирования)....не подскажете способ их решения? и еще:
почему половина МЕТОК не окрашивается в синий цвет, а все выводится зеленым? (методы Repaint(); Refresh() не помогают…) а с окраской ТОЧЕК графика проблем нет… +как программно добраться до заданной метки (например “5”) на ОСИ графика? мне нужно ее (и только ее !!!) покрасить в произвольный цвет… |
| Автор: gordmiand 12.7.2009, 18:22 |
| неужели нельзя выводить на одной серии графика метки разного цвета (или прямоугольники заданных цветов на серии типа Gantt)??? подскажите как это сделать программно....... |
| Автор: Usper 13.7.2009, 08:05 |
| А что в этом удивительного? Не могут же разработчики предусмотреть всё. Надо это реализовывать вручную. А в чём загвоздка с выводом разноцветных прямоугольников на сириес типа Gantt? |
| Автор: gordmiand 13.7.2009, 21:48 |
| то есть все-таки нельзя выводить метки разного цвета на одной серии? а что в Вашем понятии означает "реализовывать вручную"? например создавать динамически сириесы и для каждого из них указывать свой цвет меток? или можно как-то проще решить данную проблему? и при сириесе типа Gantt не получается выводить заданным цветом токо один выбранный прямоугольник (подскажите код...) |
| Автор: Usper 14.7.2009, 08:19 |
| Что-то я уже запутался в терминологии. Метки по-английски как называются? Marks? Простыми способами изменить цвет одной такой метки для серии не получится. Как это реализовать - не знаю. А про Gantt опять ничего не понял. Требуется вывести прямоугольники для Gantt разных цветов? В чём проблема? Series1->AddGanttColor(-1,2,4,"Метка",clRed). |
| Автор: gordmiand 14.7.2009, 20:21 | ||
| понятно...такого метода (AddGanttColor) я не знал.... подскажите еще: 1. можно ли (как именно?) на ОДНОМ чарте вывести ДВЕ оси TopAxis (и одну LeftAxis)… график строится без участия второй Top-оси.. она используется для визуализации других единиц измерения данных, нежели по первой Top-оси… 2. мне надо нарисовать ломаную линию вида “|_|”:
1 вариант – рисование слева направо (все верно рисуется), 2 – справа налево - фигура перевернута…. Почему так происходит (ведь если строить по точкам, то все должно быть верно) и как это исправить??? |
| Автор: Usper 15.7.2009, 12:44 | ||
| Две оси TopAxis вывести не получится, но можно воспользоваться событием OnGetAxisLabel для коррекции выводимого значения на ось (подправить можно только само значение, но не цвет). А фигура переворачивается потому что TChart по-умолчанию сортирует выводимые точки по возрастанию. Выключение сортировки:
|
| Автор: gordmiand 15.7.2009, 21:07 | ||
| спасибо за ответ про рисование ломаной линии... по п.1 хотел бы уточнить:
Подскажите как программно с помощью события OnGetAxisLabel можно поменять все выведенные только на Top-ось данные-метки (i) на другие (массив m) или только несколько значений изменить (например метки № 3,4,5 на Top-оси)??? хотелось бы получить эффект такой, что график строится по одним данным, а подписи по одной из осей (Top-ось) были другие... |
| Автор: Usper 16.7.2009, 08:25 | ||
Как я понимаю, метки на ось выводятся динамически и заранее нет никакого списка меток потому что заранее невозможно понять сколько меток будет выводится и в каком диапазоне. Поэтому доступа по индексу к метке нет. Есть доступ только по значению. Перед тем, как метка выведется, срабатывает событие OnGetAxisLabel. И уже в обработчике события надо проверить чему равен LabelText и если требуется, подправить это значение.
Этот пример отслеживает метку "5" и заменяет её на "5+". Условия Sender->Horizontal && Sender->OtherSide определяют является ли текущая ось верхней осью. Наверное можно опредлить текущую ось как-нибудь поизящнее. |
| Автор: gordmiand 16.7.2009, 20:31 | ||||||||
| По методу Chart1GetAxisLabel у меня опять несколько вопросов: 1. в ButtonClick():
в Chart1GetAxisLabel:
почему метка “1600” не меняется на “hello”??? (как такую замену осуществить???) ведь такая метка есть на Top-оси….см.рис. …а если в коде все сократить например на 10 или в условии поставить “==600” или “==800” (эти метки тоже есть на графике) – все нормально проходит…то есть я так понимаю, что метка на оси “1 600” и “1600” – не одно и тоже…но если я в условии ставлю “ ..==”1 600” ” – это тоже не помогает… как же тогда быть??? 2.
мне надо вместо текущих меток (m[i]) по Top-оси проставить метки массива mas…то есть каждому i-му элементу массива m соответствует свой i-ый элемент массива mas…: я пытаюсь так:
} 3. Как использовать параметр ValueIndex из Chart1GetAxisLabel? может для моих целей его как-то получится применить… |
| Автор: Usper 17.7.2009, 08:38 | ||||
| Проверка на нужную ось: if(Sender==Chart1->TopAxis... Метки на ось выводятся в формате, записанном в свойстве AxisValuesFormat для кажой оси. Поэтому сравнивать значения, на самом деле, надо так:
По-поводу пункта 2, вроде всё логично, но я не вижу что происходит после сравнения if (LabelText==m[i]) LabelText=mas[i]; по идее после этой строчки надо завершить цикл... По-поводу пункта 3:
|
| Автор: gordmiand 17.7.2009, 11:02 |
| по п.2 - все верно - после if (LabelText==m[i]) LabelText=mas[i]; цикл и завершается (что и написано в пред. моем сообщении вне выделенного кода проги).... вообще задача такая: int a[11]={0, 1.23, 4.32, 6.75, 8.66, 9, 11, 12.44, 13.55, 14, 16.2}; при построении этих данных по ОХ (массив a), не важно с каким OY, шкала ОХ градуируется целыми значениями-метками - т.е. для этой Top-оси Labels->Style=Auto (или Value)... мне надо эти выведенные целые метки заменить на соответствующие значения из массива b[]: AnsiString b[11]={"0", "A", "A","B","b","C","C","H","H","D","D"}; - i-му элементу из данного массива b соответствует i-ый элемент из массива a... |
| Автор: Usper 17.7.2009, 12:00 | ||
То есть после выполнения этого кода
стираются все метки? Или строчка else LabelText=""; всё-таки раскоментирована? |
| Автор: gordmiand 17.7.2009, 22:17 |
| да, все метки стираются при откомментированной строке else.... правда непонятно почему так происходит...то есть явно надо как-то обращаться к каждой имеющейся метке...и обязательно ли метки надо заменять в соотношении 1:1 - то есть например 5 меток заменяются на 5 других или нет? |
| Автор: Usper 18.7.2009, 22:04 |
| Я так и не понял, строка с else закоментирована или нет. Если эта строка не закоментирована то тогда всё ясно... |
| Автор: gordmiand 19.7.2009, 18:10 |
| строка с else НЕ ЗАКОММЕНТИРОВАНА...- и тогда ВСЕ метки становятся почему-то пустыми ("")...как быть? |
| Автор: Usper 19.7.2009, 18:43 | ||
Тогда всё ясно. Как только срабатывает обработчик, значение метки в первом проходе цикла сравнивается с m[1], если значение метки не равно m[1], метке присваивается пустое значение. Во втором проходе цикла значение метки уже равно пустой строке, и эта пустая строка сравнивается с m[2], если m[2] не равное пустой строке (а очевидно, что так и есть), то метке опять присваивается пустая строка. И так 10 раз. Однако, если волшебным образом при первом проходе метка будет равна m[1], то второй проход цикла всё равно выполнится и метке присвоится значение "". Таким образом этот цикл в любом случае присовит метке пустую строку. Цикл надо подправить:
Я модернизировал готовый пример, но с нуля я бы написал, что-нибудь другое. |
| Автор: Usper 19.7.2009, 22:06 |
| Поправил предыдущий пост. |
| Автор: gordmiand 19.7.2009, 22:15 |
| понятно....а что именно другое Вы написали бы с нуля? |
| Автор: Usper 20.7.2009, 07:50 |
| Да нет, и так сойдёт |
| Автор: gordmiand 20.7.2009, 10:19 | ||
на малых числах метки выводятся верно…а при больших значениях (см. инициализацию массива m[i]) – нет (пропадают метки по обеим (???) осям- см. рисунок)…..почему так происходит и как это исправить? |
| Автор: Usper 20.7.2009, 13:15 | ||
А... ну да, надо код после условия в блок поместить:
Но это влияет только на отображение меток на остальных осях... У меня при заданных значениях (от 7500 до 8000) метки выводятся. Правда нестабильно, чуть изменил масштаб и они могут пропасть. |
| Автор: gordmiand 20.7.2009, 21:41 | ||
| и? взятие в { } кода из Chart1GetAxisLabel дает только простановку меток по LeftAxis...TopAxis все равно пуста.... как же так? а также допустим:
мне надо выводить только разные метки из массива mas[] на top-ось...т.е. не должно быть двух меток A, A и т.п. как это сделать??? |
| Автор: gordmiand 21.7.2009, 12:30 |
| Usper: подскажите пож-та...см. предыдущее мое сообщение... |
| Автор: gordmiand 21.7.2009, 21:14 |
| так все-таки - почему при использовании последнего из приведенных в данном посте кода Usper-a вообще не выводятся метки на Top-ось? |