Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
April 22, 2023 10:48 pm GMT

Real-Time Data Visualization with D3.js and Vue.js.

Many web applications and solutions are becoming more dynamic and responsive. This is, in part, due to high compute capacity as a lot of web applications are deployed on various cloud platforms as a result of high reliability, availability and security.

To add to this, is the end users' continual demand for real time experience. As organizations becomes more data-driven, many are using data visualizations to either tell their stories or share real time feedback with their customers.

This tutorial will use D3.js, a JavaScript library for manipulating documents based on data and Vue.js, a progressive JavaScript framework used for building user interfaces, to demonstrate real time visualization.

Firstly, we will create a vue.js project using vite.js, a build tool for modern web development that is designed to be fast and efficient. If you do not have vite already installed, run the following command npm create vite@latest.

Then, navigate to project directory and run npm init vue@latest and follow the prompt by picking a project name, selecting TypeScript and other relevant features.

 Project name:  <your-project-name> Add TypeScript?  No / Yes Add JSX Support?  No / Yes Add Vue Router for Single Page Application development?  No / Yes Add Pinia for state management?  No / Yes Add Vitest for Unit testing?  No / Yes Add Cypress for both Unit and End-to-End testing?  No / Yes Add ESLint for code quality?  No / Yes Add Prettier for code formatting?  No / YesScaffolding project in ./<your-project-name>...Done.

This will scaffold a vue.js project with similar project tree:

 README.md env.d.ts index.html node_modules package-lock.json package.json public  favicon.ico src  App.vue  assets  components  main.ts  router  types  views tsconfig.app.json tsconfig.config.json tsconfig.json tsconfig.vitest.json vite.config.ts

Afterwards, confirm that your package.json file has the following dependencies, else copy and paste (more reliably install them individually if the latest version is your thing) them. Make sure that you are inside your project directory. Otherwise, change to your project directory and run npm install.

Navigate to the components directory and create the chart folder (Barchart for this example) and a BarChart.vue file as shown below:

 BarChart  BarChart.vue

Open the .vue file and paste the following code:

<template>  <div class="" ref="barChartRef"></div></template>

This is a vue.js code template with a ref?: VNodeRef property called barChartRef. We will define the ref inside the script section. Next create a script section and import the D3.js library and other Vue.js dependencies.

For demonstration purposes, we will be skipping some codes here but are available in the repository.

<script setup lang="ts">// @ is an alias to /srcimport * as d3 from "d3";import { onMounted, onBeforeUnmount, computed, ref, reactive, watch, } from "vue";...</script>

We can also define our data, data interface (schema) and other variables for the chart.

interface Input {  label: string;  value: number;}const barChartRef = ref<HTMLElement | null>(null);const margin = reactive({ top: 30, right: 20, bottom: 30, left: 40 });const height = ref(360);const width = ref(  (barChartRef?.value?.offsetWidth || 300) - margin.left - margin.right);const revenue = ref([  {    label: "2013-06-30",    value: 660,  },  {    label: "2014-12-31",    value: 814,  },  {    label: "2015-06-30",    value: 1131,  },  {    label: "2016-12-31",    value: 1267,  },  {    label: "2017-06-30",    value: 1514,  },  {    label: "2018-12-31",    value: 1763,  },  {    label: "2019-06-30",    value: 2653,  },  {    label: "2020-12-31",    value: 6148,  },  {    label: "2021-06-30",    value: 12394,  },  {    label: "2022-12-31",    value: 2162,  },]);

Then, we will transform our data to the right format as below using a computed function:

const data = computed(() => {  return revenue.value.map((d: Input) => {    return {      label: d.label,      value: d.value,    };  });});

We are going to use other Vue.js native API functions to control how our chart is rendered on the page.

onMounted(async () => {  window.addEventListener("resize", handleResize);  handleResize();  handleDraw();});onBeforeUnmount(() => {  window.removeEventListener("resize", handleResize);});watch(  () => width.value,  () => {    remove();    handleDraw();  });

To avoid having multiple charts when the page re-renders, we can create a function that checks if the number of charts on the page exceeds one. It true, it will purge all except one.

const remove = () => {  // TODO: Get svg reference  const svg = d3.select(barChartRef.value).selectAll("svg");  // check the number of existing elements, if greater than 0; remove all existing ones  if (svg.size()) svg.remove().exit();};

We can make the chart to be responsive for every device screen by checking the user's screen size and displaying a chart within the width of the screen.

const handleResize = () => {  if (barChartRef?.value?.offsetWidth) {    width.value = barChartRef.value.offsetWidth - margin.left - margin.right;    return;  }  if (window.innerWidth < 400) {    width.value = 300 - margin.left - margin.right;    return;  }  width.value = 550 - margin.left - margin.right;  return;};

Finally, let us create a function that with generate our chart every time the page renders.

const handleDraw = async () => {  // append the svg object to the body of the page  const svg = d3    .select(barChartRef.value)    .append("svg")    .attr("width", width.value + margin.left + margin.right)    .attr("height", height.value + margin.top + margin.bottom)    .append("g")    .attr("transform", `translate(${margin.left},${margin.top})`);  // Add X axis  const x = d3    .scaleBand()    .domain(data.value.map((d) => d.label))    // .domain(data.value, (d) => d.label)    // .domain([data.value.map((d) => d.label)] as unknown as string)    .range([0, width.value])    .padding(0.2);  svg    .append("g")    .attr("transform", `translate(0, ${height.value})`)    .call(d3.axisBottom(x))    // .call(d3.axisBottom(x).tickFormat((x) => d3.timeFormat("%Y")(x)))    .selectAll("text")    .attr("transform", "translate(-10,0)rotate(-45)")    .style("text-anchor", "end");  // Add Y axis  const y = d3    .scaleLinear()    .domain([0, d3.max(data.value, (d): number => d.value)] as number[])    .range([height.value, 0]);  svg.append("g").call(d3.axisLeft(y));  // Bars  svg    .selectAll("mybar")    .data(data.value)    .enter()    .append("rect")    .attr("x", (d) => x(d.label) as number)    .attr("y", (d) => y(d.value))    .attr("width", x.bandwidth())    .attr("height", (d) => height.value - y(d.value))    .attr("fill", "#4682b4");  svg    .append("text")    .attr("class", "title")    .attr("x", width.value / 2)    .attr("y", 0 - margin.top / 2)    .attr("text-anchor", "middle")    .text("Company Revenue in USD ($)");};

A sample output should look like the image below:

Vue graph

That is all we need to do in order to create a real time responsive and dynamic visualization using D3.js and Vue.js. The repository for this tutorial is on GitHub.

If you like the article, do like and share with friends.


Original Link: https://dev.to/callezenwaka/real-time-data-visualization-with-d3js-and-vuejs-4og3

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To