Categories
Vue and D3

Adding Graphics to a Vue App with D3 — Line Graph

Spread the love

D3 lets us add graphics to a front-end web app easily.

Vue is a popular front end web framework.

They work great together. In this article, we’ll look at how to add graphics to a Vue app with D3.

Graphs

We can add graphs to our Vue app with D3.

For example, we can write:

public/data.csv

year,population
2006,20
2008,35
2010,48
2012,51
2014,63
2016,23
2017,42

App.vue

<template>
  <div id="app"></div>
</template>
<script>
import * as d3 from "d3";
import Vue from "vue";

export default {
  name: "App",
  mounted() {
    Vue.nextTick(async () => {
      const margin = { top: 20, right: 20, bottom: 30, left: 50 },
        width = 960 - margin.left - margin.right,
        height = 500 - margin.top - margin.bottom;

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

      const valueline = d3
        .line()
        .x(function (d) {
          return x(d.year);
        })
        .y(function (d) {
          return y(d.population);
        });

      const svg = d3
        .select("body")
        .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})`);

      const data = await d3.csv("/data.csv");

      data.forEach(function (d) {
        d.population = +d.population;
      });

      x.domain(
        d3.extent(data, function (d) {
          return d.year;
        })
      );

      y.domain([
        0,
        d3.max(data, function (d) {
          return d.population;
        }),
      ]);

      svg
        .append("path")
        .data([data])
        .attr("class", "line")
        .attr("d", valueline);

      svg
        .append("g")
        .attr("transform", `translate(0, ${height})`)
        .call(d3.axisBottom(x));

      svg.append("g").call(d3.axisLeft(y));
    });
  },
};
</script>

<style>
.line {
  fill: none;
  stroke: green;
  stroke-width: 5px;
}
</style>

We have the data we read from in public/data.csv .

Then we create the graph by creating the constants for the width and height./

Then we add the x and y axes objects:

const margin = {
    top: 20,
    right: 20,
    bottom: 30,
    left: 50
  },
  width = 960 - margin.left - margin.right,
  height = 500 - margin.top - margin.bottom;

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

Then we create the line objects for the x and y axes by writing:

const valueline = d3
  .line()
  .x(function(d) {
    return x(d.year);
  })
  .y(function(d) {
    return y(d.population);
  });

Then we add the SVG into the body by writing:

const svg = d3
  .select("body")
  .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})`);

Then we read in the data that we want to display by writing:

const data = await d3.csv("/data.csv");

Next, we transform the read data by converting the population into numbers:

data.forEach(function(d) {
  d.population = +d.population;
});

Then we add callbacks to return the data for the x and y axes:

x.domain(
  d3.extent(data, function(d) {
    return d.year;
  })
);

y.domain([
  0,
  d3.max(data, function(d) {
    return d.population;
  }),
]);

Then we create the line for the line chart with:

svg
  .append("path")
  .data([data])
  .attr("class", "line")
  .attr("d", valueline);

Finally, we add the x and y axes with:

svg
   .append("g")
   .attr("transform", `translate(0, ${height})`)
   .call(d3.axisBottom(x));

svg.append("g").call(d3.axisLeft(y));

We have to add some styles to remove the width of the line and set the thickness of it:

<style>
.line {
  fill: none;
  stroke: green;
  stroke-width: 5px;
}
</style>

Now we should see a line graph displayed.

Conclusion

We can add a line graph with D3 into our Vue app.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *