Mark-a-Spot - это дистрибутив Drupal для краудмэппинга и отслеживания общественных проблем. Он использует функции визуализации карты и мониторинга данных, которые в более ранних версиях были тепловыми картами, картами запросов на обслуживание и простыми представлениями агрегирования, подсчитывающими контент по категории и статусу.
Обсуждение фреймворка JavaScript для пользовательского интерфейса администратора Drupal побудило меня поиграть с Vue.js и реализовать больше функций визуализации для краудсорсинговых данных. В этой короткой статье я расскажу, как я получил все это, работая с vue-chartjs, оболочкой для Charts.js.
Желаемый результат
Установка 8.4.x dev ветки Mark-a-Spot теперь представляет отдельный раздел сайта для визуализации данных и один раздел для проверки 311 запросов на обслуживание в контексте местоположения.
Недавно включенный модуль трендов будет включен автоматически и предложит страницу панелей с несколькими диаграммами в виде блоков, которые также можно разместить на любой странице и в любом регионе вашей установки, например, скрывая некоторые из этих статистических данных от публики.
Компоненты
Блоки
Шаблон веточки каждого блока состоит всего из нескольких строк разметки:
<div class="trend_organisations"> <doughnut-organisations></doughnut-organisations> </div>
Плагин блока подключает только необходимые библиотеки JavaScript:
class MarkaspotTrendFilterBlock extends BlockBase implements BlockPluginInterface { /** * {@inheritdoc} */ public function build() { $config = $this->getConfiguration(); return [ '#theme' => 'markaspot_trend_filter_block', '#filter_intro' => $config['filter_intro'], '#attached' => [ 'library' => [ 'markaspot_trend/vue', 'markaspot_trend/vue-router', 'markaspot_trend/trend', 'markaspot_trend/filter', ], ], ]; }
Библиотеки
Drupal также должен знать источник внешних библиотек. Мне потребовались vue, vue-charts.js, vue-router и axios, клиентская библиотека http для использования остальных представлений Drupal.
В первой версии мы загружаем все необходимые библиотеки, скомпилированные через CDN с unpg.com, и помещаем их в markaspot_trend.libraries.yml модуля:
axios: remote: https://unpkg.com/axios/dist/axios.min.js version: 0.17.1 license: name: MIT js: https://unpkg.com/axios/dist/axios.min.js: { type: external, minified: true } vue-router: remote: https://unpkg.com/vue-router/dist/vue-router.min.js version: 3.0.1 license: name: MIT js: https://unpkg.com/vue-router/dist/vue-router.min.js: { type: external, minified: true } vue: remote: https://unpkg.com/[email protected]/dist/vue.js version: 2.5.9 license: name: MIT js: https://unpkg.com/[email protected]/dist/vue.js: { type: external, minified: true }
Пользовательский код
Каждому блоку принадлежит отдельный js-файл. Он отображает диаграммы, следит за изменениями маршрутизатора, передавая аргументы из блока фильтра.
Как только блок фильтра изменяет маршрут vue, свойство watch запускает новый запрос к представлениям Drupal. В основном все происходит в этих нескольких строках каждого js файла блоков. Если у кого-то есть предложения по общему рефакторингу, дайте мне знать.
watch: { '$route'(to, from){ this.getChartData(); } }, methods: { getChartData: function (param) { param = (param) ? param : this.$route.path; let baseUrl = settings.path.baseUrl; let url = baseUrl + 'georeport/stats/organisations' + param; let parent = this; axios.get(url, {}).then(function (response) { let stats = response.data; let chartData = { datasets: [parent.getStats(stats)], labels: parent.getLabels(stats) }; if (parent.$data._chart) { parent.$data._chart.destroy(); } parent.renderChart(chartData, parent.options); }).catch(function (error) { console.log(error); }); return this.chartData; },
Результат всех блоков вместе с некоторыми эффектами на компоненте карты Mark-a-Spot должен быть загружен в левой части этой статьи.
Код еще не полностью переработан и все еще представляет собой смесь jQuery и vue.js. Итак, работа продолжается. В будущих версиях должно быть некоторое кеширование для повторяющихся запросов, таких как получение меток терминов.