
Здравствуйте, уважаемые хабрапользователи!
В этом посте я расскажу вам о нашей разработке — бесплатной Open-source библиотеке для интерактивной визуализации данных WPF DynamicDataDisplay.
Немного о нас: мы — это сотрудники лаборатории технологий Microsoft факультета Вычислительной математики и кибернетики Московского государственного университета. Недавно на Хабре была статья о том, каким наш факультет видится студенту первого курса, а теперь этот пост позволит вам немного больше узнать о том, чем занимаются студенты нашего факультета на более старших курсах. Пример того, над чем работают пятикурсники — это наша библиотека для интерактивной визуализации научных данных DynamicDataDisplay (сокращенно — D3).
Немного истории
Разработка библиотеки началась в сентябре 2007 года в рамках сотрудничества нашей лаборатории и Microsoft Research Cambridge. Летом 2008 года первая версия библитеки была опубликована на сайте dynamicdatadisplay.codeplex.com, где находится и развивается и поныне. С момента публикации минуло еще 3 выпуска стабильной версии библиотеки. Сейчас готовится к выпуску следующая версия — предположительно, v0.4, которая будет содержать в себе весьма много изменений и нововведений.
Но довольно вступительных слов — что же DynamicDataDisplay за библиотека и какие у нее возможности?
Возможности DynamicDataDisplay
DynamicDataDisplay предназначен для использования в managed-приложениях, построенных на технологиях WPF или Silverlight (об этом чуть позже).
Вы можете сказать, что уже и так существует предостаточно .NET библиотек для рисования графиков, и тут я с вами соглашусь — количество действительно есть. Но вот качество зачастую оставляет желать лучшего — попросите такой компонент построить график на основе данных длиной несколько десятков тысяч, и уже на нескольких сотнях элементов вы ощутите значительное замедление.
Основные преимущества DynamicDataDisplay над своими аналогами — это ориентированность на интерактивное отображение данных больших объемов, бесплатность, наличие открытого исходного кода. Интерактивное отображение данных больших объемов означает, что вы получите не статичное изображение вашей информации, а живой график, с возможностью передвигаться по нему, приближать отдельные области и отдаляться от них. DynamicDataDisplay отличается модульной и гибкой архитектурой, что позволяет вам с легкостью изменять и дополнять ее под свои нужды.
Итак, что же умеет показывать DynamicDataDisplay:
- Линии — графики:
- Последовательность маркеров — небольших визуальных элементов, связанных с данными. На уровне маркеров есть поддержка DataBinding, а более сложные взаимосвязи между данными и внешним видом маркера вы можете задать из C#-кода.
Различные встроенные маркеры:
Разнообразные bar chart'ы:
- Разнообразнейшего вида оси — обычные числовые, временные двух типов (типа DateTime и типа TimeSpan) и другие. Следующий рисунок наглядно проиллюстрирует то буйство возможных осей, которые могу присутствовать рядом с графиком:
Как видно, у нас нет фиксированного числа предопределенных осей, что дает пользователю библиотеки неограниченную свободу в поиске наилучшего набора осей.
Следующий большой раздел возможностей D3 — это
Карты
DynamicDataDisplay умеет загружать из интернета, сохранять на жесткий диск и, конечно же, показывать всевозможные карты. В официальных выпусках D3 у нас есть только один провайдер карт — OpenStreetMaps — бесплатный и свободный картографический сервер, разрешение которого на выпуск его провайдера в комплетке D3 мы получили. Дело в том, что компонент DynamicDataDisplay выкладывается в интернет от имени Microsoft, что накладывает ряд ограничений на те готовые провайдеры карт, которые мы могли бы выложить вместе с компонентом — не можем же, в конце концов, от имени Microsoft взламывать карты Google или Yahoo, Yandex или Mail.ru, или самой Microsoft (Bing Maps). Впрочем, написать такой провайдер самому довольно легко — я приведу пример нерабочего кода провайдера карт Google Sky:
public sealed class GoogleSkyServer: NetworkTileServer
{
public GoogleSkyServer()
{
UriFormat = «XXX.google.com/mw-planetary/sky/XXX.jpg»;
ServerName = «Google Sky»;
ServersNum = 2;
MinServer = 1;
FileExtension = ".jpg";
}
protected override string CreateRequestUriCore(TileIndex index)
{
var level = (int)index.Level;
var y = MapTileProvider.GetSideTilesCount(level) / 2 — index.Y — 1;
var x = MapTileProvider.GetSideTilesCount(level) / 2 + index.X;
string uri = String.Format(UriFormat, CurrentServer, x, y, level);
return uri;
}
}
(Пример сделан нерабочим специально, во избежание.)
Вот так выглядят карты OpenStreetMaps в наибольшем отдалении:

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

