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

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.003 c
15-1428130841
brother
2015-04-04 10:00
2015.11.29
получить иконки из imageres.dll


15-1428496087
Pavelnk
2015-04-08 15:28
2015.11.29
Какой размер экрана телефонов


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


15-1427122936
brother
2015-03-23 18:02
2015.11.29
рабочий стол x64 винды под x32 программой


2-1402861787
eh
2014-06-15 23:49
2015.11.29
Обновление записей в TpFibDataSet





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский