Annotating charts with d3.js





Annotating a chart is a crucial step for an insightful dataviz. This document is dedicated to d3-annotation, a d3.js library for annotation. This library has been created by Susie Lu and its documentation is truly awesome.

Minimal example



Notes:

  • This is a minimal example describing how to use d3-annotation. You can edit the code beside to see what happens.

  • Here, one annotation is created. Its features are stored in an object called annotations created at the beginning of the script. At the very least, you have to specify the position of the thing to annotate (x and y), and the text position (dx and dy).

  • Finally, the d3.annotation() is called to effectively build the annotation.
<!DOCTYPE html>
<meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>

<!-- Load d3-annotation -->
<script src="https://rawgit.com/susielu/d3-annotation/master/d3-annotation.min.js"></script>

<!-- Create a div where the graph will take place -->
<svg width="460" height="400" id="example1"></svg>

<script>

// Features of the annotation
const annotations = [
  {
    note: {
      label: "Here is the annotation label",
      title: "Annotation title"
    },
    x: 100,
    y: 100,
    dy: 100,
    dx: 100
  }
]

// Add annotation to the chart
const makeAnnotations = d3.annotation()
  .annotations(annotations)
d3.select("#example1")
  .append("g")
  .call(makeAnnotations)


</script>

Custom the note (~ the text)



Notes:

  • The note is the part with the text and the border around it.

  • You can customize it providing parameters in the note section of the annotation object.
<!DOCTYPE html>
<meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>

<!-- Load d3-annotation -->
<script src="https://rawgit.com/susielu/d3-annotation/master/d3-annotation.min.js"></script>

<!-- Create a div where the graph will take place -->
<svg width="460" height="400" id="example2"></svg>

<script>

// Features of the annotation
const annotations = [
  {
    note: {
      label: "Here is the annotation label",
      title: "Annotation title",
      align: "middle",  // try right or left
      wrap: 200,  // try something smaller to see text split in several lines
      padding: 10   // More = text lower
    },
    color: ["#69b3a2"],
    x: 160,
    y: 160,
    dy: 100,
    dx: 100
  }
]

// Add annotation to the chart
const makeAnnotations = d3.annotation()
  .annotations(annotations)
d3.select("#example2")
  .append("g")
  .call(makeAnnotations)


</script>

Custom the connector



Notes:

  • The connector makes the link between the subject and the note.

  • You can customize it through 2 main ways: i/ option in the connector part of the annotations object or ii/ using css.
<!DOCTYPE html>
<meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>

<!-- Create a div where the graph will take place -->
<svg width="460" height="400" id="example3"></svg>

<script>

// ==== LEFT ====== //
const annotations = [
  {
    note: {
      label: "Here is the annotation label",
      title: "Annotation title"
    },
    connector: {
      end: "dot",        // Can be none, or arrow or dot
      type: "line",      // ?? don't know what it does
      lineType : "vertical",    // ?? don't know what it does
      endScale: 10     // dot size
    },
    color: ["grey"],
    x: 40,
    y: 160,
    dy: 70,
    dx: 70
  }
]

// Add annotation to the chart
const makeAnnotations = d3.annotation()
  .annotations(annotations)
d3.select("#example3")
  .append("g")
  .call(makeAnnotations)


// ==== RIGHT ====== //
const annotationsRight = [
  {
    note: {
      label: "Here is the annotation label",
      title: "Annotation title"
    },
    connector: {
      end: "arrow",        // none, or arrow or dot
      type: "curve",       // Line or curve
      points: 3,           // Number of break in the curve
      lineType : "horizontal"
    },
    color: ["purple"],
    x: 250,
    y: 160,
    dy: 70,
    dx: 70
  }
]

// Add annotation to the chart
const makeAnnotationsRight = d3.annotation()
  .annotations(annotationsRight)
d3.select("#example3")
  .append("g")
  .call(makeAnnotationsRight)


// ==== CHANGE STYLE ATTRIBUTE ====== //
d3.select("#example3").selectAll(".connector")
  .attr('stroke', "blue")
  .style("stroke-dasharray", ("3, 3"))
d3.select("#example3").selectAll(".connector-end")
  .attr('stroke', "blue")
  .attr('fill', "blue")

</script>

Custom the subject



Notes:

  • Several types of annotation are available. In the examples above, the default type d3.annotationLabel was used. It does not display anything for the subject.

  • It is possible to highlight the zone of interest (=the subject) with a circle or a rectangle using d3.annotationCalloutCircle or d3.annotationCalloutRect as shown beside.
<!DOCTYPE html>
<meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>

<!-- Create a div where the graph will take place -->
<svg width="460" height="400" id="example4"></svg>

<script>

// ==== LEFT ====== //
const annotations = [
  {
    note: {
      label: "Here is the annotation label",
      title: "Annotation title"
    },
    type: d3.annotationCalloutCircle,
    subject: {
      radius: 20,         // circle radius
      radiusPadding: 20   // white space around circle befor connector
    },
    color: ["red"],
    x: 40,
    y: 160,
    dy: 70,
    dx: 70
  }
]

// Add annotation to the chart
const makeAnnotations = d3.annotation()
  .annotations(annotations)
d3.select("#example4")
  .append("g")
  .call(makeAnnotations)


// ==== RIGHT ====== //
const annotationsRight = [
  {
    note: {
      label: "Here is the annotation label",
      title: "Annotation title"
    },
    type: d3.annotationCalloutRect,
    subject: {
      width: 60,
      height: 60
    },
    x: 220,
    y: 130,
    dy: 100,
    dx: 100
  }
]

// Add annotation to the chart
const makeAnnotationsRight = d3.annotation()
  .annotations(annotationsRight)
d3.select("#example4")
  .append("g")
  .call(makeAnnotationsRight)

</script>