В нашей первой статье мы рассмотрели основы визуализации данных, создали набор данных и создали отображение, показывающее вхождения ключевых слов на форумах SitePoint. Во второй части мы заменили вывод пружинным графиком, чтобы лучше проиллюстрировать отношения между ключевыми словами, а также добавили масштабирование шрифтов, чтобы показать относительную популярность каждого ключевого слова. В нашей последней части мы добавим на дисплей еще несколько фрагментов информации и проведем рефакторинг нашего приложения в соответствии с лучшими практиками. Инструкции будут основаны на готовом коде из второго руководства, но вы можете загрузить архив проекта Flex Builder, содержащий весь готовый код .
Опять же, на этой неделе у нас есть статья-викторина, спонсируемая Adobe, чтобы проверить, что вы узнаете в этом уроке. Не забудьте проверить это, когда вы закончите здесь!
В конце второй статьи у нас остался весенний график, который выглядел так:
Это позволяет нам видеть прямые связи между ключевыми словами, а также видеть их относительную популярность. Это оставляет желать лучшего. Начнем с того, что у нас нет способа увидеть фактическое количество вхождений каждого ключевого слова, и, поскольку мы масштабируем размер шрифта с фиксированными приращениями, может быть существенная разница в количестве между ключевыми словами, которые отображаются с одинаковым размером.
Добавление большего количества текста к графику, вероятно, сделает его немного беспорядочным, а точное число вхождений — это больше второстепенная часть данных, к которой люди будут обращаться, если они заинтересованы в получении дополнительной информации. Имея это в виду, хорошим способом для продолжения является добавление всплывающей подсказки — таким образом, пользователь может щелкнуть мышью по любому ключевому слову, в котором он заинтересован, и просмотреть информацию, которую он хочет, без ненужного засорения графика.
Самый простой способ сделать это — добавить счетчик в атрибут toolTip
нашего средства визуализации элементов. Давайте попробуем сделать это сейчас:
Пример 1 (выдержка)
<sg: SpringGraph id = "mySpringGraph" backgroundColor = "# FFFFFF" lineColor = "# 6666ff" repulsionFactor = "5" right = "10" left = "10" bottom = "10" top = "10"> <sg: itemRenderer> <mx: Component> <mx: VBox cornerRadius = "5" backgroundColor = "0x444444" paddingBottom = "5" paddingLeft = "5" paddingRight = "5" paddingTop = "5" toolTip = "{data.data}" > <mx: Label text = "{data.id}" fontSize = "10" color = "0xFFFFFF" textAlign = "center" /> </ mx: VBox> </ mx: Component> </ sg: itemRenderer> < / SG: SpringGraph>
Если вы посмотрите на атрибут 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
и выберите , затем . Назовите это KeywordRenderer.mxml
и основывайте его на VBox. Вы должны получить новый файл, содержимое которого выглядит следующим образом:
Пример 2. src/com/sitepoint/itemrenderers/KeywordRenderer.mxml
(отрывок)
<? xml version = "1.0" encoding = "utf-8"?> <mx: VBox xmlns: mx = "http://www.adobe.com/2006/mxml" width = "400" height = "300" > </ тх: VBox>
Код, который нам нужен для завершения рендерера, похож на встроенную версию, которую мы создали в предыдущем уроке - полный файл должен выглядеть так:
Пример 3. 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"> <mx: Label text = "{data.id}" fontSize = "{parentDocument. getFontSize (data.data)} "color =" 0xFFFFFF "textAlign =" center "/> </ mx: VBox>
Теперь, когда все .mxml
, мы возвращаемся к нашему основному файлу .mxml
и .mxml
пару изменений. Удалите встроенный компонент - все внутри, включая теги <sg:itemRenderer>
. Это должно выглядеть так:
Пример 4. src/SitePoint_DataViz_Tutorial_Part3.mxml
(отрывок)
<sg: SpringGraph id = "mySpringGraph" backgroundColor = "# FFFFFF" lineColor = "# 6666ff" repulsionFactor = "5" right = "10" left = "10" bottom = "10" top = "10" />
Обратите внимание, что я удалил конечный тег и добавил косую черту в начальный тег, потому что нам больше не нужно ничего вкладывать в него. Нам также нужно будет переместить пошаговый код шрифта (который мы написали в части II) серии внутрь класса средства визуализации элементов. Это parentDocument
нас от необходимости использовать parentDocument
вызов функции шрифта. Это всегда хорошая идея, чтобы ваши компоненты не зависели от остального кода, чтобы их можно было повторно использовать без изменений.
Поскольку наш метод шрифта основан на данных, рассчитанных в основном приложении, нам необходимо передать его в виде последовательности параметров. Мы можем просто скопировать и вставить метод getFontSize
в наш новый рендерер элементов, а затем добавить объявления для открытых переменных следующим образом:
Пример 5. src/com/sitepoint/itemrenderers/KeywordRenderer.mxml
(отрывок)
public var dataMin: Number; public var dataMax: Number; public var fontMin: Number; public var fontMax: Number; public var fontLift: Number;
Чтобы мы могли установить эти параметры, нам нужно назначить itemRenderer в нашем основном файле приложения. Давайте добавим это к методу setup
, прямо перед строкой, в которой мы назначаем dataProvider- :
Пример 6. src/SitePoint_DataViz_Tutorial_Part3.mxml
(отрывок)
var factory: ClassFactory = новый ClassFactory (KeywordRenderer) factory.properties = {fontMin: fontMin, fontMax: fontMax, fontLift: fontLift, dataMin: dataMin, dataMax: dataMax}; mySpringGraph.itemRenderer = factory; mySpringGraph.dataProvider = myGraph;
Здесь мы создаем 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
могут снизить производительность, когда десятки или сотни создаются при рендеринге сетки.