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.

Categories
Vue and D3

Adding Graphics to a Vue App with D3 — Circle, Ellipse, and Transforms

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 Element

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

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("circle")
        .attr("cx", 200)
        .attr("cy", 50)
        .attr("r", 20)
        .attr("fill", "lightgreen");
    });
  },
};
</script>

to add the circle.

We create the svg element with the d3.select method.

We select the div with ID svgcontainer .

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

Then we add the circle by calling append with the 'circle' argument.

And we set the x and y coordinates of the center of the circle with the attr method.

'cx' sets the x coordinate of the center.

And 'cy' sets the y coordinate of the center.

'fill' sets the background color of the circle.

'r' sets the radius of the circle.

Ellipse Element

To add an ellipse, we can do something similar.

For instance, 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("ellipse")
        .attr("cx", 200)
        .attr("cy", 50)
        .attr("rx", 100)
        .attr("ry", 50)
        .attr("fill", "lightgreen");
    });
  },
};
</script>

We changed 'circle' to 'ellipse' .

Then we add the 'rx' and 'ry' attributes instead of 'r' .

'rx' sets the horizontal radius and 'ry' sets the vertical radius.

SVG Transformation

We can transform SVGs 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);

      const group = svg
        .append("g")
        .attr("transform", "translate(60, 60) rotate(30)");

      const rect = group
        .append("rect")
        .attr("x", 20)
        .attr("y", 20)
        .attr("width", 60)
        .attr("height", 30)
        .attr("fill", "green");
    });
  },
};
</script>

First, we call attr with the 'transform' string to set the transform CSS property of the svg element.

translate(60, 60) moves the SVG 60 pixels right and down respectively.

rotate(30) rotates the SVG by 30 degrees.

Then we call append the rectangle with the append method with the 'rect' as the argument and set all the attributes.

Conclusion

We can add circles and ellipses, and transform shapes with D3 in a Vue app.

Categories
Vue and D3

Adding Graphics to a Vue App with D3 — Transitions and Bar Charts

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.

Transition

We can use the D3 to apply transitions.

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 t = d3.transition().duration(2000);
      d3.select("body").transition(t).style("background-color", "lightblue");
    });
  },
};
</script>

to call d3.transition to create our transition object.

Then we set the duration of it with the duration method.

2000 is in milliseconds.

Then we call the transition method with the t method to set the background color of body to lightblue in 2 seconds.

Animation

We can add animations with D3.

For instance, we can write:

<template>
  <div id="app">
    <h3>hello world</h3>
  </div>
</template>

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

export default {
  name: "App",
  mounted() {
    Vue.nextTick(() => {
      d3.selectAll("h3")
        .transition()
        .style("font-size", "28px")
        .delay(2000)
        .duration(2000);
    });
  },
};
</script>

We get the h3 and then make the font-size 28px after 2 seconds.

Then we change the size to 28px in 2 seconds.

Drawing Charts

D3 is useful for creating charts.

We can use it to create bar charts, circle charts, pie charts, donut, charts, etc.

Bar Charts

We can create bar charts 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 data = [13, 6, 11, 20, 13];

      const width = 500;
      const scaleFactor = 20;
      const barHeight = 30;

      const graph = d3
        .select("#svgcontainer")
        .append("svg")
        .attr("width", width)
        .attr("height", barHeight * data.length);

      const bar = graph
        .selectAll("g")
        .data(data)
        .enter()
        .append("g")
        .attr("transform", (d, i) => {
          return "translate(0," + i * barHeight + ")";
        });
      bar
        .append("rect")
        .attr("width", (d) => {
          return d * scaleFactor;
        })
        .attr("height", barHeight - 1)
        .attr("fill", "green");

      bar
        .append("text")
        .attr("x", (d) => {
          return d * scaleFactor;
        })
        .attr("y", barHeight / 2)
        .attr("dy", ".35em")
        .text((d) => {
          return d;
        })
        .attr("fill", "red");
    });
  },
};
</script>

We sett the constants and the dimensions for our bar chart in the first few lines.

Then we create the g elements with:

const bar = graph
  .selectAll("g")
  .data(data)
  .enter()
  .append("g")
  .attr("transform", (d, i) => {
    return "translate(0," + i * barHeight + ")";
  });

to house the bars.

Next, we create the rectangles for the bar chart with:

bar
  .append("rect")
  .attr("width", (d) => {
    return d * scaleFactor;
  })
  .attr("height", barHeight - 1)
  .attr("fill", "green");

d has the number in the data array.

We multiply that by scaleFactor to get the width of the bars.

We set the height to barHeight — 1 to set the height and add a gap between the bars.

And the 'fill' is set to 'green' .

