Categories
Vue and D3

Adding Graphics to a Vue App with D3 — Axis and Arcs

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.

Axis API

We can use the axis API to add the axes for graphs.

For example, we can write:

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

export default {
  name: "App",
  mounted() {
    Vue.nextTick(() => {
      const width = 400,
        height = 400;
      const data = [100, 120, 140, 160, 180, 200];
      const svg = d3
        .select("body")
        .append("svg")
        .attr("width", width)
        .attr("height", height);

      const xscale = d3
        .scaleLinear()
        .domain([0, d3.max(data)])
        .range([0, width - 100]);

      const yscale = d3
        .scaleLinear()
        .domain([0, d3.max(data)])
        .range([height / 2, 0]);

      const xAxis = d3.axisBottom().scale(xscale);
      const yAxis = d3.axisLeft().scale(yscale);
      svg.append("g").attr("transform", "translate(50, 10)").call(yAxis);
      const xAxisTranslate = height / 2 + 10;

      svg
        .append("g")
        .attr("transform", `translate(50, ${xAxisTranslate})`)
        .call(xAxis);
    });
  },
};
</script>

We add the value for the y-axis with the data array.

width and height has the width and height of the graph.

Then we create scale for the x-axis by writing:

const xscale = d3
  .scaleLinear()
  .domain([0, d3.max(data)])
  .range([0, width - 100]);

We create the scale for the y-axis with:

const yscale = d3
  .scaleLinear()
  .domain([0, d3.max(data)])
  .range([height / 2, 0]);

The axes show the values between the min and max value that we pass into domain .

We create the axes with:

const xAxis = d3.axisBottom().scale(xscale);
const yAxis = d3.axisLeft().scale(yscale);

Then we add the y-axis to the graph with:

svg.append("g").attr("transform", "translate(50, 10)").call(yAxis);

And we add the x-axis with:

svg
  .append("g")
  .attr("transform", `translate(50, ${xAxisTranslate})`)
  .call(xAxis);

Shapes

We can add shapes with D3 into our Vue app.

d3.arc generates an arc.

For example, we can write:

<template>
  <div id="app">
    <svg width="400" height="300"></svg>
  </div>
</template>
<script>
import * as d3 from "d3";
import Vue from "vue";

export default {
  name: "App",
  mounted() {
    Vue.nextTick(() => {
      const arc = d3.arc().innerRadius(50).outerRadius(40).cornerRadius(15);

      const svg = d3.select("svg"),
        width = +svg.attr("width"),
        height = +svg.attr("height"),
        g = svg
          .append("g")
          .attr("transform", `translate(${width / 2} , ${height / 2})`);

      const data = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89];
      const arcs = d3.pie()(data);
      g.selectAll("path")
        .data(arcs)
        .enter()
        .append("path")
        .style("fill", function (d, i) {
          return d3.color(`hsl(120, 50%, ${d.value}%)`);
        })
        .attr("d", arc);
    });
  },
};
</script>

to create an arc with the d3.arc function:

const arc = d3.arc().innerRadius(50).outerRadius(40).cornerRadius(15);

Then we get the dimensions from the SVG and create the arc group:

const svg = d3.select("svg"),
  width = +svg.attr("width"),
  height = +svg.attr("height"),
  g = svg
  .append("g")
  .attr("transform", `translate(${width / 2} , ${height / 2})`);

Then set create the data we want to display:

const data = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89];

Next, we load the data into the data.pie method to create the arcs for each segment of the pie:

const arcs = d3.pie()(data);

And finally, we show the arcs with the given colors by writing:

g.selectAll("path")
  .data(arcs)
  .enter()
  .append("path")
  .style("fill", function(d, i) {
    return d3.color(`hsl(120, 50%, ${d.value}%)`);
  })
  .attr("d", arc);

Conclusion

We can add axes and arcs 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 *