Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > вопросы по графику


Автор: gordmiand 17.6.2009, 23:02
1. Задача следующая – вывести на графике в заданных точках определенный текст…
Я для этого беру серию типа Point (например) и хочу вывести какой-то текст в заданной точке:

Код

Series1->AddXY(10, 5 ,  "привет", clBlue);

 
Предварительно установив в свойстве данной серии чарта Marks\Style=Label 

Метка выводится в заданной точке (10,5), но почему вместо 10 на оси Х выводится текст метки? Как это исправить? Или как по-другому выводить текст в заданном месте на графике (в масштабе текущих координат графика)?

2. Как можно считать значение координаты, например оси Х графика, находящейся в данный момент под курсором мыши?

Автор: Usya 17.6.2009, 23:28
Цитата

2. Как можно считать значение координаты, например оси Х графика, находящейся в данный момент под курсором мыши?

Посмотри последний пример http://www.delphikingdom.com/asp/answer.asp?IDAnswer=56244. Там с описанием.

Можно использовать и другой способ - что-то вроде:
Код

XValue=Chart1->BottomAxis->CalcPosPoint(X);
YValue=Chart1->BottomAxis->CalcPosPoint(Y);

как приведено в предыдущем примере.
Все от задачи зависит smile 

Автор: 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. рисую линию на канве графика:

Код

    Chart1->Canvas->MoveTo(100,0);
    Chart1->Canvas->LineTo(120,500);

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


и как сделать так, чтобы текст (
Код
Chart1->Canvas->TextOutA(100,100,"hello");

) выводился вместе с построением графика (а то текст токо мигает и пропадает...)? 

Автор: Usper 19.6.2009, 08:21
По поводу п.1:
Series1->Pointer->Style=psSmallDot;
Series1->Pointer->Style=psCross;
А по поводу п.2 вывод на канву чарта можно написать в обработчике события Chart1AfterDraw. Причём это решит все вопросы. Например так:
Код

bool f;
f=true;

void __fastcall TForm1::Chart1AfterDraw(TObject *Sender)
{
    if(f) /если f==true то выводим на канву чарта всё что надо
    {
        Chart1->Canvas->MoveTo(30,30);
        Chart1->Canvas->LineTo(50,60);
    }
}
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    f=!f;   //инвертируем значение f
    Chart1->Repaint(); //перерисовываем чарт
}

Автор: gordmiand 19.6.2009, 20:10
но мне надо рисовать по одной линиии при каждом щелчке мыши в определенном месте графика, а не все сразу после прорисовки графика...


и еще:

1. почему на одной серии типа Point точки    не выводятся    разным стилем (обе получаются последнего типа – в примере ниже  это SmallDot)? Как это исправить?
Код

     Series1->Pointer->Style=psCross;
     Series1->AddXY(100,100,"м1", clBlack);

   Series1->Pointer->Style=psSmallDot;
   Series1->AddXY(200,100, "м2",clBlack);     


2. необходимо, чтобы при масштабировании (в обе стороны) графика метка внутри прямоугольника (как изначально на рис. слева) оставалась в нем же, а не смещались (рис. справа) …
Код

  Series1->AddGantt(200, 300,    11,          "");
  Series3->AddXY(250,              10.8,       "hello", clBlack);       // серия типа Point

то есть наверное надо делать пересчет координаты Y метки (сейчас 10.8)….но вот где и как…Подскажите наиболее простой способ решения такой задачки…..

3. если можно - как задать цвет только рабочей зоны графика (где есть коор-ая сетка)?


Автор: Usper 19.6.2009, 21:32
Цитата(gordmiand @  19.6.2009,  21:10 Найти цитируемый пост)
но мне надо рисовать по одной линиии при каждом щелчке мыши в определенном месте графика, а не все сразу после прорисовки графика...

И что же? Я подсказал способ, а конкретная реализация за Вами.

Цитата(gordmiand @  19.6.2009,  21:10 Найти цитируемый пост)
почему на одной серии типа Point точки    не выводятся    разным стилем

Это вопрос к разработчикам. Этот компонент не был рассчитан на подобное использование, Point - это один из стилей вывода графика. Если надо использовать два разных стиля - используйте два сириеса Point с разными стилями, если надо много стилей - это уже проблема  smile.

Автор: 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 чарта написать это:
Код

Chart1->Canvas->Brush->Color=clYellow;
Chart1->Canvas->FillRect(Chart1->ChartRect);

