Categories
Introducing Britecharts, Eventbrite's Reusable Charting Library Based on D3
Last published on April 10, 2017 by Marcos Iglesias
This article was originally posted on the Eventbrite Engineering Blog.
The usual workflow when developing interactive data visualizations with D3.js is based on the significant number of examples that the D3 community provides. They are broad and useful, but they are still not ideal. Most of the time, they require a lot of effort to integrate into your code and to make them production-ready. In a previous series of posts about Leveling Up D3, I talked about a different way of building D3.js charts, using the Reusable API, building our components via TDD and improving them with events and refactorings. Following those ideas, and with the help of Eventbrite's design team, we have been working on our chart library, and now we want to share it with you. It’s called Britecharts.
What is Britecharts?
Britecharts is a client-side reusable Charting Library based on D3.js v4 that allows an easy and intuitive use of charts and components that can be composed, creating beautiful visualizations.
The idea behind Britecharts is twofold: first, we want to allow developers and designers with little experience with D3.js to build great interactive charts with little initial effort. Second, we want to propose a framework for helping D3.js developers to create new D3.js charts by following standards like the Reusable API and Test Driven Development.
What problem does Britecharts solve?
The project is just an implementation of the Reusable Chart API. As such, it solves the problems of regular D3.js charts, namely, lack of modularity, high complexity, low re-usability and poor testability. We also wanted to accomplish this with an eye for aesthetics so that anybody could have a beautiful chart working out of the box. Our project also offers the set-up necessary to create charts on a TDD basis as well as a playground for polishing and manually testing them.
Rendering your first BriteChart
For installing the library, you can use NPM or Bower to install the individual JavaScript files and CSS stylesheets (we are getting ready a bundled version to be downloaded via CDN). Here we see an example using NPM: npm install britecharts npm install d3
Then, you will load the dependencies this way on your ES2015 project:
import * as d3 from "d3";
import bar from "britecharts/dist/umd/bar.min.js";
Next up we will create your first chart. We will start with the data definition. Here, we have a piece of data:
const data = [
{ name: "Radiating", value: 0.08167 },
{ name: "Opalescent", value: 0.0492 },
{ name: "Shining", value: 0.02782 },
{ name: "Vibrant", value: 0.04253 },
{ name: "Vivid", value: 0.02702 },
{ name: "Brilliant", value: 0.02288 },
];
This data is the result of an imaginary poll we made around our team at Eventbrite. As it is category data, we will use a horizontal bar chart to represent it. Once we choose the chart type, we want to check out the required data entries for it. We do this by navigating to the global section of the docs and searching for the bar chart. Here, we see that the right data format should be:
[
{ value: 1, name: "glittering" },
{ value: 1, name: "luminous" },
];
Our original data format is pretty much the same, so we won’t need to transform the data. To plug our chart inside a container div that we previously created on our HTML, we will need to type:
let barChart = new bar();
let barContainer = d3.select(‘.js-container’);
let containerWidth = barContainer.node() ? barContainer.node().getBoundingClientRect().width : false;
barChart
.margin({
left: 120,
right: 20,
top: 20,
bottom: 5
})
.horizontal(true)
.usePercentage(true)
.percentageAxisToMaxRatio(1.3)
.width(containerWidth)
.height(300);
barContainer.datum(data).call(barChart);
And using a template that includes Britecharts styles and the chart container:
[...]
<link
rel="stylesheet"
href="node_modules/britecharts/dist/css/britecharts.min.css"
/>
the previous code will render:
Every chart has a series of properties that are public, in this case: horizontal, width, valueLabel and height. You can find them on each chart's API menu on the docs homepage. Here is the Bar Chart API.
Responsive Charts
Once we have our data visualization rendering, we usually want to make our charts responsive. In order to achieve this, we will first set up a listener to the ‘window.resize’ event and trigger a redraw when that happens.
const redrawCharts = () => {
let barContainer = d3.select(‘.js-container’);
let newContainerWidth = barContainer.node() ? barContainer.node().getBoundingClientRect().width : false;
// Setting the new width on the chart
barChart.width(newContainerWidth);
// Rendering the chart again
barContainer.datum(data).call(barChart);
};
const throttledRedraw = _.throttle(redrawCharts, 200);
window.addEventListener("resize", throttledRedraw);
It is also useful to throttle
that event so that we don’t redraw our chart a considerable number of times, as this event triggers many times with every resize
event. For this, we will use a util library like underscore or lodash.
Advanced Settings
Now that we have a responsive chart, we will use other components to add more functionality. In this case, we will add a tooltip to our chart. The bar chart and other Britecharts have some mouse events attached to their elements and exposed through custom named events. This way, when we hover with our mouse (or tap on mobile devices), a custom event will be triggered. We can easily hook up a handler function, whose code will look like this:
...
import miniTooltip from 'britecharts/dist/umd/mini-tooltip.min.js';
let tooltip = new miniTooltip();
let barChart = new bar();
let barContainer = d3.select('.js-bar-chart-container');
let containerWidth = barContainer.node() ? barContainer.node().getBoundingClientRect().width : false;
barChart
.margin({
left: 120,
right: 20,
top: 20,
bottom: 5
})
.horizontal(true)
.usePercentage(true)
.percentageAxisToMaxRatio(1.3)
.width(containerWidth)
.height(300)
.on('customMouseOver', tooltip.show)
.on('customMouseMove', tooltip.update)
.on('customMouseOut', tooltip.hide);
let tooltipContainer = d3.select('.bar-chart .metadata-group');
tooltipContainer.datum([]).call(miniTooltip);
And that’s it! The tooltip is working!
Styling
Depending on the number of charts you will use, you could either load the whole bundle of styles or load the styles of different charts plus the common styles. The bundled configurations and split charts and styles can be found in the dist/
folder. We can add additional styles to our chart in different ways. Britecharts provides some color palettes that you can use for the bars, and you can also style the SVG elements with CSS, either overriding the original styles or by simply starting again from scratch.
Let’s see an example:
import colors from 'britecharts/dist/umd/colors.min.js';
[...]
barChart.colorSchema(colors.colorSchemas.extendedOrangeColorSchema);
[...]
barContainer.datum(data).call(barChart);
Will render an orange themed bar chart:
Remember that you could also create animations for the SVG paths, using dashed lines or making them move, grow or anything else that you can think of! Read more in this great article by Sara Soueidan
When Britecharts is not for you
We have tried to achieve a healthy balance between ease of use for both nontechnical people and D3.js specialists alike. Still, if you are going to need just one chart to customize deeply and never use again, maybe the example-based approach will work better for you.
Looking ahead
We are super excited about the launch of Britecharts and want to hear your opinions on it! Any feedback about the documentation, complexity, customization options and ease of use are highly appreciated. With Britecharts, we hope to help newcomers to the D3 community to structure their charts and test them efficiently. Our goal is for it to become a library of high-quality, tested data visualizations.
Resources
- Documentation homepage - More information about the library
- Chart Demos - Check the available charts and some styling examples
- Github repository - Wander in the code and contribute by giving your opinion on proposals
Contributing
If you are excited about Britecharts, want to add more configurable properties or even create your own chart, please check our Contributing Guide. In it, we walk you through the development environment setup, run our docs and demos and create new Pull Requests.