Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2015.11.29;
Скачать: CL | DM;

Вниз

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

 
KSergey ©   (2015-04-02 13:16) [0]

Нарисовал график. И даже 2 графика по каким-то данным.
Как умные люди делают подсказку (разную) в зависимости от положения курсора мыши на графике? Речь не о выводе координат курсора. Речь (в простом варианте) например о вывода названия графика, на который показывает курсор мыши.

Я понимаю, что в общих словах "определить к чему курсор ближе, если до графика менее 5 пикселов - вывести подсказку". Вопрос в том как организовать ту самую проверку технически?

Вижу 2 варианта:

1) Имея формулу графика (ну или данные с неким отсчетом полученные, та же формула по сути) фактически перевычислять точки графика с учетом интерполяции и определять расстояние до точки курсора. Видится крайне затратным и сложным алгоритмически при изменении метода интерполяции и/или метода рисования графика (связная линия / крестики с каким-то шагом и т.п.)

2) Всегда рисовать картинку графика в памяти (т.е. всегда иметь отрисованную и фактически отображаемую сейчас картинку в памяти) и уже по ней определяя цвет точек определять ближайший к курсору график.

Вопрос:

а) Как организовать картинку из п.2 так, чтобы она еще и быстро отрисовывалась (если рисуем именно на картинке) и чтобы на ней был при этом быстрый доступ к пикселям?

б) Может усть более ловкие и умные методы? может Windows сама умеет говорить (и быстро!) цвет фактически отрисованных в WM_PAINT пикселей? (это если вариант, когда в WM_PAINT я просто честно рисую не сохраняя в явном виде картинку в памяти самостоятельно)


 
KSergey ©   (2015-04-02 13:27) [1]

Кстати в варианте 2 еще есть проблема, если 2 графика имеют одинаковый цвет - не различить.
Можно, конечно, делать вторую картинку "техническую", которую не показывать, но на которой все цвета разные, но опять получается двойная работа: отрисуй на экране, отрисуй  на технической картинке.


 
Dimka Maslov ©   (2015-04-02 13:37) [2]

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


 
KSergey ©   (2015-04-02 14:20) [3]

Положим, точек, по которым построена ломанная, 10 тыс (это реальные цифры)
Как-то грустно искать среди них.

Ну реально отображаемых, конечно, меньше, это можно (нужно) учесть. И тем не менее. Даже если предположить график в котором на каждую точку экрана своё значение - это уже 1400...1900 точек перебирать.

Можно еще соптимизировать - зная X координату - через масштаб -пересчитать "где искать"....

но блин, всё это сильно усложняет алгоритм и придётся под каждый вариант отображения графика выдумывать строить свой алгоритм поиска (а график может быть самый разный, да хоть спиралью! или наоборот - вертикальными палками).

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


 
Kerk ©   (2015-04-02 14:40) [4]

В винде есть такая штука - регионы. Вдруг поможет.


 
кгшзх ©   (2015-04-02 15:01) [5]

если бы не в делфи то все намного проще

http://dev.sencha.com/ext/5.1.0/examples/charts-kitchensink/#tip-chart


 
KSergey ©   (2015-04-02 15:44) [6]

Поизучаю, спасибо
Ибо язык - не имеет значения


 
Rouse_ ©   (2015-04-02 16:02) [7]

Типа такого чтоль?
http://rouse.drkb.ru/tmp/hint.avi


 
KSergey ©   (2015-04-02 18:03) [8]

> Rouse_ ©   (02.04.15 16:02) [7]

Тут, если я верно понял, просто на основании координаты Х выдается значение значение Y графика в подсказке. Да? Если так, то это не то.

Речь про то, как например здесь
http://dev.sencha.com/ext/5.1.0/examples/charts-kitchensink/#tip-chart

когда подводишь мышь на график - и он становится жирным. И вопрос в том как определить, что мы к этому графику подвели сейчас мышь. Когда уже понятно о каком графике речь - то там уже можно сделать с ним что угодно; вопрос в том, как определить к какому графику подвели мышь.

Ну или так опишу задачу:  отображаем несколько фигур очень сложной формы. Нужно определить над какой фигурой сейчас курсор. Ну или фигуры пусть представлены только своей границей - соответственно на границе какой фигуры мы показываем мышью. Причем очень не хочется перевысчитывать заново координаты вершин каждой фигуры для этого и "строить" границы, ибо картинка может скролироваться и масштабироваться.


 
Rouse_ ©   (2015-04-02 18:06) [9]


> KSergey ©   (02.04.15 18:03) [8]

Понял, щас попробую накидать идею.


 
кгшзх ©   (2015-04-02 18:08) [10]

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


 
Rouse_ ©   (2015-04-02 18:12) [11]

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


 
Кто б сомневался ©   (2015-04-02 18:37) [12]



> 2) Всегда рисовать картинку графика в памяти (т.е. всегда
> иметь отрисованную и фактически отображаемую сейчас картинку
> в памяти) и уже по ней определяя цвет точек определять ближайший
> к курсору график.


