如何基于现有D3.js代码实现弧形矩形压力仪表盘?

如何将现有代码改造成弧形排列矩形的压力图表?
我想实现这类压力图表:让矩形按弧形排列,并高亮最优刻度来表示数值。核心需求是添加矩形并在构建骨架时调整其角度。
我已经做了一个生成分散矩形并调整角度的Demo,但还没实现稳定的弧形排列效果(从左侧开始的弧形):
var svg = d3.select('body').append('svg').attr("height", 500).attr("width", 500).attr("class", "svger") var rectbuf = 50; var padd = 1; for (let i = 0; i < 20; i++) { svg.append("rect") .attr("width", 30) .attr("height", 20) .attr("fill", "red") .attr("y", 20) .attr("x", rectbuf * 5) .attr("transform", "rotate("+((5+padd) *i)+")") }
我还写了一段基础矩形绘制代码:
// 创建SVG元素: var svg = d3.select("#rect").append("svg").attr("width", 800).attr("height", 200) // 使用辅助函数添加路径 svg.append('rect') .attr('x', 10) .attr('y', 120) .attr('width', 600) .attr('height', 40) .attr('stroke', 'black') .attr('fill', '#69a3b2');
我目前已有一个仪表盘图表:
对应的React + D3代码如下:
import React from 'react' import * as d3 from 'd3' class GaugeChart extends React.Component { constructor(props) { super(props) this.myRef = React.createRef() this.state = { data: [], theme: this.props.theme ? this.props.theme : ['#bde0fe', '#2698f9', '#71bcfd', '#f1f8fe'], } } componentDidMount() { var $this = this.myRef.current d3.select($this).selectAll('svg').remove() const value = this.props.value const data = [ { label: 'Completed', value: value, }, { label: 'Remaining', value: 100 - value, }, ] const width = parseInt(this.props.width, 10), height = parseInt(this.props.height, 10), radius = parseInt(this.props.r, 10), innerradius = parseInt(this.props.ir, 10) var color = d3.scaleOrdinal().range(this.state.theme) var arc = d3.arc().outerRadius(radius).innerRadius(innerradius) data.forEach(function (d) { d.total = +d.value }) var pie = d3 .pie() .startAngle(-90 * (Math.PI / 180)) .endAngle(90 * (Math.PI / 180)) .padAngle(0.02) // 扇区间留白 .sort(null) .value(function (d) { return d.total }) var svg = d3 .select($this) .append('svg') .attr('width', width) .attr('height', height + 5) .append('g') .attr('class', 'piechart') .attr('transform', 'translate(' + width / 2 + ',' + height + ')') var segments = svg.append('g').attr('class', 'segments') var slices = segments .selectAll('.arc') .data(pie(data)) .enter() .append('g') .attr('class', 'arc') slices .append('path') .attr('d', arc) .attr('fill', function (d, i) { return color(i) }) /*.transition() .attrTween('d', function(d) { var i = d3.interpolate(d.startAngle + 0.1, d.endAngle); return function(t) { d.endAngle = i(t); return arc(d); } } )*/ var arrow = svg.append('g').attr('transform', 'rotate( 0 )') arrow .append('path') .attr('fill', '#ef7e60') .attr( 'd', `M -${innerradius - 5},0 -${innerradius - 12},-5 -${ innerradius - 12 },5`, ) // 绘制三角形 var text = svg .append('text') .attr('text-anchor', 'middle') .attr('dy', 0) .attr('fill', '#ef7e60') function update(data) { text.text(`${Math.round(data[0].value)}%`) // 设置百分比文本 arrow.transition().attr('transform', `rotate( ${data[0].value * 1.8} )`) // 旋转至目标数值(对应180度的比例) } update(data) } render() { return <div ref={this.myRef} className="GaugeChart" /> } } export default GaugeChart
后续更新的示例:
- 12月2日最新示例
- 12月3日最新示例
内容的提问来源于stack exchange,提问作者The Old County
相关产品推荐
相关产品推荐

