名字
点线图: 不知道怎么命名
效果图
思路
数据: 初始化三条数据, 中间的为显示数据 使用折线图,隐藏折线,隐藏显示数据之外的所有点 X轴:隐藏X轴坐标内容 Y轴:设置y轴内容,y轴标题 注释:添加注释,线条,描述内容
代码(下面有全的子组件代码)
import { Chart
} from "@antv/g2";
useEffect(() => {
(async () => {
const chartBox
= new Chart({
container
: 'c3',
autoFit
: true,
width
: width
,
height
: height
,
title
: true
})
await setChartBox(chartBox
)
const newData
= cloneDeep(cData
)
newData
.splice(1,1, data
)
await setData(() => newData
)
})()
}, [])
const setChart = () => {
const margin
= 1 / 3
chart
.clear()
chart
.data(cData
);
chart
.scale({
date
: {
range
: [margin
/ 2, 1 - margin
/ 2],
},
num
: {
range
: [0, 1 - margin
/ 2],
min
: 0,
max
: max
,
nice
: true,
},
});
chart
.tooltip(false);
chart
.axis('date', {
label
: {
formatter
: (text
) => ""
}
})
chart
.axis('num', {
title
: {
text
: cTitle
,
autoRotate
: false,
position
: "end",
offset
: -10,
textStyle
: {
textAlign
: 'start',
fontSize
: '12',
fontWeight
: 'bold',
textBaseline
: 'top'
},
},
label
: {
formatter
: (text
) => text
}
})
chart
.line().style({
stroke
: "transparent"
}).position('date*num');
chart
.point()
.size(2)
.position('date*num')
.label("name", (val
) => {
if (val
) {
return {
content
: val
,
offsetX
: 12,
offsetY
: 12,
style
: {
fill
: dataColor
,
fontSize
: 12,
},
}
}
})
.style("num*name", ((val
, name
) => {
if (name
) {
return {
stroke
: dataColor
,
fill
: dataColor
}
}
return {
stroke
: "transparent",
lineWidth
: 0
}
}))
chart
.annotation().line({
top
: true,
start
: [-0.5, averageNum
],
end
: [2.5, averageNum
],
style
: {
stroke
: contentColor
,
lineWidth
: 1,
lineDash
: [3, 3],
},
text
: {
position
: 'start',
style
: {
fill
: contentColor
,
fontSize
: 12,
fontWeight
: 500,
},
content
: content
,
offsetY
: -5,
},
});
chart
.render();
}
子组件代码
import React
, { useState
, useEffect
, useRef
} from "react";
import "./chart.less"
import { Chart
} from "@antv/g2";
import { cloneDeep
} from "lodash"
import PropTypes
from 'prop-types';
const Charts = (props
) => {
const {
width
,
height
,
max
,
content
,
contentColor
,
dataColor
,
cTitle
,
data
,
averageNum
} = props
const initData
= [
{ date
: "a", num
: 0 },
{ date
: "b", num
: 0 },
{ date
: "c", num
: 0 }
]
const [cData
, setData
] = useState(initData
)
const [chart
, setChartBox
] = useState(null)
const chartRef
= useRef()
useEffect(() => {
(async () => {
const chartBox
= new Chart({
container
: 'c3',
autoFit
: true,
width
: width
,
height
: height
,
title
: true
})
await setChartBox(chartBox
)
const newData
= cloneDeep(cData
)
newData
.splice(1,1, data
)
await setData(() => newData
)
})()
}, [])
useEffect(() => {
if (cData
[1].name
&& chart
) {
chart
.clear()
setChart()
}
}, [chart
, cData
])
useEffect(() => {
if (cTitle
&& chart
) {
chart
.clear()
setChart()
}
}, [chart
, cTitle
])
useEffect(() => {
(async () => {
const newData
= cloneDeep(cData
)
newData
.splice(1,1, data
)
await setData(() => newData
)
if (data
&& chart
) setChart()
})()
}, [chart
, data
])
const setChart = () => {
const margin
= 1 / 3
chart
.clear()
chart
.data(cData
);
chart
.scale({
date
: {
range
: [margin
/ 2, 1 - margin
/ 2],
},
num
: {
range
: [0, 1 - margin
/ 2],
min
: 0,
max
: max
,
nice
: true,
},
});
chart
.tooltip(false);
chart
.axis('date', {
label
: {
formatter
: (text
) => ""
}
})
chart
.axis('num', {
title
: {
text
: cTitle
,
autoRotate
: false,
position
: "end",
offset
: -10,
textStyle
: {
textAlign
: 'start',
fontSize
: '12',
fontWeight
: 'bold',
textBaseline
: 'top'
},
},
label
: {
formatter
: (text
) => text
}
})
chart
.line().style({
stroke
: "transparent"
}).position('date*num');
chart
.point()
.size(2)
.position('date*num')
.label("name", (val
) => {
if (val
) {
return {
content
: val
,
offsetX
: 12,
offsetY
: 12,
style
: {
fill
: dataColor
,
fontSize
: 12,
},
}
}
})
.style("num*name", ((val
, name
) => {
if (name
) {
return {
stroke
: dataColor
,
fill
: dataColor
}
}
return {
stroke
: "transparent",
lineWidth
: 0
}
}))
chart
.annotation().line({
top
: true,
start
: [-0.5, averageNum
],
end
: [2.5, averageNum
],
style
: {
stroke
: contentColor
,
lineWidth
: 1,
lineDash
: [3, 3],
},
text
: {
position
: 'start',
style
: {
fill
: contentColor
,
fontSize
: 12,
fontWeight
: 500,
},
content
: content
,
offsetY
: -5,
},
});
chart
.render();
}
return (
<div className
={"chart"}>
<div id
="c3" ref
={chartRef
} />
</div
>
)
}
Charts
.defaultProps
= {
max
: 150,
data
: { date
: "c", num
: 60, name
: "我" },
width
: 300,
height
: 200,
dataColor
: "#fe8140",
contentColor
: "#f4a240",
cTitle
: "单位: 小时",
content
: "团队均值: 75",
averageNum
: 75,
}
Charts
.propTypes
= {
max
: PropTypes
.number
,
data
: PropTypes
.object
.isRequired
,
width
: PropTypes
.number
,
height
: PropTypes
.number
,
dataColor
: PropTypes
.string
,
contentColor
: PropTypes
.string
,
cTitle
: PropTypes
.string
,
content
: PropTypes
.string
,
averageNum
: PropTypes
.number
,
}
export default Charts
;
父组件代码
import React
from 'react';
import { Button
} from "antd"
import Chart3
from "./components/chart3"
class Charts extends React.Component {
constructor(props
) {
super(props
);
this.state
= {
cTitle
: "单位: 小时",
data
: { date
: "b", num
: 120, name
: "我" },
averageNum
: 75
}
}
change = () => {
const { cTitle
} = this.state
const flag
= cTitle
=== "单位: 个"
const title
= flag
? "单位: 小时" : "单位: 个"
const data
= flag
?
{ date
: "b", num
: 120, name
: "我" } :
{ date
: "b", num
: 55, name
: "你" }
const averageNum
= flag
? 75 : 55
this.setState({
cTitle
: title
,
data
: data
,
averageNum
: averageNum
,
})
}
render () {
const { cTitle
, data
, averageNum
} = this.state
return (
<div className
={"chartBox"}>
<Chart3
cTitle
={cTitle
}
data
={data
}
key
={data
.num
}
averageNum
={averageNum
}
/>
<Button onClick
={this.change
}>切换
</Button
>
</div
>
)
}
}
export default Charts
;
转载请注明原文地址:https://ipadbbs.8miu.com/read-26152.html