>  Может усть более ловкие и умные методы? может Windows сама
> умеет говорить (и быстро!) цвет фактически отрисованных
> в WM_PAINT пикселей?


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


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

А вдруг будет 2 прямоугольника (ну или что там) одного цвета?


 
Кто б сомневался ©   (2015-04-02 18:47) [14]


> А вдруг будет 2 прямоугольника (ну или что там) одного цвета?


Любой XY график можно представить как набор прямоугольников с разной шириной и высотой. Каждый пик и яма - новый прямоугольник.
Эта вся хрень может храниться в массиве из TRect - по ним и можно легко вычислить позицию на канве - по X - сумма ширины, по Y ... высоты - ну понятно думаю.
Я так представляю.


 
Rouse_ ©   (2015-04-02 18:56) [15]

Через построение региона на этапе вывода графика имх проще.


 
invis ©   (2015-04-02 19:00) [16]

Я бы скорее выбрал вариант 1. Все кривые сводятся к ломаным, а что ещё есть? Палки и крестики - то есть всего 3 типа графиков, причём для палок и крестиков проверка очень простая. Проверка ломаной на 2000 точек безо всяких оптимизаций занимает всего 50 мкс (2.7 Ггц). Что до масштабирования/сдвига - можно отдельно хранить график в экранных координатах с отсечением невидимых областей.
А в варианте 2 техническую картинку желательно рисовать толстой кистью (чтобы проверялось попадание в определённом радиусе), это медленнее чем обычное рисование, и правка функций рисования всё же понадобится.


 
Rouse_ ©   (2015-04-02 19:10) [17]

Ребят, кгшзх © уже правильное решение предложил. Сложность графика не важна (пусть он хоть из триллиарда точек), важно только то, с чем работает пользователь. А работает он с тем что выведено на экране, где эти триллиарды сольются в несколько тысяч пикселей, от которых и нужно плясать, расширив коридор по радиусу, и скомбинировав все это в один регион.


 
Rouse_ ©   (2015-04-02 19:12) [18]

Ну а хинт отображать уже обработкой банального CM_SHOWHINT, перекрыв оконную процедуру, и выставляя правильные параметры структуре HintInfo, чтобы при перемещении мыши в момент выхода за регион - происходил запрос нового хинта.


 
Kerk ©   (2015-04-02 19:17) [19]

Вот ведь. Про регионы первым вспомнил я, а оказывается это кгшзх правильное решение предложил. Пойду напьюсь с горя :)


 
Rouse_ ©   (2015-04-02 19:22) [20]

Ну пардоньть Ромч, и ты тоже :)
Кстати, завтра в аську выйди, а ты мне нужен.


 
Кто б сомневался ©   (2015-04-02 19:28) [21]


> Эта вся хрень может храниться в массиве из TRect - по ним
> и можно легко вычислить позицию на канве - по X - сумма
> ширины, по Y ... высоты - ну понятно думаю.

Это дает еще самое нужное - можно добавить типы к каждому участку кривой.
Это и цвет, и жирность и форма и текст что угодно. И все это можно реализовать в методах record"a участка.


 
invis ©   (2015-04-02 19:52) [22]

Регионы через BeginPath/EndPath/PathToRegion что ли? Пробовал - тормозит, 400 мс на той же ломаной из 2000 точек.
А если вручную создавать, то кода там будет не меньше, чем с геометрической проверкой. Скорее больше, стандартной функции создания региона из ломаной нет, нужно как-то изощряться.


 
Sha ©   (2015-04-02 20:01) [23]

Завтра ж пятница, поэтому на все про все для одного графика должно хватить одного массива типа TAreal :)  

type
 TYBounds = record
    YMin, YMax: word;
 end;
 TAreal = array of TYBounds;


 
Inovet ©   (2015-04-02 20:05) [24]

Чёт я не понял про ваши эти регионы. Почему не хранить просчитанные точки в массивах для каждого графика. При наведении мыши переводить экранные координаты в соответсвии с масштабом горизонтальную - в индекс массива и смотреть в окрестостях этого индекса значения - это будут Y тоже с заданным приближением.

С масштабированием отображения, чтобы не пересчитывать всё целиком, можно посложнее придумать структуру и дополнять уже посчитанное.


 
KSergey ©   (2015-04-02 20:45) [25]

20 окон с графиками, в каждом окне по 10 графиков.
Это простейший начальный случай того, что хотелось бы.
Не надорвется винда с регионами?


 
invis ©   (2015-04-02 21:08) [26]

Насчёт тормознутости регионов уточню: 400 мс - это были неудобные данные, ломаная на основе рандомного набора точек. С синусоидой лучше, 25 мс. Но при этом не получается одновременно нарисовать график (StrokePath) и получить регион, то есть два раза рисовать нужно.
Вообще, не люблю я эти мутные системные API: в таком порядке/сочетании вызовы работают, в этаком - нет, логически объяснить невозможно, только запомнить хитрое шаманское движение бубном. Ну нафиг, лучше уж самому посчитать, благо возможность есть.


 
Kerk ©   (2015-04-02 21:46) [27]


