Форум: "Прочее";
Текущий архив: 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.004 c