Then we add the next to the right of the bars by writing:

bar
  .append("text")
  .attr("x", (d) => {
    return d * scaleFactor;
  })
  .attr("y", barHeight / 2)
  .attr("dy", ".35em")
  .text((d) => {
    return d;
  })
  .attr("fill", "red");

The 'x' and 'y' attributes set the location of the text.

x comes after the bar and y is barHeight / 2 .

We also have to shift the y coordinate to that the text is aligned with the bar.

So we set the dy attribute to .35em .

Then we return the number and set that as the text with the text method.

And then we call attr with the 'fill' set to 'red' .

Conclusion

We can add transitions and bar charts with D3 into our Vue app.

Categories
Vue

Vue Konva — Animation and Caching

We can make working with the HTML canvas easier in Vue apps with the Vue Konva library.

In this article, we’ll take a look at how to use Vue Konva to make working with the HTML canvas easier in a Vue app.

Animation

We can animation shapes with the Konva.Animation constructor.

For example, we can write:

<template>
  <v-stage ref="stage" :config="stageSize">
    <v-layer ref="layer">
      <v-rect
        ref="rect"
        @dragstart="changeSize"
        @dragend="changeSize"
        :config="{
          width: 50,
          height: 50,
          fill: 'green',
          draggable: true,
        }"
      />
      <v-regular-polygon
        ref="octagon"
        :config="{
          x: 200,
          y: 200,
          sides: 8,
          radius: 20,
          fill: 'red',
          stroke: 'black',
          strokeWidth: 4,
        }"
      />
    </v-layer>
  </v-stage>
</template>

<script>
import Konva from "konva";
const width = window.innerWidth;
const height = window.innerHeight;

export default {
  data() {
    return {
      stageSize: {
        width: width,
        height: height,
      },
    };
  },
  methods: {
    changeSize(e) {
      e.target.to({
        scaleX: Math.random() + 0.8,
        scaleY: Math.random() + 0.8,
        duration: 0.2,
      });
    },
  },
  mounted() {
    const vm = this;
    const amplitude = 100;
    const period = 5000;
    const centerX = vm.$refs.stage.getNode().getWidth() / 2;
    const octagon = this.$refs.octagon.getNode();
    const anim = new Konva.Animation((frame) => {
      octagon.setX(
        amplitude * Math.sin((frame.time * 2 * Math.PI) / period) + centerX
      );
    }, octagon.getLayer());
    anim.start();
  },
};
</script>

We call the Konva.Animation constructor with a callback to change the x coordinate of the item with setX .

Then we call anim.start to start the animation.

The changeSize method is called when we’re dragging the rectangle.

It changes the position when we drag on the object.

Cache

We can cache the items rendered with the cache method.

For example, we can write:

<template>
  <div>
    <v-stage ref="stage" :config="stageConfig">
      <v-layer ref="layer">
        <v-group ref="group">
          <v-star
            v-for="item in list"
            :key="item.id"
            :config="{
              x: item.x,
              y: item.y,
              rotation: item.rotation,
              id: item.id,
              numPoints: 5,
              innerRadius: 30,
              outerRadius: 50,
              fill: 'lightgreen',
              opacity: 0.8,
              shadowColor: 'black',
              shadowBlur: 10,
              shadowOpacity: 0.6,
              scaleX: item.scale,
              scaleY: item.scale,
            }"
          />
        </v-group>
      </v-layer>
    </v-stage>
    <div class="cache">
      <input type="checkbox" @change="handleCacheChange" /> cache shapes
    </div>
  </div>
</template>

<script>
const width = window.innerWidth;
const height = window.innerHeight;
export default {
  data() {
    return {
      list: [],
      dragItemId: null,
      stageConfig: {
        width: width,
        height: height,
        draggable: true,
      },
    };
  },
  methods: {
    handleCacheChange(e) {
      const shouldCache = e.target.checked;
      if (shouldCache) {
        this.$refs.group.getNode().cache();
      } else {
        this.$refs.group.getNode().clearCache();
      }
    },
  },
  mounted() {
    for (let n = 0; n < 300; n++) {
      this.list.push({
        id: n.toString(),
        x: Math.random() * width,
        y: Math.random() * height,
        rotation: Math.random() * 180,
        scale: Math.random(),
      });
    }
  },
};
</script>

<style>
body {
  margin: 0;
  padding: 0;
}

.cache {
  position: absolute;
  top: 0;
  left: 0;
}
</style>

to add 300 stars.

In the handleCacheChange method, we call cache on the v-group ‘s ref to cache the content if the checkbox is checked.

Otherwise, we clear the cache with clearCache .

Conclusion

We can animate shapes and cache them with Vue Konva.