Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2015.11.29;
Скачать: [xml.tar.bz2];

Вниз

Как делают вывод подсказок на графиках?   Найти похожие ветки 

 
pavelnk ©   (2015-04-03 14:31) [40]

А если такая идея - анализировать пиксели которые находятся под мышью и принимать решение отталкиваясь от цвета пикселя (ведь графики будут разного цвета).


 
Inovet ©   (2015-04-03 14:47) [41]

> [39] Pavelnk ©   (03.04.15 14:20)
> как оживить пиксели битмапа

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


 
Inovet ©   (2015-04-03 14:48) [42]

> [40] pavelnk ©   (03.04.15 14:31)
> А если такая идея - анализировать пиксели которые находятся под мышью

На пиксели надо забить.


 
pavelnk ©   (2015-04-03 14:49) [43]

> Inovet ©   (03.04.15 14:47) [41]
> Неправильно. Изначально не битмап, а известная закономерность.
Но всё равно ж на битмапе, так какая разница?


 
pavelnk ©   (2015-04-03 14:50) [44]

Проще анализировать пиксели, а не закономерность.


 
Inovet ©   (2015-04-03 14:59) [45]

> [44] pavelnk ©   (03.04.15 14:50)
> Проще анализировать пиксели, а не закономерность.

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


 
Pavelnk ©   (2015-04-03 15:26) [46]

Да разве цвет не будет принадлежностью?


 
Andy BitOff ©   (2015-04-03 16:25) [47]

http://s13.postimg.org/f22h10g2f/Rec.gif


 
Юрий Зотов ©   (2015-04-03 16:32) [48]

Очень простой, но неэкономный способ.

Каждая точка - это объект, потомок TCollectionItem. Содержит свои координаты и цвет, а еще имеет свойство Figure, которое тоже есть объект, потомок TGraphicControl. Через метод Paint этого объекта точка умеет сама себя рисовать, а через его же события OnMouseEnter и OnMouseLeave точка знает, когда на нее наведена мышь.

График - это коллекция точек, потомок TCollection. У графика есть строковое свойство Hint (и раз каждая точка через свое свойство Collection знает свой график, то она имеет доступ к его свойству Hint).

Еще график имеет метод PaintCurve. В нем простой цикл - вызвать метод Paint каждой точки, а в результате график отрисован. Теперь если навести курсор на любую его точку, то у нее сработает OnMouseEnter и будет показан Hint графика (или что угодно другое). Соответственно, при уходе мыши срабатывает OnMouseLeave и Hint исчезает.


 
Andy BitOff ©   (2015-04-03 16:36) [49]

Код к моему посту выше


unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ComCtrls, ExtCtrls, StdCtrls, Buttons, gdiplus, Generics.Collections;