Автор: 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
Ну вот например так:
Код

int X0,Y0,X1,Y1;
AnsiString TopText,LeftText,RightText,InnerText;

void __fastcall TForm1::Chart1AfterDraw(TObject *Sender)
{
    int XL,YL,XR,YR; //координаты прямоугльника на канве
    XL=Chart1->BottomAxis->CalcXPosValue(X0); //пересчёт координат на графике в координаты на канве
    YL=Chart1->LeftAxis->CalcYPosValue(Y0);
    XR=Chart1->BottomAxis->CalcXPosValue(X1);
    YR=Chart1->LeftAxis->CalcYPosValue(Y1);
    Chart1->Canvas->Rectangle(XL,YL,XR,YR);
    int InnerTextX, InnerTextY, InnerTextWidth;
    InnerTextWidth=Chart1->Canvas->TextWidth(InnerText);
    if(InnerTextWidth<(XR-XL)) //если текст не влезает по-горизонтали - то и не выводим
    {
        InnerTextX=XL+(XR-XL)/2-InnerTextWidth/2; //рассчёт координаты Х для внутреннего текста
        InnerTextY=YL+(YR-YL)/2-Chart1->Canvas->TextHeight(InnerText)/2;
        Chart1->Canvas->TextOutA(InnerTextX,InnerTextY,InnerText);
    }
    int LeftTextX,LeftTextY;
    LeftTextY=YL+(YR-YL)/2-Chart1->Canvas->TextHeight(LeftText)/2;
    LeftTextX=XL-Chart1->Canvas->TextWidth(LeftText)-2;
    Chart1->Canvas->TextOutA(LeftTextX,LeftTextY,LeftText);
}


Проект на всякий случай прилагаю
Это просто пример, неплохо бы сделать всё это по-красивее. Избавится от глобальных переменных например. Вывод прямоугольника и текста не проверяется на выход за границы рабочей области. Так же не проверяются габариты внутреннего текста по высоте прямоугольника.
Габариты прямоугольника тоже не проверяются: Х0 должен быть левее Х1, а Y0 ниже чем Y1.

Автор: gordmiand 3.7.2009, 15:01
спасибо за ответ....

1.Подскажите как программно узнать минимальное значение текущей метки по оси (например левой) графика (но это не Chart1->LeftAxis->Minimum (на рисунке в эдитах), так как я могу прокручивать по вертикали график и надо знать минимальное значение метки по оси в данный момент времени) – см. рисунок

2. Как можно, например по кнопке, зумировать в обе стороны изображение графика с заданным масштабным коэффициентом?

2. Как вывести текст на канву графика так, чтобы он не стирался при манипуляциях с графиком(прокрутка, зумирование) и прокручивался вместе с ним…

Таким образом
  
Код

 Chart1->Repaint();
 Chart1->Canvas->TextOutA(100,100,"hello");

не получается нужный эффект – при прокрутке графика текст стирается…

Автор: 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 (про программное определение длины прям-ка зумирования)....не подскажете способ их решения?


и еще:
Код

TColor cvet;
 for (int i=1; i<=10; i++)
    {
        if  (i<=5) cvet=clBlue; else cvet=clGreen;
        Series1->Marks->Font->Color=cvet;
        Series1->AddXY(i, i+2, i, cvet);
    } 

