Статьи

Визуализация данных с помощью Flex, часть III

В нашей первой статье мы рассмотрели основы визуализации данных, создали набор данных и создали отображение, показывающее вхождения ключевых слов на форумах SitePoint. Во второй части мы заменили вывод пружинным графиком, чтобы лучше проиллюстрировать отношения между ключевыми словами, а также добавили масштабирование шрифтов, чтобы показать относительную популярность каждого ключевого слова. В нашей последней части мы добавим на дисплей еще несколько фрагментов информации и проведем рефакторинг нашего приложения в соответствии с лучшими практиками. Инструкции будут основаны на готовом коде из второго руководства, но вы можете загрузить архив проекта Flex Builder, содержащий весь готовый код .

Опять же, на этой неделе у нас есть статья-викторина, спонсируемая Adobe, чтобы проверить, что вы узнаете в этом уроке. Не забудьте проверить это, когда вы закончите здесь!

В конце второй статьи у нас остался весенний график, который выглядел так:


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

Добавление большего количества текста к графику, вероятно, сделает его немного беспорядочным, а точное число вхождений — это больше второстепенная часть данных, к которой люди будут обращаться, если они заинтересованы в получении дополнительной информации. Имея это в виду, хорошим способом для продолжения является добавление всплывающей подсказки — таким образом, пользователь может щелкнуть мышью по любому ключевому слову, в котором он заинтересован, и просмотреть информацию, которую он хочет, без ненужного засорения графика.

Самый простой способ сделать это — добавить счетчик в атрибут toolTip нашего средства визуализации элементов. Давайте попробуем сделать это сейчас:


Если вы посмотрите на атрибут toolTip который мы добавили в VBox в нашем компоненте рендеринга встроенных элементов, мы передадим ему ключ data в нашем объекте. Это может показаться странным: просто помните, что то, что передается в средство визуализации элементов, всегда получает справочные data во Flex, и так уж получилось, что у нашего класса Item есть свойство с именем data , которое мы используем для хранения счетчика вхождений ключевых слов. , Если бы наше свойство в классе Item называлось adventrence_count , код выглядел бы так:

  ToolTip = "{data.occurrence_count}" 

Сохраните приведенный выше код - и когда вы наведете курсор мыши на ключевое слово в результирующем графе пружин, вы увидите всплывающую подсказку:


Это работает и доказывает, что мы можем протолкнуть нашу информацию до всплывающей подсказки, но не является ни привлекательным, ни особенно полезным. В идеале нам нужен более красивый интерфейс, достаточно большой, чтобы в нем содержался дополнительный текст, например «Упомянутый в 12345 потоках».

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

Почему и почему архитектурная передовая практика выходит за рамки этой статьи, поэтому сейчас я просто изложу простой способ структурирования кода. Если вы новичок в этом, я настоятельно рекомендую вам немного почитать архитектуру и шаблоны проектирования Flex и, возможно, взглянуть на некоторые фреймворки, такие как Mate и Swiz .

Чтобы выделить наш рендерер предметов, нам нужно создать новый класс. В вашем каталоге src вас должен быть подкаталог с именем com . Внутри com создайте каталог с именем sitepoint , затем внутри него создайте еще один каталог с именем itemrenderers . Этот метод размещения папок иногда называют обратной нотацией домена и является просто удобным способом отделения кода от разных проектов. Пока пути верны, Flex не заботится о том, где живет наш код - мы создаем подкаталоги исключительно для того, чтобы им было легче управлять по мере роста кодовой базы или когда вы объединяете код из разных проектов в один. В нашем случае вы можете видеть, что у нас уже есть каталог - adobe внутри нашего каталога com ; здесь живут классы сериализации Adobe JSON. Уже сейчас вы можете видеть, как соблюдение этого обозначения домена автоматически защищает нас от любых конфликтов имен и делает все это красивым и чистым.

Теперь на панели Flex Navigator щелкните правой кнопкой itemrenderers папку itemrenderers и выберите New , затем MXML Component . Назовите это KeywordRenderer.mxml и основывайте его на VBox. Вы должны получить новый файл, содержимое которого выглядит следующим образом:


