Эксперименты с визуализацией — Простые интерактивные графики с 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