quaintitative

I write about my quantitative explorations in visualisation, data science, machine and deep learning here, as well as other random musings.

For more about me and my other interests, visit playgrd or socials below


Categories
Subscribe

Experiments in visualisation - Simple interactive charts with crossfilter.js and dc.js

 What this covers: Javascript, D3.js, crossfilter.js, dc.js

I have always liked doing things the hard way. And so I have eschewed the higher level visualisation libraries that allow one to create charts in a few lines.

D3.js has hence been the tool of my choice for online visualisation for a while now (and will be the subjects of other posts). But decided to experiment with the crossfilter.js and dc.js libraries recently.

First-off, what do the crossfilter.js and dc.js libraries do?

Now for a demonstration. Full code for the demonstration is available here.

I shall not explain the HTML and CSS boilerplate here (but there are comments within the code for a newbie).

First, the data. The mock data that I have used here are meant to represent asset returns for a portfolio from 2014-2018. Flat data is required here, and it will be clear why later.

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},

    ...
];

Next we feed the data to the crossfilter function.

var datax = crossfilter(portfolioData);

If you do a console.log(datax) now, you will see that all matters of functions are available to you.

For the purposes of this tutorial, we want to look at the Year and Asset dimensions, and sum the Return by these dimensions.

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;});

That’s basically all we need to do for data processing. Everything is now set-up for the charts.

We will do two charts, one for the year on year returns (as a row chart, or rather a vertical bar chart); and one to show how much each asset contributed to returns for the year.

First the row chart. The code for this part is really simple -

returnsRowChart .dimension(yearDimension) .group(returnsPerYear) .controlsUseVisibility(true);

returnsRowChart.xAxis().ticks(5).tickFormat(function(d){return d*100+’%’;});

returnsRowChart.ordinalColors([‘#ffc0cb’,’#ff99a2’, ‘#ff7379’, ‘#ff4c51’, ‘#ff2628’]);


That’s it!

Next, let’s do the pie chart. The steps are very much similar. 

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’]);


There is one line within that deserves a little more explanation. What this does is to show the percentage by using the end and start angles datapoint that were automatically created when you passed data into the pieChart function.

.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) + ‘%’; }) });

And finally…

dc.renderAll();


This final line renders the charts. You could also call `render()` on each chart individually, example -

returnsPieChart.render(); ```

However, do note that the two charts will not be linked and will not dynamically update in relation to each other if you do this.


Articles

Comparing Prompts for Different Large Language Models (Other than ChatGPT)
AI and UIs
Listing NFTs
Extracting and Processing Wikidata datasets
Extracting and Processing Google Trends data
Extracting and Processing Reddit datasets from PushShift
Extracting and Processing GDELT GKG datasets from BigQuery
Some notes relating to Machine Learning
Some notes relating to Python
Using CCapture.js library with p5.js and three.js
Introduction to PoseNet with three.js
Topic Modelling
Three.js Series - Manipulating vertices in three.js
Three.js Series - Music and three.js
Three.js Series - Simple primer on three.js
HTML Scraping 101
(Almost) The Simplest Server Ever
Tweening in p5.js
Logistic Regression Classification in plain ole Javascript
Introduction to Machine Learning Right Inside the Browser
Nature and Math - Particle Swarm Optimisation
Growing a network garden in D3
Data Analytics with Blender
The Nature of Code Ported to Three.js
Primer on Generative Art in Blender
How normal are you? Checking distributional assumptions.
Monte Carlo Simulation of Value at Risk in Python
Measuring Expected Shortfall in Python
Style Transfer X Generative Art
Measuring Market Risk in Python
Simple charts | crossfilter.js and dc.js
d3.js vs. p5.js for visualisation
Portfolio Optimisation with Tensorflow and D3 Dashboard
Setting Up a Data Lab Environment - Part 6
Setting Up a Data Lab Environment - Part 5
Setting Up a Data Lab Environment - Part 4
Setting Up a Data Lab Environment - Part 3
Setting Up a Data Lab Environment - Part 2
Setting Up a Data Lab Environment - Part 1
Generating a Strange Attractor in three.js
(Almost) All the Most Common Machine Learning Algorithms in Javascript
3 Days of Hand Coding Visualisations - Day 3
3 Days of Hand Coding Visualisations - Day 2
3 Days of Hand Coding Visualisations - Day 1
3 Days of Hand Coding Visualisations - Introduction