javascript - D3.JS 和 Vue 如何创建一个基本的圆环图
问题描述
我有一个 Vue 项目,我尝试在其中绘制一个简单的圆环图。我尝试创建的图表显示在 D3.js 的文档中:Donut Chart。
但是当我尝试在 Vue 中创建它时,我似乎无法让它工作。我继续得到一个
[Vue warn]: Error in mounted hook: "TypeError: _ is not iterable"
.
还有一种方法可以使 SVG 填充父 div,以便它响应父级的宽度和高度。
<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() {
// set the dimensions and margins of the graph
var width = 450;
var height = 450;
var margin = 40;
// The radius of the pieplot is half the width or half the height (smallest one). I subtract a bit of margin.
var radius = Math.min(width, height) / 2 - margin;
// append the svg object to the div called 'my_dataviz'
var svg = d3
.select("#my_dataviz")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
// Create dummy data
var data = { a: 9, b: 20, c: 30, d: 8, e: 12 };
// set the color scale
var color = d3
.scaleOrdinal()
.domain(data)
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56"]);
// Compute the position of each group on the pie:
var pie = d3.pie().value(function(d) {
return d.value;
});
var data_ready = pie(d3.entries(data));
// Build the pie chart: Basically, each part of the pie is a path that we build using the arc function.
svg
.selectAll("whatever")
.data(data_ready)
.enter()
.append("path")
.attr(
"d",
d3
.arc()
.innerRadius(100) // This is the size of the donut hole
.outerRadius(radius)
)
.attr("fill", function(d) {
return color(d.data.key);
})
.attr("stroke", "black")
.style("stroke-width", "2px")
.style("opacity", 0.7);
}
};
</script>
解决方案
你的问题是.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"]);
你需要的是:
// 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']);
工作示例:
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="https://unpkg.com/vue"></script>
<script src="https://d3js.org/d3.v5.min.js"></script>
</head>
<body>
<div class="p-3 flex flex-col" id="one">
<div class="w-full flex-1">
<div id="my_dataviz"></div>
</div>
</div>
<script>
new Vue({
el: '#one',
data: {
type: Array,
required: true,
},
mounted() {
// set the dimensions and margins of the graph
var width = 450;
var height = 450;
var margin = 40;
// The radius of the pieplot is half the width or half the height (smallest one). I subtract a bit of margin.
var radius = Math.min(width, height) / 2 - margin;
// append the svg object to the div called 'my_dataviz'
var svg = d3
.select('#my_dataviz')
.append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr(
'transform',
'translate(' + width / 2 + ',' + height / 2 + ')'
);
// Create dummy data
var data = { a: 9, b: 20, c: 30, d: 8, e: 12 };
// set the color scale
var color = d3
.scaleOrdinal()
.domain(Object.keys(data))
.range(['#98abc5', '#8a89a6', '#7b6888', '#6b486b', '#a05d56']);
// Compute the position of each group on the pie:
var pie = d3.pie().value(function (d) {
return d.value;
});
var data_ready = pie(d3.entries(data));
// Build the pie chart: Basically, each part of the pie is a path that we build using the arc function.
svg
.selectAll('whatever')
.data(data_ready)
.enter()
.append('path')
.attr(
'd',
d3
.arc()
.innerRadius(100) // This is the size of the donut hole
.outerRadius(radius)
)
.attr('fill', function (d) {
return color(d.data.key);
})
.attr('stroke', 'black')
.style('stroke-width', '2px')
.style('opacity', 0.7);
}
});
</script>
</body>
</html>
基于评论的新片段:
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="https://unpkg.com/vue"></script>
<script src="https://d3js.org/d3.v5.min.js"></script>
</head>
<body>
<div class="p-3 flex flex-col" id="one">
<div class="w-full flex-1">
<div id="my_dataviz"></div>
</div>
</div>
<script>
new Vue({
el: '#one',
data: {
type: Array,
required: true,
},
mounted() {
// set the dimensions and margins of the graph
var width = 450;
var height = 450;
var margin = 40;
// The radius of the pieplot is half the width or half the height (smallest one). I subtract a bit of margin.
var radius = Math.min(width, height) / 2 - margin;
// append the svg object to the div called 'my_dataviz'
var svg = d3
.select('#my_dataviz')
.append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr(
'transform',
'translate(' + width / 2 + ',' + height / 2 + ')'
);
// Create dummy data
var data = { a: 9, b: 20, c: 30, d: 8, e: 12 };
// set the color scale
var color = d3
.scaleOrdinal()
.domain(Object.keys(data))
.range(['#98abc5', '#8a89a6', '#7b6888', '#6b486b', '#a05d56']);
// Compute the position of each group on the pie:
var pie = d3.pie().value(function (d) {
return d[1];
});
var data_ready = pie(Object.entries(data));
// Build the pie chart: Basically, each part of the pie is a path that we build using the arc function.
svg
.selectAll('whatever')
.data(data_ready)
.enter()
.append('path')
.attr(
'd',
d3
.arc()
.innerRadius(100) // This is the size of the donut hole
.outerRadius(radius)
)
.attr('fill', function (d) {
return color(d.data[0]);
})
.attr('stroke', 'black')
.style('stroke-width', '2px')
.style('opacity', 0.7);
}
});
</script>
</body>
</html>
推荐阅读
- token - 我如何获得小米米 IO 绑定的 Roborock 吸尘器令牌
- cucumber - 如何填充仅在执行期间生成的未知 Cucumber 或 Specflow 步骤参数?
- typescript - 在标签应用程序内路由并离开的疑问
- pandas - 在多个时隙上拆分值数据帧
- python - 当我尝试将 swagger 描述导入或更新到 api 网关时,boto3 忽略了 basePath 参数
- typescript - RxJS:沿可观察链传递数据的干净方式?
- android - androidx.test.annotation 包位于哪个 AndroidX 库中?
- python - 当一个函数在大部分域上为零时数值计算卷积
- javascript - 在页面之间导航时页面淡出仅有时有效
- lerna - lerna 在 yarn 工作区的优势,为什么要使用 lerna