仪表D3.js在指针顶部显示值
Gauge D3.js display value at the top of the needle
我对D3.js有点陌生,我设法用我在互联网上找到的东西创建了一个量表。但我找不到任何显示针头顶部电流值的仪表。类似这样的东西:我想要什么
很明显,我希望价值观能够随波逐流。我试图将"text"属性添加到针本身,但没有成功。
这是一个代码笔链接:http://codepen.io/kazu_codepen/pen/wGmGjv?editors=1010
这是我的js代码:
// data which need to be fetched
var name = "azerty";
var value = 17;
var gaugeMaxValue = 100;
// data to calculate
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;
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: 20,
right: 20,
bottom: 30,
left: 20
};
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 + margin.left) / 2) + ", " + ((height + margin.top) / 2) + ")");
chart.append('path').attr('class', "arc chart-first");
chart.append('path').attr('class', "arc chart-second");
chart.append('path').attr('class', "arc chart-third");
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(perc / 3);
next_start += perc / 3;
arc1.startAngle(arcStartRad).endAngle(arcEndRad);
arcStartRad = percToRad(next_start);
arcEndRad = arcStartRad + percToRad(perc / 3);
next_start += perc / 3;
arc2.startAngle(arcStartRad + padRad).endAngle(arcEndRad);
arcStartRad = percToRad(next_start);
arcEndRad = arcStartRad + percToRad(perc / 3);
arc3.startAngle(arcStartRad + padRad).endAngle(arcEndRad);
chart.select(".chart-first").attr('d', arc1);
chart.select(".chart-second").attr('d', arc2);
chart.select(".chart-third").attr('d', arc3);
}
/////////
var dataset = [{metric:name, value: value}]
var texts = svg.selectAll("text")
.data(dataset)
.enter();
texts.append("text")
.text(function(){
return dataset[0].metric;
})
.attr('id', "Name")
.attr('transform', "translate(" + ((width + margin.left) / 6) + ", " + ((height + margin.top) / 1.5) + ")")
.attr("font-size",25)
.style("fill", "#000000");
texts.append("text")
.text(function(){
return dataset[0].value;
})
.attr('id', "Value")
.attr('transform', "translate(" + ((width + margin.left) / 1.4) + ", " + ((height + margin.top) / 1.5) + ")")
.attr("font-size",25)
.style("fill", "#000000");
texts.append("text")
.text(function(){
return 0;
})
.attr('id', 'scale0')
.attr('transform', "translate(" + ((width + margin.left) / 100 ) + ", " + ((height + margin.top) / 2) + ")")
.attr("font-size", 15)
.style("fill", "#000000");
texts.append("text")
.text(function(){
return gaugeMaxValue/2;
})
.attr('id', 'scale10')
.attr('transform', "translate(" + ((width + margin.left) / 2.15 ) + ", " + ((height + margin.top) / 30) + ")")
.attr("font-size", 15)
.style("fill", "#000000");
texts.append("text")
.text(function(){
return gaugeMaxValue;
})
.attr('id', 'scale20')
.attr('transform', "translate(" + ((width + margin.left) / 1.03 ) + ", " + ((height + margin.top) / 2) + ")")
.attr("font-size", 15)
.style("fill", "#000000");
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);
///////
/**
*
* I tried to add text here
*
*/
///////
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);
return d3.select(this).attr('d', recalcPointerPos.call(self, progress));
};
});
};
return Needle;
})();
needle = new Needle(chart);
needle.render();
needle.moveTo(percent);
})();
这是我的html代码:
<!DOCTYPE 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-first
{
fill: #9FBD35;
}
.chart-second
{
fill: #F2BA3A;
}
.chart-third
{
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>
如果有人能帮忙的话,我已经花了几天时间尝试,但都没有成功。谢谢
这是一个更新的代码笔
所做的更改:
1) 作为初始化的一部分,创建元素valueText
valueText = chart.append("text")
.attr('id', "Value")
.attr("font-size",16)
.attr("text-anchor","middle")
.attr("dy",".5em")
.style("fill", '#000000');
2) 同样在初始化时,创建formatValue
,以格式化百分比
formatValue = d3.format('1%');
3) 在转换的每一帧,计算文本的位置。它将45
单位的偏移量添加到self.len
(指针的长度),以向外移动文本。
var thetaRad = percToRad(progress / 2);
var textX = - (self.len + 45) * Math.cos(thetaRad);
var textY = - (self.len + 45) * Math.sin(thetaRad);
4) 根据计算的位置翻译valueText
,并从当前progress
更新其文本
valueText.text(formatValue(progress))
.attr('transform', "translate("+textX+","+textY+")")
好吧,我发现了一些等待更好解决方案的东西。
我使用的是:
var trX = 180 - 210 * Math.cos(percToRad(percent / 2));
var trY = 195 - 210 * Math.sin(percToRad(percent / 2));
// (180, 195) are the coordinates of the center of the gauge.
displayValue = function() {
texts.append("text")
.text(function(){
return dataset[0].value;
})
.attr('id', "Value")
.attr('transform', "translate(" + trX + ", " + trY+ ")")
.attr("font-size",18)
.style("fill", '#FB0006');
}
[…]然后调用此:
setTimeout(displayValue, 1350);
这样它就不会马上出现,而是当针头停在它的位置时。
它是有效的,就像值出现在针头顶部一样,但我仍然有两个问题。我真的希望它在指针动画中一直跟随指针,当它达到它的值时,我希望有一些比使用我通过计算得出的坐标更通用的东西,例如,有没有一个函数可以给我测量仪的中心?
我把上面的钢笔编辑成了那个版本的量表。(http://codepen.io/kazu_codepen/pen/wGmGjv?editors=1010)
无论如何,这个解决方案并不符合我的期望,但我会使用它,直到我找到更好的解决方案。
相关文章:
- 完整日历 (v2) 在每周视图槽的顶部显示弹出框
- 在顶部显示滚动条&DIV
- 仪表D3.js在指针顶部显示值
- Chrome扩展-在全屏视频顶部显示自定义通知/弹出窗口(HTML元素)
- 如何在文本字段顶部显示弹出框
- 在页面顶部显示您的应用
- 如何在表单顶部显示所有适用的错误消息,而不是逐个显示错误消息
- 当圆形图像在圆轮中发生变化时,如何在顶部显示标签
- 如何在移动浏览器的屏幕顶部显示自定义警报
- 使用滚动顶部显示滚动的像素
- 在锚标记顶部显示交互式 Html 元素
- 在图像顶部显示文本
- 首先或顶部显示表中的这些记录,由首选的 creteria 显示
- 如何从顶部显示下拉菜单到 use.show()
- 如何在屏幕顶部显示工具提示
- 在KMZ层的顶部显示地面覆盖
- 同位素:选择并在顶部显示.xx类
- 试图创建一个计算器,在顶部显示以前键入的数字
- 如何在外部网站的顶部显示webapp的标题栏
- 在页面顶部显示标题-滚动事件重新触发问题