почему половина МЕТОК не окрашивается в синий цвет, а все выводится зеленым? (методы 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
   Series1->AddXY(5, 17, "", clBlack);
   Series1->AddXY(5, 0.5, "", clBlack);
   Series1->AddXY(10, 0.5, "", clBlack);
   Series1->AddXY(10, 17, "", clBlack);

///////////////////////////////////////////////////////////////////////////
//2    
     Series1->AddXY(10, 17, "", clBlack);
     Series1->AddXY(10, 0.5, "", clBlack);
     Series1->AddXY(5, 0.5, "", clBlack);
     Series1->AddXY(5, 17, "", clBlack);


1 вариант – рисование слева направо (все верно рисуется), 2 – справа налево - фигура перевернута…. Почему так происходит (ведь если строить по точкам, то все должно быть верно) и как это исправить???

Автор: Usper 15.7.2009, 12:44
Две оси TopAxis вывести не получится, но можно воспользоваться событием OnGetAxisLabel для коррекции выводимого значения на ось (подправить можно только само значение, но не цвет).
А фигура переворачивается потому что TChart по-умолчанию сортирует выводимые точки по возрастанию. Выключение сортировки:
Код

Series1->XValues->Order=loNone;
Series1->YValues->Order=loNone;

Автор: gordmiand 15.7.2009, 21:07
спасибо за ответ про рисование ломаной линии...
по п.1 хотел бы уточнить:

Код

int m[11]={0, 11, 22, 33, 44, 55, 66, 77, 88, 99, 100};

  for (int i=1; i<= 10 ; i++)
   Series1->AddXY(i, 2+i, "", clBlack);


Подскажите как программно с помощью события OnGetAxisLabel можно поменять все выведенные только на Top-ось данные-метки (i) на другие (массив m) или только несколько значений изменить (например метки № 3,4,5 на Top-оси)??? хотелось бы получить эффект такой, что график строится по одним данным, а подписи по одной из осей (Top-ось) были другие...

Автор: Usper 16.7.2009, 08:25
Как я понимаю, метки на ось выводятся динамически и заранее нет никакого списка меток потому что заранее невозможно понять сколько меток будет выводится и в каком диапазоне. Поэтому доступа по индексу к метке нет. Есть доступ только по значению. Перед тем, как метка выведется, срабатывает событие OnGetAxisLabel. И уже в обработчике события надо проверить чему равен LabelText и если требуется, подправить это значение.
Код

void __fastcall TForm1::Chart1GetAxisLabel(TChartAxis *Sender,
      TChartSeries *Series, int ValueIndex, AnsiString &LabelText)
{
    if(Sender->Horizontal && Sender->OtherSide && LabelText=="5")
        LabelText="5+";
}


Этот пример отслеживает метку "5" и заменяет её на "5+". Условия Sender->Horizontal && Sender->OtherSide определяют является ли текущая ось верхней осью. Наверное можно опредлить текущую ось как-нибудь поизящнее.

Автор: gordmiand 16.7.2009, 20:31
По методу Chart1GetAxisLabel у меня опять несколько вопросов:
1.      
в ButtonClick(): 
Код

for (i=500; i<=3500  ; i+=500)
    Series1->AddXY(i, 15+i, "", clBlack);


в Chart1GetAxisLabel:
Код

if(Sender->Horizontal && LabelText=="1600") LabelText="hello"; 

почему метка “1600” не меняется на “hello”??? (как такую замену осуществить???) ведь такая метка есть на Top-оси….см.рис. …а если в коде все сократить например на 10 или в условии поставить “==600” или “==800” (эти метки тоже есть на графике) – все нормально проходит…то есть я так понимаю, что метка на оси “1 600” и  “1600” – не одно и тоже…но если я в условии ставлю “ ..==”1 600” ” – это тоже не помогает… как же тогда быть???


2.
Код

AnsiString mas[20]={0,"A","B","C","D","E","F","G","H","I","J" };
 int m[20];

в ButtonClick(): 
{  int i=0, k=0;

  for (i=750; i<=800  ; i+=5)
  {    k++;    m[k]=i;      }

      for (i=1; i<=10  ; i++)
      Series1->AddXY(m[i], 15+i, "", clBlack);
}


мне надо вместо текущих меток (m[i]) по Top-оси проставить метки массива mas…то есть каждому i-му элементу массива m соответствует свой i-ый элемент массива mas…:
я пытаюсь так:
Код

в Chart1GetAxisLabel:
  if(Sender->Horizontal)   
 for (int i=1; i<=10  ; i++) 
     {
       if (LabelText==m[i]) LabelText=mas[i];

          // else  LabelText="";
  - а остальные метки я хочу “убрать”, но по этой строке “убираются” все метки…у меня Increment для Top-оси=0, минимум и максимум для данной оси задаются программно…(для Top-оси  Labels->Style=Auto)
      } 

3. Как использовать параметр ValueIndex из Chart1GetAxisLabel? может для моих целей его как-то получится  применить… 

Автор: Usper 17.7.2009, 08:38
Проверка на нужную ось: if(Sender==Chart1->TopAxis...
Метки на ось выводятся в формате, записанном в свойстве AxisValuesFormat для кажой оси. Поэтому сравнивать значения, на самом деле, надо так:
Код
if(Sender==Chart1->TopAxis && LabelText==FormatFloat(Chart1->TopAxis->AxisValuesFormat,1500))
        LabelText="Hello";

По-поводу пункта 2, вроде всё логично, но я не вижу что происходит после сравнения if (LabelText==m[i]) LabelText=mas[i]; по идее после этой строчки надо завершить цикл...
По-поводу пункта 3:
Цитата
There are two different uses for OnGetAxisLabel:
1) :  Axis Labels are Values. Is this case, the Series parameter will be nil, and the ValueIndex will be -1.
2) :  Axis Labels are Series points. The Series parameter will be a valid TChartSeries, and the ValueIndex will be the current Series point position. You can change the LabelText referred parameter for drawing a different Axis Label.

