Categories
Vue and D3

Adding Graphics to a Vue App with D3 — Drag and Drop, Zoom, and CSV

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.

Drag and Drop

We can add drag and drop to our Vue app with D3 easily.

For example, we can write:

<template>
  <div id="app">
    <svg>
      <g>
        <rect x="40" y="10" width="50" height="50" fill="teal"></rect>
      </g>
    </svg>
  </div>
</template>
<script>
import * as d3 from "d3";
import Vue from "vue";

export default {
  name: "App",
  mounted() {
    Vue.nextTick(() => {
      d3.select("g")
        .datum({
          x: 0,
          y: 0,
        })
        .call(
          d3.drag().on("drag", function (d) {
            d3.select(this).attr("transform", `translate(${d.x} , ${d.y})`);
          })
        );
    });
  },
};
</script>

We have an SVG with a rectangle inside.

In the nextTick callback, we call d3.select to get the g element.

And then we call datum to set the x and y coordinates of the top left corner.

And then we call the call method by passing in the d3.drag().on method into the call method.

The callback gets the element we’re dragging with this .

And then we set the transform attribute to the drag position.

Zooming

We can add a zoom feature to shapes.

With it, we can use the mouse wheel to zoom in and out of an SVG.

For example, we can write:

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

export default {
  name: "App",
  mounted() {
    Vue.nextTick(() => {
      const svg = d3
        .select("#zoom")
        .append("svg")
        .attr("width", 460)
        .attr("height", 460)
        .call(
          d3.zoom().on("zoom", function (d) {
            svg.attr("transform", d.transform);
          })
        )
        .append("g");

      svg
        .append("circle")
        .attr("cx", 100)
        .attr("cy", 100)
        .attr("r", 40)
        .style("fill", "#68b2a1");
    });
  },
};
</script>

We have a div with ID zoom .

In the nextTick callback, we get the div and then add the svg element into it.

Then we call the call method with the d3.zoom method so that we can watch for zoom.

The d.transform has the string to change the size according to how much we zoom in or out.

Then we add the circle that we can zoom in and out.

cx and cy has the x and y coordinates of the center.

r has the radius.

style has the fill style.

Read Comma-Separated Values

We can read data from formatted data directly.

For example, we can write:

<template>
  <div id="app"></div>
</template>
<script>
import * as d3 from "d3";
const string = `year,population\n2011,10\n2012,20\n2013,30\n`;
export default {
  name: "App",
  mounted() {
    const data = d3.csvParse(string, function (d) {
      return {
        year: new Date(+d.year, 0, 1),
        population: d.population,
      };
    });
    console.log(data);
  },
};
</script>

to parse a CSV string with d3.csvParse .

The callback lets us return the transformed data after reading it.

d has the entry read and we return what we want as the new value of the entry.

Conclusion

We can add drag and drop, zooming, and read CSV strings with D3 in 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 *