>
> Rouse_ ©   (02.04.15 19:22) [20]
>
> Кстати, завтра в аську выйди, а ты мне нужен.

Выйду:)


 
Кто б сомневался ©   (2015-04-02 23:21) [28]


> Чёт я не понял про ваши эти регионы. Почему не хранить просчитанные
> точки в массивах для каждого графика.


Так наверное интереснее, просчитывать точки снова. :)


 
Кто б сомневался ©   (2015-04-02 23:39) [29]


> Ну реально отображаемых, конечно, меньше, это можно (нужно)
> учесть. И тем не менее. Даже если предположить график в
> котором на каждую точку экрана своё значение - это уже 1400.
> ..1900 точек перебирать.
>
> Можно еще соптимизировать - зная X координату - через масштаб
> -пересчитать "где искать"....
>
> но блин, всё это сильно усложняет алгоритм и придётся под
> каждый вариант отображения графика выдумывать строить свой
> алгоритм поиска


Что там его придумывать - обычный бинарный поиск - делим на два и сравниваем 2 числа.


 
Кто б сомневался ©   (2015-04-02 23:45) [30]


> Что там его придумывать - обычный бинарный поиск - делим
> на два и сравниваем 2 числа.


Массив то будет отсортирован по координатам - от 0 - до X.


 
Юрий Зотов ©   (2015-04-03 00:22) [31]

> Windows сама умеет говорить (и быстро!) цвет ... пикселей

GetPixel


 
Andy BitOff ©   (2015-04-03 08:06) [32]

Если использовать GDI+ то там у пути есть нужные методы. Например:

function TForm1.isOver(X, Y: Integer): Boolean;
var
 path: IGPGraphicsPath;
begin
 path := TGPGraphicsPath.Create();
 path.AddBeziers(PointsArr);
 Result := path.IsOutlineVisible(TGPPointF.Create(X, Y), m_theCurrentPen);
end;

Возвращает тру, если координаты находятся на линией n кривых Безье


 
KSergey ©   (2015-04-03 08:23) [33]

> Юрий Зотов ©   (03.04.15 00:22) [31]
> > Windows сама умеет говорить (и быстро!) цвет ... пикселей
> GetPixel

Опасаюсь, что работает крайне медленно эта штука.
Кстати, такой момент: если наложено 2 окна, одно полупрозрачное - какой цвет в итоге вернёт GetPixel?

Блин, что цвет тут верно заметили - разные графики могут быть одного цвета же. Кроме того, один график может быть разных цветов.
Нешта придётся таки выдумывать систему определения назад, через координаты и математику? Грустно.


 
KSergey ©   (2015-04-03 08:24) [34]

> Кто б сомневался ©   (02.04.15 23:45) [30]
> Массив то будет отсортирован по координатам - от 0 - до X.

Еще раз, график может быть, например, спиралью.


 
Andy BitOff ©   (2015-04-03 09:45) [35]


> KSergey ©

Скинь данных попробовать.


 
KSergey ©   (2015-04-03 12:08) [36]

Прикидывая как и что - всё больше склоняюсь к идее, что проще все точки (буквально все видимые) точки линии запоминать в виде массива координат.
но пример накидаю, да. Всё равно придётся на чем-то отрабатывать технологию.
А так хотелось по-простому!


 
Inovet ©   (2015-04-03 12:24) [37]

> [34] KSergey ©   (03.04.15 08:24)
> Еще раз, график может быть, например, спиралью.

Это уже не график


 
Кто б сомневался ©   (2015-04-03 12:30) [38]


> KSergey ©   (03.04.15 08:24) [34]
>
> > Кто б сомневался ©   (02.04.15 23:45) [30]
> > Массив то будет отсортирован по координатам - от 0 - до
> X.
>
> Еще раз, график может быть, например, спиралью.


Как это? Точка назад во времени (влево) чтоли возвращаться может?


 
Pavelnk ©   (2015-04-03 14:20) [39]

Вообще тема интересная, если упростить, то звучит так, как оживить пиксели битмапа. Тут наверное нужен ответ опытного или знающего человека.


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

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



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

Текущий архив: 2015.11.29;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.009 c
15-1427722087
KSergey
2015-03-30 16:28
2015.11.29
Подмена адреса функции WinAPI


2-1402320241
Sakipiel
2014-06-09 17:24
2015.11.29
FindComponent неопределен в пакете


1-1334302310
TNK
2012-04-13 11:31
2015.11.29
Word - работа с таблицей


15-1427816887
Юрий Зотов
2015-03-31 18:48
2015.11.29
Коллективная разработка софта


15-1427819941
Кто б сомневался
2015-03-31 19:39
2015.11.29
Фрэймы с одинаковым Owner