Автор: 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
То есть после выполнения этого кода
Код
if(Sender->Horizontal)   
 for (int i=1; i<=10  ; i++) 
     {
       if (LabelText==m[i]) LabelText=mas[i];

          // else  LabelText="";
    } 

стираются все метки? Или строчка  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], то второй проход цикла всё равно выполнится и метке присвоится значение "". Таким образом этот цикл в любом случае присовит метке пустую строку. Цикл надо подправить:
Код

void __fastcall TForm1::Chart1GetAxisLabel(TChartAxis *Sender,
      TChartSeries *Series, int ValueIndex, AnsiString &LabelText)
{
if(Sender==Chart1->TopAxis)   
 for (int i=1; i<=10  ; i++)     
       if (LabelText==m[i]) {LabelText=mas[i]; return;}            
LabelText="";
}

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

Автор: Usper 19.7.2009, 22:06
Поправил предыдущий пост.

Автор: gordmiand 19.7.2009, 22:15
понятно....а что именно другое Вы написали бы с нуля?

Автор: Usper 20.7.2009, 07:50
Да нет, и так сойдёт smile Переписать следовало код, который был до поправки. Но я уже это сделал, к тому же он не работал smile.

Автор: gordmiand 20.7.2009, 10:19
Код

AnsiString mas[20]={0,"A","B","C","D","E","F","G","H","I","J" };
int m[20], k=0;
  
for (i=7500; i<=8000  ; i+=50)
  {   k++;
     m[k]=i;     }

      for (int i=1; i<=10  ; i++)
      Series1->AddXY(m[i], 15+i, "", clBlack);



void __fastcall TForm1::Chart1GetAxisLabel(TChartAxis *Sender,
      TChartSeries *Series, int ValueIndex, AnsiString &LabelText)
{
if(Sender==Chart1->TopAxis)

  for (int i=1; i<=10  ; i++)
        if (LabelText==FormatFloat(Chart1->TopAxis->AxisValuesFormat,m[i]))

        {LabelText=mas[i]; return;}

 LabelText="";
}



на малых числах метки выводятся верно…а при больших значениях (см. инициализацию массива 
m[i]) – нет (пропадают метки по обеим (???) осям- см. рисунок)…..почему так происходит и как это исправить?








Автор: Usper 20.7.2009, 13:15
А... ну да, надо код после условия в блок поместить:
Код
void __fastcall TForm1::Chart1GetAxisLabel(TChartAxis *Sender,
      TChartSeries *Series, int ValueIndex, AnsiString &LabelText)
{
    if(Sender==Chart1->TopAxis)
    {
        for (int i=1; i<=10  ; i++)
        if (LabelText==FormatFloat(Chart1->TopAxis->AxisValuesFormat,m[i]))
        {LabelText=mas[i]; return;}
        LabelText="";
    }
}

Но это влияет только на отображение меток на остальных осях... У меня при заданных значениях (от 7500 до 8000) метки выводятся. Правда нестабильно, чуть изменил масштаб и они могут пропасть.

Автор: gordmiand 20.7.2009, 21:41
и? взятие в { } кода из Chart1GetAxisLabel дает только простановку меток по LeftAxis...TopAxis все равно пуста....  как же так? 
а также допустим:
Код

AnsiString mas[20]={0,"A","A","C","D","E","C","G","C","E","J" };

мне надо выводить только разные метки из массива mas[] на top-ось...т.е. не должно быть двух меток A, A и т.п.  как это сделать???

Автор: gordmiand 21.7.2009, 12:30
Usper: подскажите пож-та...см. предыдущее мое сообщение...

Автор: gordmiand 21.7.2009, 21:14
так все-таки - почему при использовании последнего из приведенных в данном посте кода Usper-a  вообще не выводятся метки на Top-ось?  

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)