Кейс 1: грузоперевозки между странами

Название кейса

Грузоперевозки между странами

Описание кейса

Показываем топ 10 стран и все международные перевозки между ними.

Версия платформы

2.16

Браузер

Google Chrome 83

Статус

проверено

Сложность

Надо попотеть

Используемые библиотеки

sankey.js dependency-wheel.js

Ссылка на источник

https://www.highcharts.com/docs/chart-and-series-types/dependency-wheel

 

Вступление


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

Данные


Для построения нашего колеса зависимостей необязательно знать подробности модели данных, которая может быть довольно сложной. Самое главное иметь представление о том, что кладется в столбцы и строки в запросе на ViQube для виджета, и как потом мы манипулируем с прилетевшей из ViQube информацией для отображения именно того, что нам нужно: а именно топа-10 стран по экспорту товаров и все связи между ними на колесе.

Данные, привязанные к виджету:

Столбцы

Показатель “Объем перевозок“

Строки

Два атрибута измерения без группировки:

  • Страна импортер

  • Страна экспортер

Просмотр части данных в виде таблицы:

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

 

Код виджета


  • Первые 10 строчек необходимы для подключения внешних библиотек на лету. Это нужно только в случаях, когда мы не можем положить библиотеки в папку /docker-volume/dashboard-viewer/customjsна сервере с платформой. Поэтому в большинстве случаев эти 10 строчек можно смело удалять, предварительно положив sankey.js dependency-wheel.js в папку customjs.

  • 15-19 строки это преобразование данных с ViQube в массив данных, понятных Highcharts.

  • С 21 по 33 строчки происходит основная работа с данными, необходимая для правильного выделения топа-10 стран. Причем мы выделяем топ-10 стран по экспорту (по первому измерению).

Только для разработчика.
Выбор стран-экспортеров происходит в строках 27-28, где мы берем нулевой элемент текущего элемента-массива из массива данных. Этот нулевой элемент и будет страной экспортером.

  • Подробно алгоритм здесь описывать не будем, скажем лишь как поменять топ-10 на топ-15: в строке 32 меняем число 10 в двух местах на желаемое (15 в нашем случае):
    country.splice(15, country.length-15)

  • С 39 строчки отрисовывается сам виджет.

// Подключаем библиотеки необходимые для Колеса распределения let tempElem = document.createElement('script'); let tempElem2 = document.createElement('script'); tempElem.type = 'text/javascript'; tempElem.src = 'https://code.highcharts.com/7.1.3/modules/sankey.js' document.head.append(tempElem); tempElem2.type = 'text/javascript'; tempElem2.src = 'https://code.highcharts.com/7.1.3/modules/dependency-wheel.js' tempElem2.onload = render; document.head.append(tempElem2); // опционально: для замера времени отрисовки виджета //var time = performance.now() // Готовим массив всех данных var tempArr = []; for (var i= 0; i < w.data.rows.length; i++){ tempArr.push([w.data.rows[i][0], w.data.rows[i][1], w.data.values[0][i]]) } // Создаём массив уникальных имён первого измерения w.data.rows[i][0], и подсчитываем сумму всех элементов с таким именем. let country = []; for (let str of tempArr) { if (!country.map(item => item[0]).includes(str[0])) { country.push([str[0]]); } if (country[country.map(item => item[0]).indexOf(str[0])].length <2) {country[country.map(item => item[0]).indexOf(str[0])].push(str[2])} else {country[country.map(item => item[0]).indexOf(str[0])][1] += str[2]} } // Сортируем список уникальных имён и оставляем Топ-10, после чего массив значений фильтруем по имеющимся именам в Топ-10, имена проверяем и в 1 и во 2 измерении country.sort(function(a, b) { return b[1] - a[1]; }); country.splice(10, country.length-10); // обрезается массив, выделяя топ 10 значений tempArr = tempArr.filter(item => (country.map(it => it[0]).includes(item[0])>0) && (country.map(it => it[0]).includes(item[1])>0) && (item[2] !== null)) // опционально: для замера времени отрисовки виджета //time = performance.now() - time; //console.log('Время выполнения = ', time); function render () {Highcharts.chart(w.general.renderTo, { series: [{ keys: ['from', 'to', 'weight'], data: tempArr, type: 'dependencywheel', name: 'Направление перевозок' }] });}

 

 

Живой пример