221 lines
5.7 KiB
JavaScript
221 lines
5.7 KiB
JavaScript
import cls from "./index.module.css";
|
||
import "./overwrite.css"; // 覆写 antd 默认样式,全局
|
||
import ReactECharts from "echarts-for-react";
|
||
import * as echarts from "echarts";
|
||
import { Switch, Radio } from "antd";
|
||
import { useEffect, useState } from "react";
|
||
import { useSelector } from "react-redux";
|
||
|
||
const GoodRateChart = (props) => {
|
||
// 是否展示班次数据
|
||
const [showMore, setShowMore] = useState(false);
|
||
// 更新 key,用于刷新图表
|
||
const [updateKey, setUpdateKey] = useState(Date.now());
|
||
// 默认的日期类型
|
||
const [dateType, setDateType] = useState("day");
|
||
const cutting = useSelector((state) => state.cutting);
|
||
|
||
useEffect(() => {
|
||
setUpdateKey(Date.now());
|
||
}, [showMore]);
|
||
|
||
function handleSwitchChange(val) {
|
||
// val: boolean
|
||
setShowMore(val);
|
||
}
|
||
|
||
function handleDateChange({ target }) {
|
||
// e: Event
|
||
setDateType(target.value);
|
||
}
|
||
|
||
// 根据日期类型,数据列表,是否展示班次数据,生成对应的 options
|
||
const options = getOptions(cutting.chart[dateType], showMore, dateType);
|
||
|
||
return (
|
||
<div className={cls.GoodRateChart}>
|
||
<div className={cls.titleBar}>
|
||
<h2>生产良品率</h2>
|
||
<Switch defaultChecked={showMore} onChange={handleSwitchChange} />
|
||
<div className={cls.legend}>
|
||
<span className="legend__title">班次详情</span>
|
||
<ul className="legend__list">
|
||
<li>总量</li>
|
||
{showMore && (
|
||
<>
|
||
<li>白班</li>
|
||
<li>夜班</li>
|
||
</>
|
||
)}
|
||
</ul>
|
||
</div>
|
||
<Radio.Group
|
||
defaultValue="day"
|
||
buttonStyle="solid"
|
||
onChange={handleDateChange}
|
||
className={cls.radioGroup}
|
||
style={{ flex: 1, textAlign: "right" }}
|
||
>
|
||
<Radio.Button value="day" className="radio-group__item">
|
||
日
|
||
</Radio.Button>
|
||
<Radio.Button value="week" className="radio-group__item">
|
||
周
|
||
</Radio.Button>
|
||
<Radio.Button value="month" className="radio-group__item">
|
||
月
|
||
</Radio.Button>
|
||
<Radio.Button value="year" className="radio-group__item">
|
||
年
|
||
</Radio.Button>
|
||
</Radio.Group>
|
||
</div>
|
||
<ReactECharts key={updateKey} option={options} />
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default GoodRateChart;
|
||
|
||
function getOptions(dataList, showMore, dateType) {
|
||
const list = [...dataList].sort((a, b) => a.dataTime - b.dataTime);
|
||
// data: Array(7)
|
||
// .fill(1)
|
||
// .map((_, index) => {
|
||
// const today = new Date();
|
||
// const dtimestamp = today - index * 24 * 60 * 60 * 1000;
|
||
// return `${new Date(dtimestamp).getMonth() + 1}.${new Date(
|
||
// dtimestamp
|
||
// ).getDate()}`;
|
||
// })
|
||
// .reverse(),
|
||
const color = ["#FFD160", "#12FFF5", "#2760FF"];
|
||
const grid = { top: 28, right: 12, bottom: 48, left: 48 };
|
||
const xAxis = {
|
||
type: "category",
|
||
data: list.map((item) =>
|
||
dateType == "day"
|
||
? item.dataTime.split("T")[1]
|
||
: item.dataTime.split("T")[0]
|
||
),
|
||
// data: list.map((item) => {
|
||
// console.log("datetime", item.dataTime);
|
||
// return item.dataTime.split("T")[0];
|
||
// }),
|
||
axisLabel: {
|
||
color: "#fff",
|
||
fontSize: 10,
|
||
rotate: 25,
|
||
margin: 13,
|
||
},
|
||
axisTick: { show: false },
|
||
axisLine: {
|
||
lineStyle: {
|
||
width: 1,
|
||
color: "#213259",
|
||
},
|
||
},
|
||
};
|
||
const yAxis = {
|
||
type: "value",
|
||
axisLabel: {
|
||
color: "#fff",
|
||
fontSize: 12,
|
||
formatter: "{value} %",
|
||
},
|
||
axisLine: {
|
||
show: true,
|
||
lineStyle: {
|
||
color: "#213259",
|
||
},
|
||
},
|
||
splitLine: {
|
||
lineStyle: {
|
||
color: "#213259a0",
|
||
},
|
||
},
|
||
interval: 10,
|
||
min: 0,
|
||
max: 100,
|
||
};
|
||
const seriesTeam = [
|
||
{
|
||
data: list.map((item) => item.day * 100),
|
||
type: "line",
|
||
areaStyle: {
|
||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||
{ offset: 0, color: "#12FFF540" },
|
||
{ offset: 0.5, color: "#12FFF520" },
|
||
{ offset: 1, color: "#12FFF510" },
|
||
]),
|
||
},
|
||
// smooth: true,
|
||
},
|
||
{
|
||
data: list.map((item) => item.night * 100),
|
||
type: "line",
|
||
areaStyle: {
|
||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||
{ offset: 0, color: "#2760FF40" },
|
||
{ offset: 0.5, color: "#2760FF20" },
|
||
{ offset: 1, color: "#2760FF10" },
|
||
]),
|
||
},
|
||
// smooth: true,
|
||
},
|
||
];
|
||
return {
|
||
grid,
|
||
color,
|
||
xAxis,
|
||
yAxis,
|
||
tooltip: {
|
||
trigger: "axis",
|
||
color: "#fff",
|
||
formatter: "{b} {c}%",
|
||
axisPointer: {
|
||
type: "shadow",
|
||
},
|
||
textStyle: {
|
||
color: "#fffc",
|
||
},
|
||
className: "xc-chart-tooltip",
|
||
// backgroundColor: ''
|
||
},
|
||
series: [
|
||
{
|
||
data: list.map((item) => (item.sum * 100).toFixed(2)),
|
||
type: "line",
|
||
symbol: 'circle',
|
||
symbolSize: 6,
|
||
areaStyle: {
|
||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||
{ offset: 0, color: "#FFD16040" },
|
||
{ offset: 0.5, color: "#FFD16020" },
|
||
{ offset: 1, color: "#FFD16010" },
|
||
]),
|
||
},
|
||
// smooth: true,
|
||
},
|
||
...(showMore ? seriesTeam : []),
|
||
],
|
||
};
|
||
}
|
||
|
||
// {
|
||
// data: Array(7)
|
||
// .fill(1)
|
||
// .map((_) => {
|
||
// return randomInt(60, 100);
|
||
// }),
|
||
// type: "line",
|
||
// areaStyle: {
|
||
// color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||
// { offset: 0, color: "#FFD16040" },
|
||
// { offset: 0.5, color: "#FFD16020" },
|
||
// { offset: 1, color: "#FFD16010" },
|
||
// ]),
|
||
// },
|
||
// // smooth: true,
|
||
// },
|