type
 TArrTypeEnum = (atBeziers, atLines);
 TArrayData = record
   arr: TArray<TGPPointF>;
   ArrType: TArrTypeEnum;
   Caption: string;
   isOver: Boolean;
   PenColor: TGPColor;
   PenWidth: Single;
   SelPenColor: TGPColor;
   SelPenWidth: Single;
 end;

 TForm1 = class(TForm)
   procedure FormCreate(Sender: TObject);
   procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
   procedure FormPaint(Sender: TObject);
 private
   m_theArrayList: TArray<TArrayData>;
   m_Over: boolean;
   m_theCurrentPen: IGPPen;
   m_theHint: THintWindow;
   procedure draw;
   { Private declarations }
 public
   { Public declarations }

 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 m_theCurrentPen := TGPPen.Create(TGPColor.Black);
 m_theHint := THintWindow.Create(self);
 m_theArrayList := TArray<TArrayData>.Create();
 SetLength(m_theArrayList, 3);

 m_theArrayList[0].arr := TArray<TGPPointF>.create(
     TGPPointF.Create(10, 100),
     TGPPointF.Create(100,10),
     TGPPointF.Create(150,150),
     TGPPointF.Create(200,100),
     TGPPointF.Create(300,10),
     TGPPointF.Create(350,150),
     TGPPointF.Create(400,100),
     TGPPointF.Create(500,10),
     TGPPointF.Create(550,150),
     TGPPointF.Create(600,100)
     );
 m_theArrayList[0].ArrType := atBeziers;
 m_theArrayList[0].Caption := "Bezier 1";
 m_theArrayList[0].isOver := false;
 m_theArrayList[0].PenColor := TGPColor.Blue;
 m_theArrayList[0].PenWidth := 1;
 m_theArrayList[0].SelPenColor := TGPColor.Yellow;
 m_theArrayList[0].SelPenWidth := 5;

 m_theArrayList[1].arr := TArray<TGPPointF>.create(
    TGPPointF.Create(110,100),
    TGPPointF.Create(200,10),
    TGPPointF.Create(250,150),
    TGPPointF.Create(300,100),
    TGPPointF.Create(400,10),
    TGPPointF.Create(450,150),
    TGPPointF.Create(500,100),
    TGPPointF.Create(600,10),
    TGPPointF.Create(650,150),
    TGPPointF.Create(700,100)
    );
 m_theArrayList[1].ArrType := atBeziers;
 m_theArrayList[1].Caption := "Bezier 2";
 m_theArrayList[1].isOver := false;
 m_theArrayList[1].PenColor := TGPColor.Red;
 m_theArrayList[1].PenWidth := 2;
 m_theArrayList[1].SelPenColor := TGPColor.Green;
 m_theArrayList[1].SelPenWidth := 5;

 m_theArrayList[2].arr := TArray<TGPPointF>.create(
     TGPPointF.Create(60, 100),
     TGPPointF.Create(150,10),
     TGPPointF.Create(200,150),
     TGPPointF.Create(250,100),
     TGPPointF.Create(350,10),
     TGPPointF.Create(400,150),
     TGPPointF.Create(450,100),
     TGPPointF.Create(550,10),
     TGPPointF.Create(600,150),
     TGPPointF.Create(650,100)
     );
 m_theArrayList[2].ArrType := atLines;
 m_theArrayList[2].Caption := "Lines 1";
 m_theArrayList[2].isOver := false;
 m_theArrayList[2].PenColor := TGPColor.Gray;
 m_theArrayList[2].PenWidth := 3;
 m_theArrayList[2].SelPenColor := TGPColor.Cyan;
 m_theArrayList[2].SelPenWidth := 10;
end;

procedure TForm1.draw;
var
 Graphics: IGPGraphics;
 ArrayDataItem: TArrayData;
begin
 Graphics := TGPGraphics.FromHWnd(Handle);

 Graphics.Clear(TGPColor.White);

 for ArrayDataItem in m_theArrayList do begin
   if ArrayDataItem.isOver then begin
     m_theCurrentPen.Color := ArrayDataItem.SelPenColor;
     m_theCurrentPen.Width := ArrayDataItem.SelPenWidth;
   end
   else begin
     m_theCurrentPen.Color := ArrayDataItem.PenColor;
     m_theCurrentPen.Width := ArrayDataItem.PenWidth;
   end;
   case ArrayDataItem.ArrType of
     atBeziers: Graphics.DrawBeziers(m_theCurrentPen, ArrayDataItem.arr);
     atLines  : Graphics.DrawLines(m_theCurrentPen, ArrayDataItem.arr);
   end;
 end;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
 i: integer;
 oldOver, NeedRedraw: Boolean;
 P: TPoint;
 HintCaption: string;
 pen: IGPPen;
 path: IGPGraphicsPath;

begin
 HintCaption := "";
 NeedRedraw := false;
 for i := 0 to Length(m_theArrayList) - 1 do begin
   oldOver := m_theArrayList[i].isOver;

   pen := TGPPen.Create(TGPColor.Black, 10);
   path := TGPGraphicsPath.Create();
   case m_theArrayList[i].ArrType of
     atBeziers: path.AddBeziers(m_theArrayList[i].arr);
     atLines  : path.AddLines(m_theArrayList[i].arr);
   end;
   m_theArrayList[i].isOver := path.IsOutlineVisible(TGPPointF.Create(X, Y), pen);

   if oldOver <> m_theArrayList[i].isOver then
     NeedRedraw := true;
   if m_theArrayList[i].isOver then
     HintCaption := HintCaption + " " + m_theArrayList[i].Caption;
 end;

 if NeedRedraw then
   Draw;
 if HintCaption <> "" then begin
   p := ClientToScreen(Point(X + 10, Y - 20));
   m_theHint.ActivateHint(Rect(P.X, P.Y, P.X + 100, P.Y + 18), HintCaption);
 end
 else
   m_theHint.ReleaseHandle;
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
 draw;
