D3.js

Updated: 2018-11-30

SVG vs Canvas

Common

const width = 960,
  height = 600;

const scale = height / 4;

const projection = d3.geoMercator()
  .translate([width / 2, height / 2])
  .scale(scale);

const data = ...; // geojson or topojson

SVG

const path = d3.geoPath().projection(projection);

const map = d3
  .select("#map")
  .append("svg")
  .attr("width", width)
  .attr("height", height);

map
  .append("path")
  .datum(data)
  .attr("class", "land")
  .attr("d", path);

Canvas

const path = d3
  .geoPath()
  .projection(projection)
  .context(context);

const canvas = d3
  .select("#map")
  .append("canvas")
  .attr("width", width)
  .attr("height", height);

const context = canvas.node().getContext("2d");

context.beginPath();
path(data);
context.fillStyle = "#DDD";
context.fill();
context.closePath();

D3 Scales

D3 scales can be use not only for data viz

  • Domain: input
  • Range: output

Scale map from input(domain) to output(range)

  • Time: d3.time.scale()
  • Linear: d3.scale.linear()
  • Log: d3.scale.log()

E.g.

var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);

x.domain(
  d3.extent(data, function(d) {
    return d.date;
  })
);
y.domain([
  0,
  d3.max(data, function(d) {
    return d.close;
  })
]);

Update Axis

svg.selectAll("g .y.axis").call(yAxis);

Remove

d3.select("svg").remove();

Date Format

To Create formats:

var rawFormat = d3.time.format("%Y%m%d%H%M");
var newFormat = d3.time.format("%Y-%m-%d  %H:%M");

To parse the data:

// timestamp is a string like "201809010805", this returns a Date object
var date = rawFormat.parse(timestamp);

To convert a Date object to string

// return a string like "2018-09-01  08:05"
var str = newFormat(date);

https://github.com/d3/d3/blob/master/API.md#time-formats-d3-time-format

Add Grid Lines

// function to generate axis(the axis is essentially a function)
function getYAxis() {
  return d3.svg
    .axis()
    .scale(y)
    .orient("left");
}

// Add initial Y Axis with ticks
svg
  .append("g")
  .attr("class", "y axis")
  .call(getYAxis());

// Add initial grid line(dummy Y Axis)
svg
  .append("g")
  .attr("class", "grid-line")
  .call(
    getYAxis()
      .tickFormat("") // Hide tick text
      .tickSize(-width, 0, 0) // Set tick width so it expands all the way to the right
  );

function updateChart(data) {
  svg.selectAll("g .y.axis").call(getYAxis());

  svg.selectAll("g .grid-line").call(
    getYAxis()
      .tickFormat("")
      .tickSize(-width, 0, 0)
  );
}