Building a simple doughnut chart with D3.JS and Vue - a beginner's guide

In my Vue project, I attempted to create a simple Doughnut chart following the example provided in the D3.js documentation: Doughnut Chart.

However, I encountered an issue while trying to implement this chart in Vue. Every time I attempt to get it to work, I receive the error message

[Vue warn]: Error in mounted hook: "TypeError: _ is not iterable"
.

I am also looking for a way to ensure that the SVG fills the parent div and adjusts dynamically based on the width and height of the parent container.

<template>
  <div class="p-3 flex flex-col">
    <div class="w-full flex-1">
      <div id="my_dataviz"></div>
    </div>
  </div>
</template>
<script>
import * as d3 from "d3";

export default {
  name: "DoughnutChartItem",
  props: {
    data: {
      type: Array,
      required: true
    }
  },
  mounted() {
    var width = 450;
    var height = 450;
    var margin = 40;

    var radius = Math.min(width, height) / 2 - margin;

    var svg = d3
      .select("#my_dataviz")
      .append("svg")
      .attr("width", width)
      .attr("height", height)
      .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

    var data = { a: 9, b: 20, c: 30, d: 8, e: 12 };

    var color = d3
      .scaleOrdinal()
      .domain(data)
      .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56"]);

    var pie = d3.pie().value(function(d) {
      return d.value;
    });
    var data_ready = pie(d3.entries(data));

    svg
      .selectAll("whatever")
      .data(data_ready)
      .enter()
      .append("path")
      .attr(
        "d",
        d3
          .arc()
          .innerRadius(100)
          .outerRadius(radius)
      )
      .attr("fill", function(d) {
        return color(d.data.key);
      })
      .attr("stroke", "black")
      .style("stroke-width", "2px")
      .style("opacity", 0.7);
  }
};
</script>

Answer №1

Your issue can be found in the line .domain(data):

// set the color scale
var color = d3
  .scaleOrdinal()
  .domain(data) //<-- domain function is expecting an array not an object
  .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56"]);

Here's what you should use instead:

// set the color scale
var color = d3
  .scaleOrdinal()
  .domain(Object.keys(data)) //<-- set domain to ['a','b','c','d','e']
  .range(['#98abc5', '#8a89a6', '#7b6888', '#6b486b', '#a05d56']);

See a working example below:

... (original content remains unchanged)

New snippet based on feedback:

... (original content remains unchanged)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Trigger a click based on the CSS path starting from a specific element in the DOM

I am currently developing a feature for mouse activities, such as moving the mouse, clicking, and scrolling. I want to be able to record these activities and then playback them later on. So far, I have successfully recorded mouse movement, and now I need t ...

Customizing tooltip text in Google Chart API: A step-by-step guide

http://code.google.com/apis/chart/ <script type="text/javascript" src="https://www.google.com/jsapi"></script> <script type="text/javascript"> // Loading the Visualization API and the piechart package from Google. google.load(' ...

Steps to include a Target property in a freshly created MouseEvent

Trying to dispatch a contextMenu event, I've noticed that in the MouseEvent interface for TypeScript, the target property is missing, even though it is documented in the contextMenu documentation. Here's my TypeScript snippet: const emulatedMou ...

Creating a Copy to Clipboard feature in React can be achieved by transferring data from an h1 tag to an input field

I'm trying to extract data from an API into an h1 tag in my app. Is there a way for me to easily copy this data and paste it into an input field? Any help would be greatly appreciated. Thanks! ...

Encountering issues with Office.context.document.getFileAsync function

I am experiencing a strange issue where, on the third attempt to extract a word document as a compressed file for processing in my MS Word Task Pane MVC app, it crashes. Here is the snippet of code: Office.context.document.getFileAsync(Office.FileType.Co ...

Graph your data with a stunning Fusioncharts area range graph combined with a sleek

My goal is to create a visual representation of an area range graph with a corresponding mid line. You can view the image below for reference: https://i.sstatic.net/8KDbF.png While I have successfully incorporated the low and high values, I am encounterin ...

Transmitting JSON data containing nested objects through AngularJS

Looking to modify the way I am sending a POST request with nested child objects. Here is the current format: { "title": "sample string 2", "comment": "sample string 5", "child": { "name": "sample string 2" }, "children": [ { ...

What purpose does the additional symbol "$()" serve in the selector "$($())"?

Currently, I am looking to incorporate a jQuery scrollspy feature into one of my ongoing projects. Upon coming across this jsfiddle (https://jsfiddle.net/mekwall/up4nu/), I successfully integrated it into my project. However, I have hit a roadblock while ...

Error encountered while using a vue js template

I have recently started learning vue.js and I am using it to dynamically update a list of <li> elements based on the selection from another list using vue.js. I'm encountering an error message that says: vue.js:465 [Vue warn]: Error compiling t ...

Inconsistent CSS3 transitions behavior in Firefox 4

I have been playing around with some css3 transitions and created a slider test. It works perfectly in webkit browsers, but I have noticed an issue in Firefox 4. When clicking on the left link for the first time, the slider is supposed to slide to the left ...

Discovering the present route within the Vue 2.7 composition API

When working with Vue2, I am able to access the current path using this.$route.path In Vue3, I can utilize useRouter() for similar functionality. However, inVue2.7 composition api, neither of these options is available. ...

Steps for creating a function to validate if two classes are identical

Currently, I am developing a memory game using JavaScript. One of the features I have implemented is toggling between two card faces by changing the class back and forth. Now, I am in the process of creating a function that will check if two game cards are ...

transform nested object into a flat object using JavaScript

here is the given JSON format: - { "_id": "5c1c4b2defb4ab11f801f30d", "name": "Ray15", "email": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="afddced69e9aefc8c2cec6c381ccc0c2">[email protected]</a>" ...

Execute a Loop in the Background

Currently, I have a requirement to continuously run a loop in the background of my JavaScript-based app. This loop is responsible for cycling a ScrollableView every six seconds. However, the issue arises when this loop prevents any other operations from be ...

Creating mp4 files from a sequence of jpg images using Node.js

My server continuously receives jpg files from a client. The challenge at hand is: how can I create one mp4 file using all of these jpg files? I currently save all the jpg files and then utilize ffmpeg with “filename%3d.jpg” once the client finishes s ...

Tips for improving the efficiency of the find_average_number(array) simple function?

I successfully completed a CodeWars challenge where I wrote the function find_average to calculate the average of numbers in an array. However, I now have some questions: 1) How can I optimize this code in terms of Big-O notation? Is there a way to reduce ...

Utilizing Laravel Data in Vue Components: A Comprehensive Guide

Understanding File Organization Within App.blade.php Incorporating Vue Router for Component Retrieval. When working with a regular variable such as $users, it can be easily accessed in the blade file using {{$users}}. So, the question arises - how do we ...

What is the best way to iterate through three arrays with a single v-for loop?

I am currently working with 3 arrays stored in my Vuex State. Is there a way to loop through all of them using just ONE v-for directive? For example: export const stepOne = { state: { textfields: [ { value: "", label: "weig ...

Looking for a solution to display PHP AJAX errors in my jQuery script?

I am facing an issue with my PHP AJAX code and jQuery integration. The current problem is that the error case in jQuery is consistently being triggered, but I am unsure of the reason behind it. Below is the jQuery code snippet: $('.vote_up').cl ...

Using Vue.js to create an infinite bounce animation within a component

I have created a vuejs component that displays an image block. Here is my HTML, with the component being called 4 times: <div id="activities" class="row text-center justify-content-center activities"> <zpeakimage type="art" text="{{ art_text ...