Используя C# Graphics нарисовать график в 30 000 точек в общем-то несложно. Но работать потом с ним (увеличить масштаб например) затратно с точки зрения ресурсов. Наверно разумно рисовать столько точек, сколько физически может уместиться в текущем размере в пикселях.
Предположим, есть массив из 30 000 точек. Как построить такой график на ширине в 800px по "средним"(не знаю, как правильно) точкам? А потом увеличить какую-нибудь конкретную область, чтобы график обновился и стал чётче.
Начать наверное надо с того, что это за график - это функция или набор данных?
В любом случае, не стоит хранить именно графическую информацию. Необходимо иметь возможность построить необходимую кривую в заданном диапазоне по исходным данным. Например, если у вас есть набор из 30 тыс. значений, то при масштабировании необходимо сначала определить интервал отображаемых значений, затем построить график только по ним.
Это набор данных. Величина сигнала, измеренная устройством на каждом пикселе некоего датчика, которых всего ~30 000.
А если по умолчанию нужно выводить весь спектр сигнала, а потом при желании масштабировать?
ars-bars, я бы замерил производительность прорисовки для каждого пикселя, каждого 2-го, 4-го, 16-го, и т. д. (для одномерного графика). Если это двумерный график, то бить набор данных надо "сеткой", по 4, по 9, по 16, по 25 и т. д. соседних элементов.
На самом мелком масштабе прорисовка должна идти по каждому N-ному элементу (квадрату), где N подобрано с таким расчётом, чтобы общее время прорисовки было приемлемым на целевой машине. При увеличении масштаба, соответственно прорисовываете всё более детально, уменьшая N
Все 30 000 точек строить необязательно.
В "хороших" графиках в мелких масштабах графики линейны, поэтому можно заменить линейной интерполяцией.
То есть:
1. выберем все точки в нужном диапазоне.
2. далее берем последовательно точки из этого диапазона, только если расстояние по Х до предыдущей превышает deltaXminGraph в пикселях.
3.Соединяем прямым отрезком предыдущую и текущую точку.
Имеет смысл для текущего масштаба запомнить/закэшировать используемые точки.
Но это будет работать, если графики "хорошие"....гладкие....
Если же присутствует некий шум....всякое шебуршение, импульсы.....то надо сначала отфильтровать его...
Если же этот шум тоже нужно нарисовать, то тут уже разные варианты появляются.....в зависимости от того что именно интересно....
График в этом вопросе - это набор данных, величина сигнала, измеренная устройством на каждом пикселе некоего датчика, которых всего ~30 000. К сожалению, он выглядит так, что сопоставим случайной генерации чисел от 0 до 4000 на протяжении 30 000.
На крупных масштабах (когда мелких деталей не видно) мы должны отсечь одиночные выбросы и провалы, а так же игнорировать высокочастотную составляющую: только крупные изменения должны быть видны. Это похоже на применение оконного медианного и оконного среднего фильтров (в окне отбрасываем несколько минимальных и максимальных замеров, а по остальным усредняем). После их применения график будет более гладкий и его можно будет рисовать как я выше написал.
Параметры фильтров должны зависеть от масштаба. Т.е. размер окна и сколько максимальных и минимальных замеров выбрасывать должно зависеть от масштаба. Так на мелких масштабах (когда должны быть видны самые мелкие детали) размер окна должен уменьшится до единицы (до есть никакой фильтрации по сути не должно быть).