К данным, которые накладываются на эту карту, уже не надо применять никакого преобразования, поскольку обе оси — широт и долгот — линейны.
На основе карт мы разработали довольно много других визуализаций: например, это фрактал Мандельброта, который по мере приближения к нему рассчитывает дополнительные тайлы карты, которые затем добавляются в пирамиду тайлов (пирамида тайлов — это дерево тайлов, упорядоченное по уровню масштаба. На первом уровне может быть, скажем, одно изображение, на втором — 4, на 3 — 16 и т.д.):

Загруженные тайлы карты могут быть упакованы в разновидность zip-архива (WPF'овский package, такой же, как использующийся в форматах документов docx, xlsx, xps) и затем распространяться в более удобной форме, работая как предзагруженный кэш тайлов.
Изолинии
DynamicDataDisplay умеет рисовать линии уровня или изолинии, причем на произвольной, даже кривоугольной сетке:

На данном изображении показаны линии уровня высот и глубин Земли. Сами изолинии получаются довольно объемными и, будучи отрисованными средствами WPF, довольно заметно притормаживают. Для ускорения их отображения мы применяем рендеринг изображения изолиний в битмапы, которые затем рисуются силами карты. Получается весьма шустро.
Вот так выглядят изолинии, отрисованные сами по себе, без промежуточного сохранения в битмап:

Перспективы развития DynamicDataDisplay
В будущем мы планируем развивать DynamicDataDisplay, чтобы он
Вот некоторые нововведения, которые или уже находятся в разработке, или скоро начнут разрабатываться:
- цветовые карты
- трехмерные визуализации:
- поверхности уровня
- сетки
- маркеры в трехмерном пространстве
- карты из DeepZoom
Ну и наконец, набор ссылок на все, связанное с нашей библиотекой:
Полезные ссылки
- Страница библиотеки WPF DynamicDataDisplay — dynamicdatadisplay.codeplex.com
- Twit библиотеки — twitter.com/DynamicDataDisp
- Опрос по использованию DynamicDataDisplay и предложения новых возможностей — microsoft.cs.msu.su/Projects/Pages/D3Poll.aspx
- Небольшая Wiki по DinamicDataDisplay — microsoft.cs.msu.su/personal/thecentury/Public%20Documents/Wiki/D3.html
- Стабильная WPF версия библиотеки — dynamicdatadisplay.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=26761
- Примеры использования WPF версии (XBAP-приложение) — mstlab.org/xbap/d3/DynamicDataDisplay.Xbap.Samples.xbap Для работы этого демо нужно установить Microsoft Parallel Extensions to .NET Framework 3.5, June 2008 Community Technology Preview (http://www.microsoft.com/downloads/details.aspx?FamilyId=348F73FD-593D-4B3C-B055-694C50D2B0F3&displaylang=en), поскольку мы его используем в некоторых частях библиотеки
- Стабильная Silverlight версия — dynamicdatadisplay.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=31046
- Примеры использования Silverlight версии — dynamicdatadisplay.codeplex.com/wikipage?title=DynamicDataDisplay%20Silverlight
- Самые новые версии библиотеки — dynamicdatadisplay.codeplex.com/SourceControl/ListDownloadableCommits.aspx
На данный момент библиотека довольно известна за пределами России, если судить, например, по статистике codeplex.com. Несколько коммерческих проектов успешно используют библиотеку DynamicDataDisplay. Цель этой статьи — повысить известность библиотеки в России.
На этом пока все, надеюсь, вы найдете нашу библиотеку полезной и сможете легко и успешно использовать ее в ваших проектах!