d3js 矩形条规图表

问题描述 投票:0回答:1

我如何将当前代码转换为类似压力图的内容(其中矩形排列成弧形),然后突出显示最佳情况的刻度线以表示该值。

因此,我们将在创建骨架时添加矩形并更改角度。

我有这个演示,可以创建矩形扩展并更改角度 - 但我不确定如何稳定它并从左侧创建弧 - https://jsfiddle.net/smo6kqzw/3/

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)+")")

}
  

// create svg element:
var svg = d3.select("#rect").append("svg").attr("width", 800).attr("height", 200)

// Add the path using this helper function
svg.append('rect')
  .attr('x', 10)
  .attr('y', 120)
  .attr('width', 600)
  .attr('height', 40)
  .attr('stroke', 'black')
  .attr('fill', '#69a3b2');

我目前有一个看起来像这样的表盘图表

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) // some space between slices
      .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`,
      ) // draw triangle

    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)}%`) // set % text

      arrow.transition().attr('transform', `rotate( ${data[0].value * 1.8}  )`) //rotate to desired qantity ( i put to 60% of 180 deg )
    }
    update(data)
  }

  render() {
    return <div ref={this.myRef} className="GaugeChart" />
  }
}
export default GaugeChart
d3.js
1个回答
0
投票

关于您的演示代码...

“我有这个演示,它创建了一系列矩形并进行了更改 角度 - 但我不知道如何稳定它并创建 从左侧开始的弧线”

实际上,您只需要修改起始角度,然后直接沿着圆弧计算刻度的位置。例如

const svg = d3.select('body')
  .append('svg')
  .attr("height", 500)
  .attr("width", 500)
  .attr("class", "svger");

const numTicks = 20;
const tickLength = 10;
const arcRadius = 150;
const centerX = 250;
const centerY = 250;

for (let i = 0; i < numTicks; i++) {
  const angle = (i / (numTicks - 1)) * Math.PI; // Half a circle (180 degrees)

  const x1 = centerX + arcRadius * Math.cos(angle);
  const y1 = centerY - arcRadius * Math.sin(angle);
  const x2 = x1 + tickLength * Math.cos(angle);
  const y2 = y1 - tickLength * Math.sin(angle);

  svg.append("line")
    .attr("x1", x1)
    .attr("y1", y1)
    .attr("x2", x2)
    .attr("y2", y2)
    .attr("stroke", "black");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

© www.soinside.com 2019 - 2024. All rights reserved.