Код, который нам нужен для завершения рендерера, похож на встроенную версию, которую мы создали в предыдущем уроке - полный файл должен выглядеть так:


Теперь, когда все .mxml , мы возвращаемся к нашему основному файлу .mxml и .mxml пару изменений. Удалите встроенный компонент - все внутри, включая теги <sg:itemRenderer> . Это должно выглядеть так:


Обратите внимание, что я удалил конечный тег и добавил косую черту в начальный тег, потому что нам больше не нужно ничего вкладывать в него. Нам также нужно будет переместить пошаговый код шрифта (который мы написали в части II) серии внутрь класса средства визуализации элементов. Это parentDocument нас от необходимости использовать parentDocument вызов функции шрифта. Это всегда хорошая идея, чтобы ваши компоненты не зависели от остального кода, чтобы их можно было повторно использовать без изменений.

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


Чтобы мы могли установить эти параметры, нам нужно назначить itemRenderer в нашем основном файле приложения. Давайте добавим это к методу setup , прямо перед строкой, в которой мы назначаем dataProvider- :


Здесь мы создаем ClassFactory и устанавливаем необходимые параметры в массиве ( factory.properties ), затем назначаем фабрику в качестве средства визуализации элементов для нашего графа пружин. Нам нужно сделать это в нашем скрипте, поскольку мы не можем установить параметры, если просто назначим его в качестве атрибута в нашем теге MXML.

Ваш окончательный KeywordRenderer.mxml должен выглядеть следующим образом:

Пример 7. src/com/sitepoint/itemrenderers/KeywordRenderer.mxml (отрывок)

  <? xml version = "1.0" encoding = "utf-8"?> <mx: VBox xmlns: mx = "http://www.adobe.com/2006/mxml" cornerRadius = "5" borderThickness = "1" borderStyle = "solid" backgroundColor = "0x444444" paddingBottom = "5" paddingLeft = "5" paddingRight = "5" paddingTop = "5" buttonMode = "true" mouseChildren = "false" useHandCursor = "true" click = "this. searchForums () "toolTip =" "toolTipCreate =" createCustomToolTip ('Упоминается в' + formatter.format (data.data) + 'threads', событие) "> <mx: Script> <! [CDATA [import mx.events. ToolTipEvent;  import com.sitepoint.tooltips.KeywordToolTip;  private var sitePointSearchURL: String = "http://www.sitepoint.com/forums/search.php?q=";  public var dataMin: Number;  public var dataMax: Number;  public var fontMin: Number;  public var fontMax: Number;  public var fontLift: Number;  приватная функция createCustomToolTip (title: String, событие: ToolTipEvent): void {var ktt: KeywordToolTip = new KeywordToolTip ();  ktt.message = title;  event.toolTip = ktt;  } приватная функция getFontSize (data: Number): Number {var fontSize: Number = (data - dataMin) / fontLift;  if (fontSize <fontMin) {return fontMin;  } else if (fontSize> fontMax) {return fontMax;  } else {return fontSize;  }} приватная функция searchForums (): void {navigateToURL (новый URLRequest (sitePointSearchURL + data.id), "_self");  }]]> </ mx: Script> <mx: NumberFormatter id = "formatter" /> <mx: Label text = "{data.id}" fontSize = "{getFontSize (data.data)}" color = "0xFFFFFF "textAlign =" center "/> </ mx: VBox> 


Если вы скомпилируете и перезагрузите приложение, ничего не изменится ... идеально! Это именно то, что вы хотите! При рефакторинге цель состоит в том, чтобы сохранить поведение приложения таким же, обеспечивая при этом теплое нечеткое ощущение, что вы правильно спроектировали свой код на будущее.

примечание: вопросы производительности

При создании пользовательских средств визуализации элементов (особенно для таких компонентов, как сетки данных) необходимо учитывать производительность. Для наших простых целей вполне достаточно вышеуказанного средства визуализации. Однако, если вы создаете рендерер для большой сетки данных, например, вам лучше создать чистый рендерер элементов ActionScript. Это не зависит от контейнера, так как такие элементы, как Canvas и VBox могут снизить производительность, когда десятки или сотни создаются при рендеринге сетки.