我尝试使用经典技术使我的图表响应以下行:
.el.append('circle')
.attr('class', 'needle-center')
.attr('width', '100%')
.attr('height', '100%')
.attr('preserveAspectRatio', 'xMinYMin')
,但无法调整大小。或者,我可以通过在控制台中现在返回行的位置添加函数来重新创建图表。
以下代码段:
var needle;
(function create(){
var barWidth, chart, chartInset, degToRad, repaintGauge,
height, margin, numSections, padRad, percToDeg, percToRad,
percent, radius, sectionIndx, svg, totalPercent, width;
percent = .65;
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-filled");
chart.append('path').attr('class', "arc chart-empty");
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)
{
var next_start = totalPercent;
arcStartRad = percToRad(next_start);
arcEndRad = arcStartRad + percToRad(perc / 2);
next_start += perc / 2;
arc1.startAngle(arcStartRad).endAngle(arcEndRad);
arcStartRad = percToRad(next_start);
arcEndRad = arcStartRad + percToRad((1 - perc) / 2);
arc2.startAngle(arcStartRad + padRad).endAngle(arcEndRad);
chart.select(".chart-filled").attr('d', arc1);
chart.select(".chart-empty").attr('d', arc2);
}
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 / 3;
this.radius = this.len / 6;
}
/*
.append('circle')
.attr('class', 'needle-center')
.attr('width', '100%')
.attr('height', '100%')
.attr('viewBox', '0' + ' ' + '0'+ ' ' + config.clipWidth + ' ' + config.clipHeight)
.attr('preserveAspectRatio', 'xMinYMin')
*/
Needle.prototype.render = function() {
this
.el.append('circle')
.attr('class', 'needle-center')
.attr('width', '100%')
.attr('height', '100%')
.attr('preserveAspectRatio', 'xMinYMin')
.attr('r', this.radius);
return this.el.append('path').attr('class', '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);
d3.select(window).on("resize", console.log('Recreate Chart'));
})();
.chart-gauge {
height: 100%;
width:auto;
margin: 100px auto;
}
.chart-filled {
fill: steelblue;
}
.chart-empty {
fill: #dedede;
}
.needle, .needle-center {
fill: #464A4F;
}
svg {
font: 10px sans-serif;
}
<script src="https://d3js.org/d3.v3.min.js"></script>
<div class="chart-gauge"></div>