我想从d3.js制作一个Gauge作为我可以在Vue中使用的组件。但是我正在努力以正确的方式导入它,所以我可以将它包装在一个自定义组件中。
除了从npm安装了d3:npm install d3
。我有这个用于仪表
// data which need to be fetched
var name = " ";
var value = 840;
var gaugeMaxValue = 1680;
// donn�es � calculer
var percentValue = value / gaugeMaxValue;
////////////////////////
var needleClient;
(function(){
var barWidth, chart, chartInset, degToRad, repaintGauge,
height, margin, numSections, padRad, percToDeg, percToRad,
percent, radius, sectionIndx, svg, totalPercent, width,
valueText, formatValue, k;
percent = percentValue;
numSections = 1;
sectionPerc = 1 / numSections / 2;
padRad = 0.025;
chartInset = 10;
// Orientation of gauge:
totalPercent = .75;
el = d3.select('.chart-gauge');
margin = {
top: 30,
right: 30,
bottom: 30,
left: 30
};
width = el[0][0].offsetWidth - margin.left - margin.right;
height = width;
radius = Math.min(width, height) / 2;
barWidth = 40 * width / 300;
//Utility methods
percToDeg = function(perc) {
return perc * 360;
};
percToRad = function(perc) {
return degToRad(percToDeg(perc));
};
degToRad = function(deg) {
return deg * Math.PI / 180;
};
// Create SVG element
svg = el.append('svg').attr('width', width + margin.left + margin.right).attr('height', height + margin.top + margin.bottom);
// Add layer for the panel
chart = svg.append('g').attr('transform', "translate(" + ((width) / 2 + margin.left) + ", " + ((height + margin.top) / 2) + ")");
chart.append('path').attr('class', "arc chart-red");
chart.append('path').attr('class', "arc chart-yellow");
chart.append('path').attr('class', "arc chart-green");
chart.append('path').attr('class', "arc chart-yellow_");
chart.append('path').attr('class', "arc chart-red_");
valueText = chart.append("chart")
formatValue = d3.format('1%');
arc5 = d3.svg.arc().outerRadius(radius - chartInset).innerRadius(radius - chartInset - barWidth)
arc4 = d3.svg.arc().outerRadius(radius - chartInset).innerRadius(radius - chartInset - barWidth)
arc3 = d3.svg.arc().outerRadius(radius - chartInset).innerRadius(radius - chartInset - barWidth)
arc2 = d3.svg.arc().outerRadius(radius - chartInset).innerRadius(radius - chartInset - barWidth)
arc1 = d3.svg.arc().outerRadius(radius - chartInset).innerRadius(radius - chartInset - barWidth)
repaintGauge = function ()
{
perc = 0.5;
var next_start = totalPercent;
arcStartRad = percToRad(next_start);
arcEndRad = arcStartRad + percToRad(0.175);
next_start += 0.175;
arc1.startAngle(arcStartRad).endAngle(arcEndRad);
arcStartRad = percToRad(next_start);
arcEndRad = arcStartRad + percToRad(0.05);
next_start += 0.05;
arc2.startAngle(arcStartRad + padRad).endAngle(arcEndRad);
arcStartRad = percToRad(next_start);
arcEndRad = arcStartRad + percToRad(0.05);
next_start += 0.05;
arc3.startAngle(arcStartRad + padRad).endAngle(arcEndRad);
arcStartRad = percToRad(next_start);
arcEndRad = arcStartRad + percToRad(0.05);
next_start += 0.05;
arc4.startAngle(arcStartRad + padRad).endAngle(arcEndRad);
arcStartRad = percToRad(next_start);
arcEndRad = arcStartRad + percToRad(0.175);
next_start += 0.175;
arc5.startAngle(arcStartRad + padRad).endAngle(arcEndRad);
chart.select(".chart-red").attr('d', arc1);
chart.select(".chart-yellow").attr('d', arc2);
chart.select(".chart-green").attr('d', arc3);
chart.select(".chart-yellow_").attr('d', arc4);
chart.select(".chart-red_").attr('d', arc5);
}
/////////
var Needle = (function() {
//Helper function that returns the `d` value for moving the needle
var recalcPointerPos = function(perc) {
var centerX, centerY, leftX, leftY, rightX, rightY, thetaRad, topX, topY;
thetaRad = percToRad(perc / 2);
centerX = 0;
centerY = 0;
topX = centerX - this.len * Math.cos(thetaRad);
topY = centerY - this.len * Math.sin(thetaRad);
leftX = centerX - this.radius * Math.cos(thetaRad - Math.PI / 2);
leftY = centerY - this.radius * Math.sin(thetaRad - Math.PI / 2);
rightX = centerX - this.radius * Math.cos(thetaRad + Math.PI / 2);
rightY = centerY - this.radius * Math.sin(thetaRad + Math.PI / 2);
return "M " + leftX + " " + leftY + " L " + topX + " " + topY + " L " + rightX + " " + rightY;
};
function Needle(el) {
this.el = el;
this.len = width / 2.5;
this.radius = this.len / 8;
}
Needle.prototype.render = function() {
this.el.append('circle').attr('class', 'needle-center').attr('cx', 0).attr('cy', 0).attr('r', this.radius);
return this.el.append('path').attr('class', 'needle').attr('id', 'client-needle').attr('d', recalcPointerPos.call(this, 0));
};
Needle.prototype.moveTo = function(perc) {
var self,
oldValue = this.perc || 0;
this.perc = perc;
self = this;
// Reset pointer position
this.el.transition().delay(100).ease('quad').duration(200).select('.needle').tween('reset-progress', function() {
return function(percentOfPercent) {
var progress = (1 - percentOfPercent) * oldValue;
repaintGauge(progress);
return d3.select(this).attr('d', recalcPointerPos.call(self, progress));
};
});
this.el.transition().delay(300).ease('bounce').duration(1500).select('.needle').tween('progress', function() {
return function(percentOfPercent) {
var progress = percentOfPercent * perc;
repaintGauge(progress);
var thetaRad = percToRad(progress / 2);
var textX = - (self.len + 45) * Math.cos(thetaRad);
var textY = - (self.len + 45) * Math.sin(thetaRad);
valueText.text(formatValue(progress))
.attr('transform', "translate("+textX+","+textY+")")
return d3.select(this).attr('d', recalcPointerPos.call(self, progress));
};
});
};
return Needle;
})();
needle = new Needle(chart);
needle.render();
needle.moveTo(percent);
setTimeout(displayValue, 1350);
})();
这是有效的HTML,但不是作为组件
<html>
<head>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<style type="text/css" src="gauge.css">
.chart-gauge
{
width: 400px;
margin: 100px auto
}
.chart-green
{
fill: #9FBD35;
}
.chart-yellow
{
fill: #F2BA3A;
}
.chart-yellow_
{
fill: #F2BA3A;
}
.chart-red
{
fill: #FB3033;
}
.chart-red_
{
fill: #FB3033;
}
.needle, .needle-center
{
fill: #000000;
}
.text {
color: "#112864";
font-size: 16px;
}
svg {
font: 10px sans-serif;
}
</style>
</head>
<body>
<div class="chart-gauge"></div>
<script type="text/javascript" src="./gaugeClient.js"></script>
<script type="text/javascript" src="./labels.js"></script>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</body>
</html>
答案 0 :(得分:13)
第一个组件旨在帮助您每次都重写代码,所以为什么不为d3创建一个组件,您可以像以下那样每次都重复使用
通用c3组件,c3.vue
<template>
<div :style="style" v-bind:class="class" id="{{ randomid }}" ></div>
</template>
<script>
import c3 from 'c3'
module.exports = {
props: {
legend: {
type: Object,
},
size: {
type: Object,
},
colour: {
type: Object,
},
axis: {
type: Object,
},
bar: {
type: Object,
},
chartdata:{
type: Object,
default: function () {
return {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
]
}
}
},
class:{
type: Object,
},
styles: {
type: Object,
}
},
created: function() {
},
ready: function(){
this.drawChart();
},
methods : {
drawChart: function () {
var self = this
var chart = c3.generate({
bindto: document.getElementById(self.randomid) ,
data: self.chartdata,
size : self.size,
colour : self.colour,
legend : self.legend,
bar : self.bar,
axis : self.axis
});
}
},
computed: {
randomid: function () {
return _.uniqueId('c3_')
}
}
}
</script>
接下来注册组件:
Vue.component('c3-chart', require('./c3.vue'))
现在您可以使用它来创建您想要的任何图表,是+仪表
<template>
<div>
<c3-chart :chartdata="gauge.data" :colour="gauge.colour" :size="gauge.size"></c3-chart>
</div>
</template>
<script>
module.exports = {
props: {
},
components: {
},
data: function () {
return {
gauge : {
data: {
columns: [
['data', 91.4]
],
type: 'gauge',
onclick: function (d, i) { console.log("onclick", d, i); },
onmouseover: function (d, i) { console.log("onmouseover", d, i); },
onmouseout: function (d, i) { console.log("onmouseout", d, i); }
},
color: {
pattern: ['#FF0000', '#F97600', '#F6C600', '#60B044'],
threshold: {
values: [30, 60, 90, 100]
}
},
size: {
height: 180
}
}
}
},
created: function() {
},
ready: function(){
},
methods : {
},
events: {
},
computed: {
}
}
</script>