Эксперименты с визуализацией — Простые интерактивные графики с crossfilter.js и dc.js
Что это включает: Javascript, D3.js, crossfilter.js, dc.js
Мне всегда нравилось делать вещи трудным путем. И поэтому я отказался от библиотек визуализации более высокого уровня, которые позволяют создавать диаграммы в несколько строк.
Таким образом, D3.js некоторое время был моим предпочтительным инструментом для онлайн-визуализации (и будет темой других сообщений). Но недавно решил поэкспериментировать с библиотеками crossfilter.js и dc.js.
Во-первых, что делают библиотеки crossfilter.js и dc.js?
- crossfilter.js упрощает агрегирование и обработку данных в Javascript. Для тех, кто знаком со сводными таблицами Excel, это в основном его аналог в коде. Для тех, кто знаком с Tableau или Qlikview/Qliksense, это работает очень похоже. Это позволяет создавать измерения и выполнять вычисления с подмножествами данных в этих измерениях. Сам по себе crossfilter.js помогает только манипулировать данными.
- Но в сочетании с dc.js, высокоуровневой библиотекой диаграмм, вы получаете возможность (бесплатно) кодировать онлайн-визуализации, которые стоят огромных денег в Tableau или Qliksense.
Теперь для демонстрации. Полный код для демонстрации доступен здесь.
Я не буду здесь объяснять шаблоны HTML и CSS (но в коде есть комментарии для новичков).
Во-первых, данные. Имитационные данные, которые я использовал здесь, предназначены для представления доходности активов для портфеля за 2014–2018 годы. Здесь требуются плоские данные, и позже будет понятно, почему.
var portfolioData = [
{Year: 2014, Asset: 'Equity', Return: 0.045},
{Year: 2014, Asset: 'Bond', Return: 0.025},
{Year: 2014, Asset: 'Gold', Return: 0.015},
{Year: 2014, Asset: 'Cash', Return: 0.005},
...
];
Затем мы передаем данные функции перекрестного фильтра.
var datax = crossfilter(portfolioData);
Если вы сделаете console.log(datax)
сейчас, вы увидите, что вам доступны все вопросы функций.
Для целей этого руководства мы хотим рассмотреть параметры Год и Актив и просуммировать Доходность по этим параметрам.
var yearDimension = datax.dimension(function(d) {return d.Year;});
var assetDimension = datax.dimension(function(d) {return d.Asset;});
var returnsPerYear = yearDimension.group().reduceSum(function(d) {return +d.Return;});
var returnsPerAsset = assetDimension.group().reduceSum(function(d) {return +d.Return;});
Это в основном все, что нам нужно сделать для обработки данных. Теперь все настроено для графиков.
Мы сделаем две диаграммы, одну для годовой доходности (в виде гистограммы или, скорее, вертикальной гистограммы); и один, чтобы показать, насколько каждый актив способствовал доходу за год.
Сначала рядовая диаграмма. Код для этой части действительно прост -
- Получить
returnsRowChart
настройку с помощью функцииdc.rowChart
- Поток в измерении и сумме доходностей по годам
- Настройте способ отображения оси x
- Выберите цвета
var returnsRowChart = dc.rowChart("#rowchart");
returnsRowChart
.dimension(yearDimension)
.group(returnsPerYear)
.controlsUseVisibility(true);
returnsRowChart.xAxis().ticks(5).tickFormat(function(d){return d*100+'%';});
returnsRowChart.ordinalColors(['#ffc0cb','#ff99a2', '#ff7379', '#ff4c51', '#ff2628']);
Вот и все!
Далее займемся круговой диаграммой. Шаги очень похожи.
var returnsPieChart = dc.pieChart("#piechart");
returnsPieChart
.dimension(assetDimension)
.group(returnsPerAsset)
.innerRadius(50)
.controlsUseVisibility(true)
.on('pretransition', function(chart) {
chart.selectAll('text.pie-slice').text(function(d) {
return d.data.key + '-' + dc.utils.printSingleValue((d.endAngle - d.startAngle) / (2*Math.PI) * 100) + '%';
})
});
returnsPieChart.ordinalColors(['#ffc0cb','#ff99a2','#ff4c51', '#ff2628']);
Внутри есть одна строка, которая заслуживает немного большего пояснения. Что это делает, так это показывает процент, используя точку данных конечного и начального углов, которые были автоматически созданы, когда вы передавали данные в функцию pieChart.
.on('pretransition', function(chart) {
chart.selectAll('text.pie-slice').text(function(d) {
return d.data.key + '-' + dc.utils.printSingleValue((d.endAngle - d.startAngle) / (2*Math.PI) * 100) + '%';
})
});
И наконец…
dc.renderAll();
Эта последняя строка отображает диаграммы. Вы также можете вызвать render()
на каждом графике отдельно, например:
returnsPieChart.render();
Однако в этом случае две диаграммы не будут связаны и не будут динамически обновляться по отношению друг к другу.
playgrd.com