dn.js is a lightweight javascript wrapper for d3.js, Leaflet and Google Maps. dn.js simplifies the production of n-dimensional, attractive, fast-to-load, interactive visualisations. With just a few lines of code, visualisations with bar charts, column charts, pie charts, line charts, maps and sankey diagrams can be produced, like the example below. The charts are all linked so that filtering one chart, automatically updates the other charts, based on the users selection.
The library is open-source - everything is available for download on GitHub - and is just 16kb gzipped (38kb minified and 235kb with documentation).
Here is a quick example of dn.js using (fictitious!) meal delivery data from 2018 and 2019 for selected cities in the UK. For more information, do also check out the other examples and explore the quick start guide below or the more detailed documentation.
Total deliveries shown:
Average rating (5 is best):
The example above is available in a JSFiddle. We have designed the code with simplicity, performance and usability in mind. The core lines of code comprise 15 to load and process the data, 6 to create the chart group and tweak the chart defaults, and 7 to draw the charts. Together with 4 to set the summary information, that's an interactive data visualisation in around 30 lines of code! Here is the code snippet to load and process our data:
// Instantiate our DNChartGroup and our pie/donut colour range, and the look up lists we will generate for the type of food, location of delivery and the dates
var chartGroup, lookupListFood, lookupListLocation, lookupListDate = null;
var pieColourRange = colourbrewer.IAPink[5].reverse();

function LoadData() {
    // Load the data using d3.csv
    d3.csv(urlData).then(function (data) {

        // Build the lookup lists for Food and location (dn is our DN object)
        lookupListFood = dn.BuildLookupList(data, "Food", 100);
        lookupListLocation = dn.BuildLookupList(data, "Location", 200);

        // Loop through and ensure that the raw data is numeric and set the codes for the food and location data
        data.map(d => {
            d.Count = +d.Count;
            d.FO = dn.GetObjInList(lookupListFood, "Title", d.Food).ID;
            d.RA = +d.RA;
            d.DA = +(d.Date.replace(/-/g, "")).substring(0,6);
            d.LO = dn.GetObjInList(lookupListLocation, "Title", d.Location).ID;
            return d;
        // Create the lookups for the dates
        lookupListDate = dn.GetYearMonthDescriptionList(dn.Unique(data.map(d => d.DA)));

        // Create the chart group
We then load the data into our DNChartGroup and adjust any default settings needed:
function CreateChartGroup(data) {
    // Create the chart group
    chartGroup = new DNChartGroup(data);

    // Setup the default font, hide the dropshadows and tweak the margins
    chartGroup.defaultFont = "Open Sans";
    dn.defaultPieDonutWidth = 30;
    dn.defaultPieDonutLegendRectangleSize = 16;
    dn.defaultBarChartMargins.right = 60;

Lastly, we create the charts:
function VisualiseData() {
    //--CHART-01-- Location
    new DNChart().BarChart("FO", "DataVis", chartGroup, 250, 0, 245, 240, 70, "BChart2", true, 30, "", lookupListFood, "Type of meal delivered", true); 
    //--CHART-02-- Draw a Sankey of Food versus Location
    new DNChart().SankeyChart("SA", "DataVis", chartGroup, 505, 0, 415, 240, true, colourbrewer.IAOrange[2], colourbrewer.IABlue[2], lookupListFood, lookupListLocation, "FO", "LO", "Food by Location", true); 
    //--CHART-03-- Location
    new DNChart().BarChart("LO", "DataVis", chartGroup, 930, 0, 245, 240, 70, "BChart1", true, 30, "", lookupListLocation, "Location of delivery", true); 
    //--CHART-04-- Rating
    new DNChart().PieChart("RA", "DataVis", chartGroup, 930, 250, 245, 250, 65, colourbrewer.IAPink[5].reverse(), null, "Rating of delivery", true);
    //--CHART-05-- Draw the data over time
    new DNChart().ColumnChart("DA", "DataVis", chartGroup, 0, 250, 920, 250, 10, "CChart5", false, 0, null, lookupListDate, "Date of delivery", true, true);  
    //--X06-- And lastly, lets show the summary
    d3.select("#VisSummary").style("left", 0 + "px").style("top", 0 + "px").style("width", 240 + "px").style("height", 240 + "px").style("display", "");
// This sets the summary info - it will be called each time the selections on the chart change.
function SetSummary() {
    if (dn.IsDefined(chartGroup)) {     
        // Calculate and present the total number of people currently being displayed
        let total = chartGroup.filteredJSData.reduce((acc, b) => acc + b.Count, 0);           
        // Calculate and present the average rating
        let avgRating = (total === 0) ? "--" : chartGroup.filteredJSData.reduce((acc, b) => acc + (b.Count * b.RA), 0) / total;
        d3.select("#AverageRating").html(dn.NumberWithNDP(avgRating, 1));
There's lots more to show, including adding logic to support responsiveness (look at the example above while resizing your browser), saving filter histories in your browser URL and our road map for development. First though, here is how to install it.

Getting started / prerequisites

To produce the interactive charts and maps, dn.js requires d3.js:
  1. d3.js - brings data to life using HTML, SVG, and CSS. d3.js (v5) is required for all dn.js visualisations.
In addition, for specific types of visualisations, the following freely available libraries are also required:
  1. Leaflet.js - for producing mobile-friendly, interactive maps.
  2. d3-sankey.js - for presenting Sankey diagrams.
Consider also these three freely available libraries to support animated visualisations, accessible colour ranges and faster download of large datasets:
  1. d3RangeSlider.js (minified version) - to create animated visualisations. This is adapted from this range slider by Rasmus Fonseca and is now included as an option in dn.js column charts, which is particularly useful for animating time-series data (see this example using refugee population data).
  2. ColourBrewer.js (minified version) - this is an extension of the colour schemes made available by Cynthia Brewer on colorbrewer2.org. It's very useful for creating accessible colour ranges (see the stock market example).
  3. JSZip - really useful when working with larger datasets, this library unzips zip archives in JavaScript and is also used in the example using refugee population data. It consists of two JavaScript files, JSZip handles the unzipping and JSZipUtils handles downloading the binary data.
Check out the documentation below on the four classes contained in dn.js: DN, DNChartGroup, DNChart and DNURLEditor.

Tutorials and documentation

Here is some more detailed guidance on each of the charts available, our roadmap for development and some hints and useful functions included in dn.js for data exploration and more: