/** @format */ import * as d3 from 'd3'; import _ from 'lodash'; import React, { useEffect, useLayoutEffect, useRef, useState } from 'react'; interface D3GaugeChartProps { size?: Record; [key: string]: any; } const D3GaugeChart = (props: D3GaugeChartProps) => { const { size = { width: 300, height: 300 }, option = {}, theme } = props; const height = 600; //画布高度 const width = 600; //画布宽度 const outerRadius = 200; //仪表盘外半径 const innerRadius = 198; //仪表盘内半径 useEffect(() => { const svg = d3 .select('.datav-wrapper') .append('svg') .attr('width', width) .attr('height', height) .style('background', '#000000'); // 在body中添加宽高并绘制背景色 const group = svg .append('g') .attr('class', 'group') .attr('transform', `translate(${width * 0.5}, ${height * 0.5})`); //添加分组并将分组中心移至画布中心 const arc = d3 .arc() .innerRadius(innerRadius) .outerRadius(outerRadius); //编写弧生成器并传入内外半径 const keduListB = Array.from(new Array(61).keys()); //(大)刻度的数组 const keduListS = Array.from(new Array(61).keys()); //(小)刻度的数组 const radiusScaleB = d3 .scaleLinear() .domain([0, 60]) .range([-(Math.PI / 2), Math.PI / 2]); //(大)刻度线性比例尺 const colorScale = d3 .scaleLinear() .domain([0, 60]) .range(['rgba(84, 254, 254, 1)', 'rgba(62, 166, 255, 1)']); //(小)颜色线性比例尺 const baseData = 0; //设置基础速度 group.append('g').attr('class', 'pan'); //绘制仪表盘的圆弧分组 group.append('g').attr('class', 'kedu_b'); //绘制大刻度分组 group.append('g').attr('class', 'kedu_s'); //绘制小刻度分组 group.append('g').attr('class', 'zhizhen'); //绘制指针分组 group.append('g').attr('class', 'shuzi'); //绘制刻度数字分组 group.append('g').attr('class', 'show'); //绘制速度框和数字分组 group.append('g').attr('class', 'button'); //绘制按钮框和数字分组 // 线 轮盘 group .select('.pan') .append('path') .attr('id', 'pan') .attr( 'd', arc({ startAngle: radiusScaleB(0), endAngle: radiusScaleB(60) }), ) .attr('fill', 'rgba(128, 110, 110, 0.5)'); // .attr('stroke', '#6AE3F8'); group .append('text') .text('1111') .attr('x', 0) .attr('y', '0') .attr('fill', 'white') .append('animateMotion') .attr('id', 'animimg') // .attr('path', function(d) { // return arc({ startAngle: radiusScaleB(0), endAngle: radiusScaleB(60) }); // }) .attr('begin', '0s') .attr('dur', '3s') .attr('rotate', 'auto') // .attr('calcMode', 'linear') // .attr('accumulate', 'sum') .attr('repeatCount', '1'); d3.select('#animimg') .append('mpath') //让上面的动画关联运动路径 .attr('xlink:href', '#pan'); // 刻度背景 group .select('.kedu_b') .selectAll('line') .data(keduListB) .enter() .append('line') .attr('x1', d => 190 * Math.sin(radiusScaleB(d))) .attr('y1', d => 190 * Math.cos(radiusScaleB(d)) * -1) .attr('x2', d => 160 * Math.sin(radiusScaleB(d))) .attr('y2', d => 160 * Math.cos(radiusScaleB(d)) * -1) .attr('stroke', 'rgba(128, 110, 110, 0.5)') .attr('stroke-width', 5); // 刻度值 group .select('.kedu_s') .selectAll('line') .data(keduListS) .enter() .append('line') .attr('x1', d => 190 * Math.sin(radiusScaleB(d))) .attr('y1', d => 190 * Math.cos(radiusScaleB(d)) * -1) .attr('x2', d => 160 * Math.sin(radiusScaleB(d))) .attr('y2', d => 160 * Math.cos(radiusScaleB(d)) * -1) .attr('stroke', function(d) { return colorScale(d); }) .attr('stroke-width', 5); // group // .select('.shuzi') // .selectAll('text') // .data(keduListB) // .enter() // .append('text') // .attr('x', d => 160 * Math.sin(radiusScaleB(d))) // .attr('y', d => 160 * Math.cos(radiusScaleB(d)) * -1) // .attr('text-anchor', 'middle') // .attr('dy', '0.35em') // .attr('fill', '#6AE3F8') // .style('text-shadow', '0px 0px 2px #6AE3F8') // .text(d => d * 20); // group // .select('.zhizhen') // .append('polygon') // .attr('points', '-2,-20,2,-20,4,0,1,140,-1,140,-4,0') // .attr('fill', '#6AE3F8') // .attr('transform', 'rotate(60)'); }, []); return
; }; export default D3GaugeChart;