end;

end.


 
Inovet ©   (2015-04-03 16:47) [50]

> [47] Andy BitOff ©   (03.04.15 16:25)
> http://s13.postimg.org/f22h10g2f/Rec.gif

Это нюансы итерфейса. Как опознать, вот в чём вопрос.


 
Inovet ©   (2015-04-03 16:52) [51]

> [48] Юрий Зотов ©   (03.04.15 16:32)

Таки дилема и цимус лоджика - разделять ли данные и их отображение или нет.


 
KSergey ©   (2015-04-03 17:06) [52]

> Andy BitOff ©   (03.04.15 16:36) [49]
> Код к моему посту выше

Человек не слова, но дела!
Восхищён!

Интересен как минимум пример работы с GDI+, ну и более чем по теме.
Спасибо


 
Andy BitOff ©   (2015-04-03 17:12) [53]


> KSergey ©

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

gdi+ брать у Митова - http://www.mitov.com/products/igdi+#overview


 
Кто б сомневался ©   (2015-04-03 17:13) [54]

Как график должен выглядеть, можешь снять скриншот?
И это график чего?


 
Юрий Зотов ©   (2015-04-03 17:27) [55]

> Inovet ©   (03.04.15 16:52) [51]
> разделять ли данные и их отображение или нет.


Если следовать принципам ООП, то не разделять. Инкапсуляция, тудыть ее. Объект содержит и данные, и методы их обработки. Поскольку только ему одному известно, как надо их обрабатывать

Хотя никто не мешает хранить где-то кривую отдельно, в виде массива точек. И передавать этот массив на вход PaintCurve.


 
Юрий Зотов ©   (2015-04-03 17:32) [56]

Если нужны исходники, то вот здесь почти готовый сабж:

http://delphikingdom.com/asp/viewitem.asp?catalogid=215


 
Palladin ©   (2015-04-03 18:00) [57]


> Inovet ©   (03.04.15 16:52) [51]
>
> > [48] Юрий Зотов ©   (03.04.15 16:32)
>
> Таки дилема и цимус лоджика - разделять ли данные и их отображение
> или нет.
>

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


 
Кто б сомневался ©   (2015-04-03 19:39) [58]


> Юрий Зотов ©   (03.04.15 16:32) [48]
>
> Очень простой, но неэкономный способ.
>
> Каждая точка - это объект, потомок TCollectionItem.


Еще один велосипед :)


 
Inovet ©   (2015-04-03 19:43) [59]

> [55] Юрий Зотов ©   (03.04.15 17:27)
> Объект содержит и данные, и методы их обработки.

> [55] Юрий Зотов ©   (03.04.15 17:27)
> Хотя никто не мешает хранить где-то кривую отдельно, в виде массива точек

Значит, нужен обобщённый объект, который хранит и обрабатывает и то и другое. Я и говорю - не жирно ли это для точки на битмап, не лучше ли отдельно точки и отдельно их диаграммы.


 
Inovet ©   (2015-04-03 19:52) [60]

> [57] Palladin ©   (03.04.15 18:00)
> от фанатичного следования парадигамам

Это чё, наезд на "официальную" науку? Так, у меня не хватает знаний, чтобы ею заниматься. Но иногда знаний хватает для реализации практических подходов.


 
Rouse_ ©   (2015-04-03 21:35) [61]

Ну вот, а мне данные не кинули, хоть и просил :(
А по поводу регионов - они для того и придуманы, чтобы работать максимально быстро :)


 
Palladin ©   (2015-04-04 02:29) [62]


> Это чё, наезд на "официальную" науку?

