Skip to content

Instantly share code, notes, and snippets.

@seth-shaw-unlv
Created February 20, 2021 04:51
Show Gist options
  • Save seth-shaw-unlv/9d77a6e4dd2f97baa90eac5f68a699f4 to your computer and use it in GitHub Desktop.
Save seth-shaw-unlv/9d77a6e4dd2f97baa90eac5f68a699f4 to your computer and use it in GitHub Desktop.
D3.js Charts

Line Chart

Data (fig-1.csv)

item_count	stark	bartik	carapace	drupal8_parallax_theme
1462	3.074	3.251	3.480	3.160
107384	8.625	8.990	9.214	8.849
338947	19.573	17.215	17.740	17.272

HTML

<script src="https://d3js.org/d3.v6.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<div id="chart"></div>

JavaScript

  // set the dimensions and margins of the graph
  var margin = {
      top: 10,
      right: 10,
      bottom: 30,
      left: 40
    },
    width = 600 - margin.left - margin.right,
    height = 400 - margin.top - margin.bottom;

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

  // append the svg object to the chart div
  var svg = d3.select("#chart")
    .append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform",
      "translate(" + margin.left + "," + margin.top + ")");

  //Read the data
  d3.tsv("/files/fig-2.csv", function(d) {
    return {
      item_count: +d.item_count,
      stark: +d.stark,
      bartik: +d.bartik,
      carapace: +d.carapace,
      drupal8_parallax_theme: +d.drupal8_parallax_theme
    };
  }).then(function(data) {

    // Legend and Axes placement
    var legendDotSize = 25;
    var xAxisHeight = height - 80;
    var legendStartheight = xAxisHeight + legendDotSize * 1.75;
    var themes = ["stark", "bartik", "carapace", "drupal8_parallax_theme"];
    var legendItemsPerCol = themes.length / 2;

    // Add X axis
    var x = d3.scaleLinear().domain(d3.extent(data, function(d) {
        return d.item_count;
      }))
      .range([0, width]);
    svg.append("g")
      .attr("transform", "translate(0," + xAxisHeight + ")")
      .call(d3.axisBottom(x));

    // Add Y axis
    var y = d3.scaleLinear()
      .domain([0, d3.max(data, function(d) {
        return [d.stark, d.bartik, d.carapace, d.drupal8_parallax_theme].reduce(function(a, b) {
          return Math.max(a, b);
        })
      })])
      .range([xAxisHeight, 0]);
    svg.append("g")
      .call(d3.axisLeft(y));

    // Usually you have a color scale in your chart already
    var color = d3.scaleOrdinal()
      .domain(themes)
      .range(d3.schemeDark2);

    themes.forEach(function(item, index) {
      // line
      svg.append("path")
        .datum(data)
        .attr("fill", "none")
        .attr("stroke", color(index))
        .attr("stroke-width", 3)
        .attr("d", d3.line()
          .x(function(d) {
            return x(d.item_count)
          })
          .y(function(d) {
            return y(d[item])
          })
        );
      // dots
      svg.selectAll("dots")
        .data(data)
        .enter()
        .append("circle")
        .attr("fill", color(index))
        .attr("stroke", "none")
        .attr("cx", function(d) {
          return x(d.item_count)
        })
        .attr("cy", function(d) {
          return y(d[item])
        })
        .attr("r", 3)

      // legend dots
      svg.selectAll("mydots")
        .data(themes)
        .enter()
        .append("circle")
        .attr("cx", (width * 0.45) * (index / legendItemsPerCol | 0) + 10)
        .attr("cy", function(d) {
          return legendStartheight + (index % legendItemsPerCol) * legendDotSize
        })
        .attr("r", 7)
        .style("fill", function(d) {
          return color(index)
        })

      // legend labels
      svg.selectAll("mylabels")
        .data(themes)
        .enter()
        .append("text")
        .attr("x", (width * 0.45) * (index / legendItemsPerCol | 0) + legendDotSize)
        .attr("y", function(d) {
          return legendStartheight + (index % legendItemsPerCol) * (legendDotSize)
        })
        .style("fill", function(d) {
          return color(index)
        })
        .text(function(d) {
          return item
        })
        .attr("text-anchor", "left")
        .style("alignment-baseline", "middle")
    });

  });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment