Categories
Vue and D3

Adding Graphics to a Vue App with D3 — Arrays, Collections, and Elements

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.

Arrays

D3 has methods to let us work with an array of numbers easily.

For example, we can write:

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

export default {
  name: "App",
  mounted() {
    const data = [20, 40, 60, 80, 100];
    console.log(d3.min(data));
    console.log(d3.max(data));
    console.log(d3.extent(data));
    console.log(d3.sum(data));
    console.log(d3.mean(data));
    console.log(d3.quantile(data, 0.5));
    console.log(d3.variance(data));
    console.log(d3.deviation(data));
  },
};
</script>

We get the min value of the array with the d3.min method.

The max can be obtained from the d3.max method.

d3.extent returns the min and max of the array.

d3.sum returns the sum of the array values.

d3.mean returns the average of the array values.

d3.quantile returns the given quantile.

d3.variance returns the variance from the data.

d3.deviation returns the standard deviation of the data.

Collections API

We also work with objects with D3.

For example, we can write:

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

export default {
  name: "App",
  mounted() {
    const month = { jan: 1, Feb: 2, mar: 3, apr: 4 };
    console.log(d3.keys(month));
    console.log(d3.values(month));
    console.log(d3.entries(month));
  },
};
</script>

to get the keys, values, and key-value pairs from the month object respectively.

Selection API

We can select elements from the DOM and then style it our way.

For example, we can write:

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

export default {
  name: "App",
  mounted() {
    d3.select("p").style("color", "red");
  },
};
</script>

select selects the first p element from the DOM.

Then we call style to set its color to red.

Also, we can write:

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

export default {
  name: "App",
  mounted() {
    d3.selectAll("body").style("color", "red");
  },
};
</script>

Then we select all the body elements.

We can chain the methods.

For example, we can write:

<template>
  <div id="app">
    <p><b>hello</b></p>
  </div>
</template>
<script>
import * as d3 from "d3";

export default {
  name: "App",
  mounted() {
    const b = d3.selectAll("p").selectAll("b");
    console.log(b);
  },
};
</script>

We get the belement in the p element by chaining the selectAll method.

Also, we can filter elements that are selected with the filter method:

For instance, we can write:

<template>
  <div id="app">
    <table>
      <tr>
        <td>foo</td>
      </tr>
      <tr>
        <td>bar</td>
      </tr>
      <tr>
        <td>baz</td>
      </tr>
    </table>
  </div>
</template>
<script>
import * as d3 from "d3";

export default {
  name: "App",
  mounted() {
    const even = d3.selectAll("tr").filter(":nth-child(odd)");
    console.log(even);
  },
};
</script>

to get all the tr elements with even indexes.

We can merge the selections with the merge method:

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

export default {
  name: "App",
  mounted() {
    Vue.nextTick(() => {
      const width = 300;
      const height = 300;
      const svg = d3
        .select("#svgcontainer")
        .append("svg")
        .attr("width", width)
        .attr("height", height);
      const rect = svg
        .append("rect")
        .attr("x", 20)
        .attr("y", 20)
        .attr("width", 200)
        .attr("height", 100)
        .attr("fill", "green");

      const rect2 = svg
        .append("rect")
        .attr("x", 20)
        .attr("y", 20)
        .attr("width", 100)
        .attr("height", 100)
        .attr("fill", "blue");

      rect.enter().append("rect").merge(rect2);
    });
  },
};
</script>

We have 2 rectangles, rect and rect2 .

Then we have:

rect.enter().append("rect").merge(rect2);

to combine the 2 rectangles together.

Now we see the blue and green rectangles side by side.

Conclusion

We can work with arrays, objects, and DOM elements with D3 in Vue apps.

Categories
Vue and D3

Adding Graphics to a Vue App with D3 — Line Graph

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.

Categories
Vue and D3

Adding Graphics to a Vue App with D3 — Pie Chart

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.

Pie Chart

We can add a pie chart with D3 into our Vue app.

For example, we can write:

public/populations.csv

states,percent
California,38.00
New York,18.00
Texas,20.0

App.vue

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

export default {
  name: "App",
  mounted() {
    Vue.nextTick(async () => {
      const svg = d3.select("svg"),
        width = svg.attr("width"),
        height = svg.attr("height"),
        radius = Math.min(width, height) / 2;

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

      const color = d3.scaleOrdinal(["gray", "green", "brown"]);

      const pie = d3.pie().value(function (d) {
        return d.percent;
      });

      const path = d3
        .arc()
        .outerRadius(radius - 10)
        .innerRadius(0);

      const label = d3
        .arc()
        .outerRadius(radius)
        .innerRadius(radius - 80);

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

      const arc = g
        .selectAll(".arc")
        .data(pie(data))
        .enter()
        .append("g")
        .attr("class", "arc");

      arc
        .append("path")
        .attr("d", path)
        .attr("fill", function (d) {
          return color(d.data.states);
        });

      arc
        .append("text")
        .attr("transform", function (d) {
          return `translate(${label.centroid(d)})`;
        })
        .text(function (d) {
          return d.data.states;
        });

      svg
        .append("g")
        .attr("transform", `translate(${width / 2 - 120},20)`)
        .append("text")
        .text("Top population states in the US")
        .attr("class", "title");
    });
  },
};
</script>

<style scoped>
.arc text {
  font: 12px arial;
  text-anchor: middle;
}

.arc path {
  stroke: #fff;
}

.title {
  fill: green;
  font-weight: italic;
}
</style>

We start by getting the svg element and setting the width , height and radius of the pie chart:

const svg = d3.select("svg"),
  width = svg.attr("width"),
  height = svg.attr("height"),
  radius = Math.min(width, height) / 2;

Then we translate the svg by writing:

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

Next, we add the colors for the pie chart by writing;

const color = d3.scaleOrdinal(["gray", "green", "brown"]);

Then we add the data for the pie chunk by writing:

const pie = d3.pie().value(function(d) {
  return d.percent;
});

Next, we create the arcs for the pie chart by writing

const path = d3
  .arc()
  .outerRadius(radius - 10)
  .innerRadius(0);

Then we create the labels by writing:

const label = d3
  .arc()
  .outerRadius(radius)
  .innerRadius(radius - 80);

Then we read the data from populations.csv :

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

Then we set the lengths of the arcs with the read data by writing:

const arc = g
  .selectAll(".arc")
  .data(pie(data))
  .enter()
  .append("g")
  .attr("class", "arc");

Then we set the fill color of the pie chunks by writing:

arc
  .append("path")
  .attr("d", path)
  .attr("fill", function(d) {
    return color(d.data.states);
  });

Then we add the text for the pie chunks by writing:

arc
  .append("text")
  .attr("transform", function(d) {
    return `translate(${label.centroid(d)})`;
  })
  .text(function(d) {
    return d.data.states;
  });

And finally, we add the title text for the graph by writing:

svg
  .append("g")
  .attr("transform", `translate(${width / 2 - 120},20)`)
  .append("text")
  .text("Top population states in the US")
  .attr("class", "title");

Now we should see a pie chart displayed.

Conclusion

We can add a pie chart with D3 into our Vue app.

Categories
Vue and D3

Adding Graphics to a Vue App with D3 — Circle Chart

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.

Circle Chart

We can add a circle into our Vue app with D3.

To do this, we write:

<template>
  <div id="app">
    <div id="svgcontainer"></div>
  </div>
</template>
<script>
import * as d3 from "d3";
import Vue from "vue";
export default {
  name: "App",
  mounted() {
    Vue.nextTick(() => {
      const width = 400;
      const height = 400;
      const data = [10, 24, 35];
      const colors = ["green", "lightblue", "yellow"];

      const svg = d3
        .select("body")
        .append("svg")
        .attr("width", width)
        .attr("height", height);

      const g = svg
        .selectAll("g")
        .data(data)
        .enter()
        .append("g")
        .attr("transform", function (d, i) {
          return "translate(0,0)";
        });

      g.append("circle")
        .attr("cx", function (d, i) {
          return i * 75 + 50;
        })
        .attr("cy", function (d, i) {
          return 75;
        })
        .attr("r", function (d) {
          return d * 1.5;
        })
        .attr("fill", function (d, i) {
          return colors[i];
        });

      g.append("text")
        .attr("x", function (d, i) {
          return i * 75 + 25;
        })
        .attr("y", 80)
        .attr("stroke", "teal")
        .attr("font-size", "10px")
        .attr("font-family", "sans-serif")
        .text(function (d) {
          return d;
        });
    });
  },
};
</script>

We start by creating the constants for the SVG with the width and height variables.

The data has the data we want to display.

colors have the color for each circle.

We use the width and height to create the SVG with:

const svg = d3
  .select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height);

Then we add the SVG group g with:

const g = svg
  .selectAll("g")
  .data(data)
  .enter()
  .append("g")
  .attr("transform", function(d, i) {
    return "translate(0,0)";
  });

Then we add the circles with:

g.append("circle")
  .attr("cx", function(d, i) {
    return i * 75 + 50;
  })
  .attr("cy", function(d, i) {
    return 75;
  })
  .attr("r", function(d) {
    return d * 1.5;
  })
  .attr("fill", function(d, i) {
    return colors[i];
  });

We set the cx and cy attributes to add the x and y coordinates of the center of the circles.

Then we add the r attribute to add the radius. The radius is proportional to the number in data so if the number is bigger, the radius is bigger.

Then fill is an entry in the colors array.

Finally, we add the number display with:

g.append("text")
  .attr("x", function(d, i) {
    return i * 75 + 25;
  })
  .attr("y", 80)
  .attr("stroke", "teal")
  .attr("font-size", "10px")
  .attr("font-family", "sans-serif")
  .text(function(d) {
    return d;
  });

The text’s x and y attributes are the x and y coordinates of the position of the text.

stroke has the text color.

font-size is the size of the font. font-family is the font type.

text has a callback that returns the text to display.

Conclusion

We can add a circle chart into our Vue app with D3.

Categories
Vue and D3

Adding Graphics to a Vue App with D3

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.

Getting Started

We install D3 by running npm i d3 .

Then we can use it in our Vue app.

Data Join

Now that we installed D3, we can use it in our app.

D3 lets us render an array of items into a list easily.

To do this, we write:

<template>
  <div id="app">
    <ul id="list">
      <li v-for="n of arr.length"></li>
    </ul>
  </div>
</template>

<script>
import * as d3 from "d3";
import Vue from "vue";

export default {
  name: "App",
  data() {
    return {
      arr: [10, 20, 30, 25, 15],
    };
  },
  mounted() {
    Vue.nextTick(() => {
      d3.select("#list")
        .selectAll("li")
        .data(this.arr)
        .text((d) => d);
    });
  },
};
</script>

to render the numbers in arr into the li elements.

d3.select selects the ul with ID list .

Then we call selectAll to select all the li s inside.

And then we call data to return the data.

And text to set the text of each li .

Now the numbers should be in the list.

The D3 code is in the Vue.nextTick callback so that we get the li s after they’re rendered.

SVG

We can add SVGs in a Vue app with D3.

For example, we can write:

<template>
  <div id="app">
    <div id="svgcontainer"></div>
  </div>
</template>

<script>
import * as d3 from "d3";
import Vue from "vue";

export default {
  name: "App",
  mounted() {
    Vue.nextTick(() => {
      const width = 300;
      const height = 300;
      const svg = d3
        .select("#svgcontainer")
        .append("svg")
        .attr("width", width)
        .attr("height", height);
      svg
        .append("line")
        .attr("x1", 100)
        .attr("y1", 100)
        .attr("x2", 200)
        .attr("y2", 200)
        .style("stroke", "rgb(255,0,0)")
        .style("stroke-width", 2);
    });
  },
};
</script>

We select the div with ID svgcontainer .

Then we set with the width and height of the svg with the attr method.

Then we add a line with the append method with the 'line' argument.

We set the x1 and y1 attributes to add the x and y coordinates of the start of the line.

And we do the same with the end of the line with the x2 and y2 attributes.

The style method sets the styles.

stroke sets the line color and stroke-width sets the line width.

Rectangle

We can add a rectangle by calling the append method with the 'rect' argument:

<template>
  <div id="app">
    <div id="svgcontainer"></div>
  </div>
</template>

<script>
import * as d3 from "d3";
import Vue from "vue";

export default {
  name: "App",
  mounted() {
    Vue.nextTick(() => {
      const width = 300;
      const height = 300;
      const svg = d3
        .select("#svgcontainer")
        .append("svg")
        .attr("width", width)
        .attr("height", height);
      svg
        .append("rect")
        .attr("x", 20)
        .attr("y", 20)
        .attr("width", 200)
        .attr("height", 100)
        .attr("fill", "green");
    });
  },
};
</script>

Then we set the x and y attributes to add the x and y coordinates of the top left corner of the rectangle.

And we call attr with 'width' and 'height' to set the width and height of the rectangle.

'fill' sets the background color of the rectangle.

Conclusion

We can add basic shapes to our Vue app with D3.