Ну... я хотел сказать, что реальные посоны, в зависимости от условий, среды исполнения, от данных, и вообще задачи, как таковой, использую разные методы решения. В том числе и гетерогенные. И не кидаются в философские измышления (читай "срачи") вроде: "ООП рулез" или "ассемблер форева". Нет для них этой дилеммы.
А еще в моей практике есть решения адептов квадратно-гнездового способа мышления: это просто клиника. Вроде "я узнал о новой фиче, будем использовать ее везде, она мне понравилась". Через пол года, конечно, чел осознает (в случае наличия хоть какого то признака мозговой деятельности) ущербность пихания этой фичи во все дырки и фича предается анафеме, потому что не решает все проблемы. Но он не осознает ущербности подхода "новая фича во все дырки". И потому заменяется старую фичу на другую фичу. И тд и тп.


 
Юрий Зотов ©   (2015-04-04 07:42) [63]

> Кто б сомневался ©   (03.04.15 19:39) [58]

> Еще один велосипед :)


Открою страшную тайну: почти каждая написанная Вами, мною, да и кем угодно программа - это еще один велосипед. Или даже целый парк новых велосипедов.

Сабж - не исключение. Тем более, что задача достаточно распространенная и наверняка не раз кем-то уже решенная. Поэтому как ее ни решай - все равно еще один велосипед получишь.

> Inovet ©   (03.04.15 19:43) [59]

> нужен обобщённый объект, который хранит и обрабатывает и то и другое.


Коллекция (график) и является таким объектом, если ее элемент (точка) хранит свои данные (координаты, цвет, и т.п.). В этом варианте график и сам хранит свои данные, и сам умеет себя рисовать.

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

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

> не жирно ли это для точки на битмап

Я же сразу так и написал - способ простой, но неэкономный. Единственный его плюс - это простота и скорость реализации. Что важнее - простота или экономичность - это уже решает сам ТС.


 
Кто б сомневался ©   (2015-04-04 13:48) [64]


> Открою страшную тайну: почти каждая написанная Вами, мною,
>  да и кем угодно программа - это еще один велосипед. Или
> даже целый парк новых велосипедов.


Не, ну велосипед еще - это что то не в меру усложненное.


> Но элемент коллекции (точка) хранить свои данные не обязан.


Тогда уже лучше сделать массив из record ов, да работать напрямую с ними без промежуточного класса коллекции.

Имхо самый оптимальный вариант остается [14] [21] и [29], как по производительности, так и по гибкости. Другого пока не вижу.


 
Юрий Зотов ©   (2015-04-04 16:01) [65]

> Кто б сомневался ©   (04.04.15 13:48) [64]

> Не, ну велосипед еще - это что то не в меру усложненное.


Сложность - понятие субъективное. Способ, который я привел, наверное, не лучший, но вот сложным он уж никак не является. Наоборот, он очень простой, потому что всю работу делает VCL и остается лишь написать всего два несложных класса. К тому же, есть почти готовый код этих классов

> Тогда уже лучше сделать массив из record ов, да работать
> напрямую с ними без промежуточного класса коллекции.


Ага, только вот все то, что Вы назвали "работой" придется писать ручками. И отрисовку, и отслеживание мыши. Не думаю, что это проще. Впрочем, если Вы приведете код этой "работы", то можно будет сравнить.

А что касается гибкости... ну, надеюсь, что человеку, понимающему ООП, даже и объяснять не надо.

===============

Дискуссию заканчиваю. Было предложено несколько вариантов, указаны их плюсы и минусы - выбор за ТС, а обсуждать тут более нечего.


 
Kerk ©   (2015-04-04 16:40) [66]

ЮЗ прав. Как хранить сам список точек - это уже детали. Главное отделить модель от представления. Все эти идеи с GetPixel - полный капец. Нужна модель в памяти, которая умеет себя рисовать.



Страницы: 1 2 вся ветка

Форум: "Прочее";
Текущий архив: 2015.11.29;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.61 MB
Время: 0.005 c
15-1427969782
KSergey
2015-04-02 13:16
2015.11.29
Как делают вывод подсказок на графиках?


2-1402256430
Dimka-super
2014-06-08 23:40
2015.11.29
Циклы и рисование пикселей на форме . Помогите нормально написат


15-1428701404
Юрий
2015-04-11 00:30
2015.11.29
С днем рождения ! 11 апреля 2015 суббота


2-1402664348
Who_are_you?
2014-06-13 16:59
2015.11.29
Два байта в одно число


15-1427898124
Dimka Maslov
2015-04-01 17:22
2015.11.29
А вот почему?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский