反应车速表或仪表。如何在反应中创建带标签的速度计?
React Speedometer or gauge. How to created labelled speedometer in react?
我用这个库画了速度表。 https://github.com/palerdot/react-d3-speedometer
我想在每个段上设置标签。如果有任何其他图书馆可以绘制这样的图表,请帮忙。
根据对该问题的回答,这是不可行的:Is it possible to set label on segments
Currently the labels are automatically calculated based on maxValue, 'minValue' and segments. This may not be possible at all, as per the library functionality, there will be 5 values for your chart instead of 4 you have mentioned. I'm afraid this is not possible at all as far as I see. So I'm closing this issue.
有很多绘制图表的库,但每个库都有其局限性,对于我的项目,我最终自己实现了图表,这并不难,并且可以让您完全按照自己的需要做事,而不会遇到怪癖。
这是我从 ReactPie component, it draws a PieSegment so you could use that to create a similar result than the gauge pretty easily. You can try it in that pen: https://codepen.io/leefsmp/pen/dJjpXx
中提取的一些代码
class ReactPieSegment extends React.Component {
constructor (props) {
super (props)
}
generatePathDef(centre, rIn, rOut, start, delta) {
const endRad = start + delta
const startOut = {
x: centre.x + rOut * Math.cos(start),
y: centre.y + rOut * Math.sin(start)
}
const endOut = {
x: centre.x + rOut * Math.cos(endRad),
y: centre.y + rOut * Math.sin(endRad)
}
const startIn = {
x: centre.x + rIn * Math.cos(endRad),
y: centre.y + rIn * Math.sin(endRad)
};
var endIn = {
x: centre.x + rIn * Math.cos(start),
y: centre.y + rIn * Math.sin(start)
}
const largeArc = delta > Math.PI ? 1 : 0
return (
`M${startOut.x},${startOut.y}` +
` A${rOut},${rOut} 0 ` +
`${largeArc},1 ${endOut.x},${endOut.y}` +
` L${startIn.x},${startIn.y}` +
` A${rIn},${rIn} 0 ` +
`${largeArc},0 ${endIn.x},${endIn.y}` +
` L${startOut.x},${startOut.y} Z`
)
}
render () {
const {
fillColor, strokeColor,
start, delta,
rIn, rOut,
centre
} = this.props
const pathDef = this.generatePathDef(
centre, rIn, rOut, start, delta)
const labelDist = rIn + 1.2 * (rOut-rIn)
const labelRad = start + 0.5 * delta
const labelPos = {
x: centre.x + labelDist * Math.cos (labelRad) - 10,
y: centre.y + labelDist * Math.sin (labelRad)
}
const labelStyle = {
transform: `translate(${labelPos.x}px, ${labelPos.y}px)`
}
return (
<g className='react-pie-segment'>
<path
stroke={strokeColor}
fill={fillColor}
d={pathDef}
/>
<text style={labelStyle}>
{this.props.label}
</text>
</g>
)
}
}
class Demo extends React.Component {
constructor (props) {
super (props)
}
render() {
return (
<div className="demo">
<svg>
<ReactPieSegment
centre={{x:150, y:150}}
strokeColor={"green"}
fillColor={"green"}
delta={Math.PI/4}
start={Math.PI}
label={"label 1"}
rOut={90}
rIn={50}
/>
<ReactPieSegment
centre={{x:150, y:150}}
strokeColor={"yellow"}
fillColor={"yellow"}
delta={Math.PI/4}
start={5*Math.PI/4}
label={"label 2"}
rOut={90}
rIn={50}
/>
<ReactPieSegment
centre={{x:150, y:150}}
strokeColor={"orange"}
fillColor={"orange"}
delta={Math.PI/4}
start={6*Math.PI/4}
label={"label 3"}
rOut={90}
rIn={50}
/>
<ReactPieSegment
centre={{x:150, y:150}}
strokeColor={"red"}
fillColor={"red"}
delta={Math.PI/4}
start={7*Math.PI/4}
label={"label 4"}
rOut={90}
rIn={50}
/>
</svg>
</div>
)
}
}
const root = document.getElementById('root')
ReactDOM.render(<Demo/>, root)
我用这个库画了速度表。 https://github.com/palerdot/react-d3-speedometer
我想在每个段上设置标签。如果有任何其他图书馆可以绘制这样的图表,请帮忙。
根据对该问题的回答,这是不可行的:Is it possible to set label on segments
Currently the labels are automatically calculated based on maxValue, 'minValue' and segments. This may not be possible at all, as per the library functionality, there will be 5 values for your chart instead of 4 you have mentioned. I'm afraid this is not possible at all as far as I see. So I'm closing this issue.
有很多绘制图表的库,但每个库都有其局限性,对于我的项目,我最终自己实现了图表,这并不难,并且可以让您完全按照自己的需要做事,而不会遇到怪癖。
这是我从 ReactPie component, it draws a PieSegment so you could use that to create a similar result than the gauge pretty easily. You can try it in that pen: https://codepen.io/leefsmp/pen/dJjpXx
中提取的一些代码class ReactPieSegment extends React.Component {
constructor (props) {
super (props)
}
generatePathDef(centre, rIn, rOut, start, delta) {
const endRad = start + delta
const startOut = {
x: centre.x + rOut * Math.cos(start),
y: centre.y + rOut * Math.sin(start)
}
const endOut = {
x: centre.x + rOut * Math.cos(endRad),
y: centre.y + rOut * Math.sin(endRad)
}
const startIn = {
x: centre.x + rIn * Math.cos(endRad),
y: centre.y + rIn * Math.sin(endRad)
};
var endIn = {
x: centre.x + rIn * Math.cos(start),
y: centre.y + rIn * Math.sin(start)
}
const largeArc = delta > Math.PI ? 1 : 0
return (
`M${startOut.x},${startOut.y}` +
` A${rOut},${rOut} 0 ` +
`${largeArc},1 ${endOut.x},${endOut.y}` +
` L${startIn.x},${startIn.y}` +
` A${rIn},${rIn} 0 ` +
`${largeArc},0 ${endIn.x},${endIn.y}` +
` L${startOut.x},${startOut.y} Z`
)
}
render () {
const {
fillColor, strokeColor,
start, delta,
rIn, rOut,
centre
} = this.props
const pathDef = this.generatePathDef(
centre, rIn, rOut, start, delta)
const labelDist = rIn + 1.2 * (rOut-rIn)
const labelRad = start + 0.5 * delta
const labelPos = {
x: centre.x + labelDist * Math.cos (labelRad) - 10,
y: centre.y + labelDist * Math.sin (labelRad)
}
const labelStyle = {
transform: `translate(${labelPos.x}px, ${labelPos.y}px)`
}
return (
<g className='react-pie-segment'>
<path
stroke={strokeColor}
fill={fillColor}
d={pathDef}
/>
<text style={labelStyle}>
{this.props.label}
</text>
</g>
)
}
}
class Demo extends React.Component {
constructor (props) {
super (props)
}
render() {
return (
<div className="demo">
<svg>
<ReactPieSegment
centre={{x:150, y:150}}
strokeColor={"green"}
fillColor={"green"}
delta={Math.PI/4}
start={Math.PI}
label={"label 1"}
rOut={90}
rIn={50}
/>
<ReactPieSegment
centre={{x:150, y:150}}
strokeColor={"yellow"}
fillColor={"yellow"}
delta={Math.PI/4}
start={5*Math.PI/4}
label={"label 2"}
rOut={90}
rIn={50}
/>
<ReactPieSegment
centre={{x:150, y:150}}
strokeColor={"orange"}
fillColor={"orange"}
delta={Math.PI/4}
start={6*Math.PI/4}
label={"label 3"}
rOut={90}
rIn={50}
/>
<ReactPieSegment
centre={{x:150, y:150}}
strokeColor={"red"}
fillColor={"red"}
delta={Math.PI/4}
start={7*Math.PI/4}
label={"label 4"}
rOut={90}
rIn={50}
/>
</svg>
</div>
)
}
}
const root = document.getElementById('root')
ReactDOM.render(<Demo/>, root)