Merge branch 'master' of git.picaiba.com:g7hoo/xuchang-new
Šī revīzija ir iekļauta:
revīzija
682cfc0407
@ -94,69 +94,69 @@
|
||||
/** center top **/
|
||||
.TE227 {
|
||||
top: 128px;
|
||||
left: 660px;
|
||||
left: 630px;
|
||||
}
|
||||
.TE229 {
|
||||
top: 128px;
|
||||
left: 776px; /* +120px */
|
||||
left: 746px; /* +120px */
|
||||
}
|
||||
.TE231 {
|
||||
top: 128px;
|
||||
left: 896px;
|
||||
left: 866px;
|
||||
}
|
||||
.TE233 {
|
||||
top: 128px;
|
||||
left: 1006px;
|
||||
left: 980px;
|
||||
}
|
||||
.TE235 {
|
||||
top: 128px;
|
||||
left: 1119px;
|
||||
left: 1100px;
|
||||
}
|
||||
.TE237 {
|
||||
top: 128px;
|
||||
left: 1236px;
|
||||
left: 1220px;
|
||||
}
|
||||
.TE239 {
|
||||
top: 128px;
|
||||
left: 1346px;
|
||||
left: 1330px;
|
||||
}
|
||||
.TE241 {
|
||||
top: 128px;
|
||||
left: 1456px;
|
||||
left: 1450px;
|
||||
}
|
||||
|
||||
/** center bottom **/
|
||||
.TE228 {
|
||||
top: 620px;
|
||||
left: 628px;
|
||||
left: 600px;
|
||||
}
|
||||
.TE230 {
|
||||
top: 620px;
|
||||
left: 750px;
|
||||
left: 720px;
|
||||
}
|
||||
.TE232 {
|
||||
top: 620px;
|
||||
left: 870px;
|
||||
left: 850px;
|
||||
}
|
||||
.TE234 {
|
||||
top: 620px;
|
||||
left: 995px;
|
||||
left: 970px;
|
||||
}
|
||||
.TE236 {
|
||||
top: 620px;
|
||||
left: 1120px;
|
||||
left: 1100px;
|
||||
}
|
||||
.TE238 {
|
||||
top: 620px;
|
||||
left: 1245px;
|
||||
left: 1225px;
|
||||
}
|
||||
.TE240 {
|
||||
top: 620px;
|
||||
left: 1370px;
|
||||
left: 1350px;
|
||||
}
|
||||
.TE242 {
|
||||
top: 620px;
|
||||
left: 1480px;
|
||||
left: 1470px;
|
||||
}
|
||||
|
||||
/** center middle **/
|
||||
@ -244,7 +244,7 @@
|
||||
left: 2070px;
|
||||
}
|
||||
.TE218 {
|
||||
top: 640px;
|
||||
top: 660px;
|
||||
left: 2090px;
|
||||
}
|
||||
.TE219 {
|
||||
@ -264,7 +264,7 @@
|
||||
left: 2180px;
|
||||
}
|
||||
.TE223 {
|
||||
top: 640px;
|
||||
top: 660px;
|
||||
left: 2200px;
|
||||
}
|
||||
.TE224 {
|
||||
@ -309,69 +309,69 @@
|
||||
/** center top **/
|
||||
.TE333 {
|
||||
top: 128px;
|
||||
left: 620px;
|
||||
left: 670px;
|
||||
}
|
||||
.TE335 {
|
||||
top: 128px;
|
||||
left: 735px;
|
||||
left: 785px;
|
||||
}
|
||||
.TE337 {
|
||||
top: 128px;
|
||||
left: 855px;
|
||||
left: 890px;
|
||||
}
|
||||
.TE339 {
|
||||
top: 128px;
|
||||
left: 975px;
|
||||
left: 1010px;
|
||||
}
|
||||
.TE341 {
|
||||
top: 128px;
|
||||
left: 1090px;
|
||||
left: 1120px;
|
||||
}
|
||||
.TE343 {
|
||||
top: 128px;
|
||||
left: 1205px;
|
||||
left: 1235px;
|
||||
}
|
||||
.TE345 {
|
||||
top: 128px;
|
||||
left: 1325px;
|
||||
left: 1345px;
|
||||
}
|
||||
.TE347 {
|
||||
top: 128px;
|
||||
left: 1440px;
|
||||
left: 1450px;
|
||||
}
|
||||
|
||||
/** center bottom **/
|
||||
.TE334 {
|
||||
top: 620px;
|
||||
left: 588px;
|
||||
left: 620px;
|
||||
}
|
||||
.TE336 {
|
||||
top: 620px;
|
||||
left: 710px;
|
||||
left: 740px;
|
||||
}
|
||||
.TE338 {
|
||||
top: 620px;
|
||||
left: 840px;
|
||||
left: 860px;
|
||||
}
|
||||
.TE340 {
|
||||
top: 620px;
|
||||
left: 965px;
|
||||
left: 1000px;
|
||||
}
|
||||
.TE342 {
|
||||
top: 620px;
|
||||
left: 1090px;
|
||||
left: 1120px;
|
||||
}
|
||||
.TE344 {
|
||||
top: 620px;
|
||||
left: 1215px;
|
||||
left: 1245px;
|
||||
}
|
||||
.TE346 {
|
||||
top: 620px;
|
||||
left: 1340px;
|
||||
left: 1370px;
|
||||
}
|
||||
.TE348 {
|
||||
top: 620px;
|
||||
left: 1460px;
|
||||
left: 1490px;
|
||||
}
|
||||
|
||||
/** center middle **/
|
||||
|
@ -7,7 +7,7 @@ import ReactECharts from 'echarts-for-react';
|
||||
const EnergyCostChart = (props) => {
|
||||
const options = {
|
||||
color: ['#FFD160', '#12FFF5', '#2760FF'],
|
||||
grid: { top: 32, right: 12, bottom: 20, left: 48 },
|
||||
grid: { top: 32, right: 12, bottom: 56, left: 48 },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: Array(7)
|
||||
|
@ -11,7 +11,7 @@ function FeederStatus(props) {
|
||||
style={{
|
||||
position: "absolute",
|
||||
bottom: "128px",
|
||||
left: "800px",
|
||||
left: "740px",
|
||||
width: "300px",
|
||||
height: "80px",
|
||||
zIndex: "-1",
|
||||
|
@ -51,7 +51,7 @@ function getOptions(series, isra, currentStatistic) {
|
||||
color: "#DFF1FE",
|
||||
fontSize: 12,
|
||||
},
|
||||
data: isra.checkTypeList,
|
||||
data: isra.checkType,
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
@ -115,7 +115,7 @@ function FaultTotal(props) {
|
||||
? isra.yearStatistic
|
||||
: [];
|
||||
|
||||
const series = preHandleStatisticData(currentStatistic, isra.checkTypeList);
|
||||
const series = preHandleStatisticData(currentStatistic, isra.checkType);
|
||||
const options = getOptions(series, isra, currentStatistic);
|
||||
|
||||
function handleDateChange(v) {
|
||||
|
@ -1,77 +1,22 @@
|
||||
import cls from "./index.module.css";
|
||||
import GraphBase from "../GraphBase";
|
||||
import ReactECharts from "echarts-for-react";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
function getOptions(series) {
|
||||
return {
|
||||
color: ["#2760FF", "#8167F6", "#5B9BFF", "#99D66C", "#FFD160", "#FF8A40"],
|
||||
grid: {
|
||||
left: 24,
|
||||
top: 10,
|
||||
bottom: 10,
|
||||
right: 24,
|
||||
},
|
||||
legend: {
|
||||
icon: "circle",
|
||||
top: 32,
|
||||
right: 0,
|
||||
bottom: 32,
|
||||
width: 296,
|
||||
height: 130,
|
||||
itemGap: 30,
|
||||
formatter: function (name) {
|
||||
return `${name} {sub|${
|
||||
series[0].data.find((o) => o.name == name).value
|
||||
}}`;
|
||||
},
|
||||
textStyle: {
|
||||
color: "#DFF1FE",
|
||||
fontSize: 18,
|
||||
rich: {
|
||||
sub: {
|
||||
color: "#fff9",
|
||||
fontSize: 18,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
series,
|
||||
};
|
||||
}
|
||||
|
||||
function getSeries(currentStatistic, currentLine) {
|
||||
const currentItem = currentStatistic.find((item) => item.name == currentLine);
|
||||
return [
|
||||
{
|
||||
type: "pie",
|
||||
center: ["26%", "54%"],
|
||||
radius: ["55%", "75%"],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: true,
|
||||
formatter: "{d}%",
|
||||
fontSize: 14,
|
||||
color: "inherit",
|
||||
},
|
||||
labelLine: {
|
||||
length: 0,
|
||||
},
|
||||
data: currentItem.data.map((item) => ({
|
||||
value: item.checkNum,
|
||||
name: item.checkType,
|
||||
})),
|
||||
},
|
||||
];
|
||||
}
|
||||
import { randomInt } from "../../../utils";
|
||||
|
||||
function FaultType(props) {
|
||||
const [init, setInit] = useState(true);
|
||||
const [currentLine, setCurrentLine] = useState("");
|
||||
const isra = useSelector((state) => state.isra);
|
||||
const currentStatistic = isra.dayStatistic || [];
|
||||
const currentLineStatistic =
|
||||
currentLine != ""
|
||||
? currentStatistic.find((item) => item.name === currentLine)?.data || []
|
||||
: [];
|
||||
const lines = currentStatistic.map((item) => item.name);
|
||||
const CHART_TYPE = "line"; // "pie" | "line";
|
||||
|
||||
useEffect(() => {
|
||||
if (init == false) return;
|
||||
if (lines.length) {
|
||||
@ -82,7 +27,12 @@ function FaultType(props) {
|
||||
|
||||
const options = init
|
||||
? {}
|
||||
: getOptions(getSeries(currentStatistic, currentLine));
|
||||
: getOptions(
|
||||
CHART_TYPE == "pie"
|
||||
? getSeries(currentStatistic, currentLine)
|
||||
: currentLineStatistic,
|
||||
CHART_TYPE
|
||||
);
|
||||
|
||||
function handleLineChange(line) {
|
||||
setCurrentLine(line);
|
||||
@ -124,3 +74,149 @@ function FaultType(props) {
|
||||
}
|
||||
|
||||
export default FaultType;
|
||||
|
||||
function getOptions(data, chart_type) {
|
||||
const color = [
|
||||
"#2760FF",
|
||||
"#8167F6",
|
||||
"#5B9BFF",
|
||||
"#99D66C",
|
||||
"#FFD160",
|
||||
"#FF8A40",
|
||||
];
|
||||
const grid = {
|
||||
left: 24,
|
||||
top: 10,
|
||||
bottom: 10,
|
||||
right: 24,
|
||||
};
|
||||
const legend_common = {
|
||||
icon: "circle",
|
||||
top: 32,
|
||||
right: 0,
|
||||
bottom: 32,
|
||||
width: 296,
|
||||
height: 130,
|
||||
itemGap: 30,
|
||||
textStyle: {
|
||||
color: "#DFF1FE",
|
||||
fontSize: 18,
|
||||
rich: {
|
||||
sub: {
|
||||
color: "#fff9",
|
||||
fontSize: 18,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
if (chart_type == "pie") {
|
||||
return {
|
||||
color,
|
||||
grid,
|
||||
legend: {
|
||||
...legend_common,
|
||||
formatter: function (name) {
|
||||
return `${name} {sub|${
|
||||
data[0].data.find((o) => o.name == name).value
|
||||
}}`;
|
||||
},
|
||||
},
|
||||
series: data,
|
||||
};
|
||||
} else if (chart_type == "line") {
|
||||
const dataList = data.map((item) => ({
|
||||
category: item.checkType,
|
||||
value: item.checkNum,
|
||||
}));
|
||||
|
||||
return {
|
||||
grid: {
|
||||
top: 48,
|
||||
left: 48,
|
||||
bottom: 40,
|
||||
right: 18,
|
||||
},
|
||||
legend: {
|
||||
...legend_common,
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "item",
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: (dataList || []).map((item) => item.category),
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
fontSize: 12,
|
||||
rotate: 24,
|
||||
},
|
||||
axisTick: { show: false },
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: "#213259",
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
name: "单位/个",
|
||||
nameTextStyle: {
|
||||
color: "#fff",
|
||||
fontSize: 10,
|
||||
align: "right",
|
||||
},
|
||||
type: "value",
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
fontSize: 12,
|
||||
formatter: "{value}",
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: "#213259",
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: "#213259a0",
|
||||
},
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: "bar",
|
||||
itemStyle: {
|
||||
color: color[randomInt(0, color.length - 1)],
|
||||
},
|
||||
data: (dataList || []).map((item) => item.value),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function getSeries(currentStatistic, currentLine) {
|
||||
const currentItem = currentStatistic.find((item) => item.name == currentLine);
|
||||
return [
|
||||
{
|
||||
type: "pie",
|
||||
center: ["26%", "54%"],
|
||||
radius: ["55%", "75%"],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: true,
|
||||
formatter: "{d}%",
|
||||
fontSize: 14,
|
||||
color: "inherit",
|
||||
},
|
||||
labelLine: {
|
||||
length: 0,
|
||||
},
|
||||
data: currentItem.data.map((item) => ({
|
||||
value: item.checkNum,
|
||||
name: item.checkType,
|
||||
})),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
import cls from './good.module.scss';
|
||||
import Container from '../../Container';
|
||||
import TodayTableData from './components/TodayTableData';
|
||||
import GoodRateChart from './components/GoodRateChart';
|
||||
import TechSplitline from '../TechSplitline';
|
||||
import cls from "./good.module.scss";
|
||||
import Container from "../../Container";
|
||||
import TodayTableData from "./components/TodayTableData";
|
||||
import GoodRateChart from "./components/GoodRateChart";
|
||||
import TechSplitline from "../TechSplitline";
|
||||
|
||||
const GoodProduction = () => {
|
||||
return (
|
||||
<Container icon="good" title="本日生产良品率" className={cls.goodProd}>
|
||||
<div className={`${cls.goodProd__content} h-full`}>
|
||||
<TodayTableData />
|
||||
<TechSplitline />
|
||||
<GoodRateChart />
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
return (
|
||||
<Container icon="good" title="本日生产良品率" className={cls.goodProd}>
|
||||
<div className={`${cls.goodProd__content} h-full`}>
|
||||
<TodayTableData />
|
||||
<TechSplitline />
|
||||
<GoodRateChart />
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default GoodProduction;
|
||||
|
@ -1,154 +1,205 @@
|
||||
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 { randomInt } from '../../../../../utils';
|
||||
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 { randomInt } from "../../../../../utils";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
const GoodRateChart = (props) => {
|
||||
const options = {
|
||||
color: ['#FFD160', '#12FFF5', '#2760FF'],
|
||||
grid: { top: 28, right: 12, bottom: 32, left: 48 },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
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(),
|
||||
axisLabel: {
|
||||
color: '#fff',
|
||||
fontSize: 12,
|
||||
},
|
||||
axisTick: { show: false },
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: '#213259',
|
||||
},
|
||||
},
|
||||
},
|
||||
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,
|
||||
},
|
||||
series: [
|
||||
{
|
||||
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,
|
||||
},
|
||||
{
|
||||
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: '#12FFF540' },
|
||||
{ offset: 0.5, color: '#12FFF520' },
|
||||
{ offset: 1, color: '#12FFF510' },
|
||||
]),
|
||||
},
|
||||
// smooth: true,
|
||||
},
|
||||
{
|
||||
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: '#2760FF40' },
|
||||
{ offset: 0.5, color: '#2760FF20' },
|
||||
{ offset: 1, color: '#2760FF10' },
|
||||
]),
|
||||
},
|
||||
// smooth: true,
|
||||
},
|
||||
],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
},
|
||||
};
|
||||
// 是否展示班次数据
|
||||
const [showMore, setShowMore] = useState(false);
|
||||
// 更新 key,用于刷新图表
|
||||
const [updateKey, setUpdateKey] = useState(Date.now());
|
||||
// 默认的日期类型
|
||||
const [dateType, setDateType] = useState("day");
|
||||
const cutting = useSelector((state) => state.cutting);
|
||||
|
||||
function handleSwitchChange(val) {
|
||||
// val: boolean
|
||||
}
|
||||
console.log("cutting chart", dateType, cutting.chart[dateType]);
|
||||
|
||||
return (
|
||||
<div className={cls.GoodRateChart}>
|
||||
<div className={cls.titleBar}>
|
||||
<h2>生产良品率</h2>
|
||||
<Switch defaultChecked onChange={handleSwitchChange} />
|
||||
<div className={cls.legend}>
|
||||
<span className="legend__title">班次详情</span>
|
||||
<ul className="legend__list">
|
||||
<li>总量</li>
|
||||
<li>白班</li>
|
||||
<li>夜班</li>
|
||||
</ul>
|
||||
</div>
|
||||
<Radio.Group
|
||||
defaultValue="week"
|
||||
buttonStyle="solid"
|
||||
className={cls.radioGroup}
|
||||
>
|
||||
<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 option={options} />
|
||||
</div>
|
||||
);
|
||||
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);
|
||||
|
||||
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) {
|
||||
console.log("showmore", showMore);
|
||||
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) => item.dataTime.split("T")[0]),
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
fontSize: 12,
|
||||
rotate: 45,
|
||||
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",
|
||||
formatter: "{b} {c}%",
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: list.map((item) => item.sum * 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,
|
||||
},
|
||||
...(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,
|
||||
// },
|
||||
|
@ -1,86 +1,87 @@
|
||||
.GoodRateChart {
|
||||
height: 1px;
|
||||
flex: 1;
|
||||
padding-top: 8px;
|
||||
/* background: #ae27276a; */
|
||||
height: 1px;
|
||||
flex: 1;
|
||||
padding-top: 8px;
|
||||
/* background: #ae27276a; */
|
||||
}
|
||||
.GoodRateChart .titleBar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
color: white;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
color: white;
|
||||
}
|
||||
.GoodRateChart .titleBar h2 {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
line-height: 32px;
|
||||
letter-spacing: 1.2px;
|
||||
color: #52fff8;
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
line-height: 32px;
|
||||
letter-spacing: 1.2px;
|
||||
color: #52fff8;
|
||||
}
|
||||
|
||||
.GoodRateChart .titleBar .legend {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.GoodRateChart .titleBar .legend * {
|
||||
font-size: 14px;
|
||||
line-height: 14px;
|
||||
color: #dff1fe;
|
||||
font-size: 14px;
|
||||
line-height: 14px;
|
||||
color: #dff1fe;
|
||||
}
|
||||
|
||||
.GoodRateChart .titleBar .legend ul {
|
||||
display: flex;
|
||||
margin: 0;
|
||||
margin-left: 8px;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
margin: 0;
|
||||
margin-left: 8px;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
align-items: center;
|
||||
}
|
||||
.GoodRateChart .titleBar .legend ul li {
|
||||
position: relative;
|
||||
margin: 4px;
|
||||
padding-left: 16px;
|
||||
position: relative;
|
||||
margin: 4px;
|
||||
padding-left: 16px;
|
||||
}
|
||||
.GoodRateChart .titleBar .legend ul li::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 2px;
|
||||
top: 2px;
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 2px;
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 2px;
|
||||
top: 2px;
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.GoodRateChart .titleBar .legend ul li:first-child::before {
|
||||
background-color: #ffd160;
|
||||
background-color: #ffd160;
|
||||
}
|
||||
|
||||
.GoodRateChart .titleBar .legend ul li:nth-child(2)::before {
|
||||
background-color: #12fff5;
|
||||
background-color: #12fff5;
|
||||
}
|
||||
|
||||
.GoodRateChart .titleBar .legend ul li:nth-child(3)::before {
|
||||
background-color: #2760ff;
|
||||
background-color: #2760ff;
|
||||
}
|
||||
|
||||
.radioGroup * {
|
||||
border: none !important;
|
||||
border-radius: 0 !important;
|
||||
border: none !important;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
.radioGroup *:focus-within {
|
||||
box-shadow: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.radioGroup *::before {
|
||||
width: 0 !important;
|
||||
width: 0 !important;
|
||||
}
|
||||
|
||||
.radioGroup_button_wrapper {
|
||||
color: #fff !important;
|
||||
background: #03233c !important;
|
||||
color: #fff !important;
|
||||
background: #03233c !important;
|
||||
}
|
||||
|
||||
.radioGroup_button_wrapper.ant-radio-button-wrapper-checked {
|
||||
background: #02457e !important;
|
||||
background: #02457e !important;
|
||||
}
|
||||
|
@ -1,9 +1,16 @@
|
||||
import { useState } from "react";
|
||||
import cls from "./index.module.scss";
|
||||
import { ScrollBoard } from "@jiaminghi/data-view-react";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
function getRate(decimal) {
|
||||
return (decimal.toFixed(2) * 100).toFixed(2) + "%";
|
||||
}
|
||||
|
||||
const TodayTableData = (props) => {
|
||||
const [config, setConfig] = useState({
|
||||
const cutting = useSelector((state) => state.cutting);
|
||||
|
||||
const config = {
|
||||
// headerBGC: 'rgba(4, 44, 76, 0.3)',
|
||||
headerBGC: "rgba(4, 44, 76, .8)",
|
||||
header: [
|
||||
@ -18,14 +25,21 @@ const TodayTableData = (props) => {
|
||||
columnWidth: [90],
|
||||
headerHeight: 40,
|
||||
hoverPause: false,
|
||||
data: [
|
||||
["Y61", "37%", "62%", "97%", "7%"],
|
||||
["Y62", "95%", "10%", "99%", "3%"],
|
||||
["Y63", "68%", "1%", "92%", "4%"],
|
||||
["Y64", "94%", "21%", "97%", "2%"],
|
||||
["Y65", "99%", "30%", "95%", "5%"],
|
||||
],
|
||||
});
|
||||
data: cutting.table.map((line) => [
|
||||
line.lineName,
|
||||
getRate(line.first),
|
||||
getRate(line.second),
|
||||
getRate(line.product),
|
||||
getRate(line.waste),
|
||||
]),
|
||||
// data: [
|
||||
// ["Y61", "37%", "62%", "97%", "7%"],
|
||||
// ["Y62", "95%", "10%", "99%", "3%"],
|
||||
// ["Y63", "68%", "1%", "92%", "4%"],
|
||||
// ["Y64", "94%", "21%", "97%", "2%"],
|
||||
// ["Y65", "99%", "30%", "95%", "5%"],
|
||||
// ],
|
||||
};
|
||||
return (
|
||||
<div className={cls.todayTableData}>
|
||||
<ScrollBoard config={config} style={{ width: "100%" }} />
|
||||
|
@ -2,12 +2,13 @@ import { motion, AnimatePresence } from "framer-motion";
|
||||
import { useRef, useEffect, useMemo, useCallback, useState } from "react";
|
||||
import FeederStatus from "../../../../Common/Feeder";
|
||||
import TemperatureBottom from "../../../../Common/TemperatureBottom";
|
||||
import TemperatureTop from "../../../../Common/TemperatureTop";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
|
||||
function EnterToFloorOne(props) {
|
||||
// const ctx = useContext(SocketContext);
|
||||
const ctx = null;
|
||||
const fireInfo = useSelector((state) => state.fireInfo);
|
||||
const fireDir = fireInfo?.fireDirection || null;
|
||||
|
||||
const fireDir = ctx?.runState?.fireDirection || null;
|
||||
const [fireCanPlay, setFireCanPlay] = useState(false);
|
||||
const vd = useRef(null);
|
||||
const show = props.opacity || 0;
|
||||
@ -69,10 +70,10 @@ function EnterToFloorOne(props) {
|
||||
></video>
|
||||
)}
|
||||
|
||||
<TemperatureBottom
|
||||
<TemperatureTop
|
||||
style={{
|
||||
top: "218px",
|
||||
left: "688px",
|
||||
left: "678px",
|
||||
width: "2380px",
|
||||
zIndex: 0,
|
||||
}}
|
||||
|
@ -2,12 +2,13 @@ import { motion, AnimatePresence } from "framer-motion";
|
||||
import { useRef, useEffect, useMemo, useState } from "react";
|
||||
import FeederStatus from "../../../../Common/Feeder";
|
||||
import TemperatureTop from "../../../../../components/Common/TemperatureTop";
|
||||
|
||||
import TemperatureBottom from "../../../../Common/TemperatureBottom";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
|
||||
function FloorOneToTwo(props) {
|
||||
const ctx = null;
|
||||
const fireInfo = useSelector((state) => state.fireInfo);
|
||||
const fireDir = fireInfo?.fireDirection || null;
|
||||
|
||||
const fireDir = ctx?.runState?.fireDirection || null;
|
||||
const [fireCanPlay, setFireCanPlay] = useState(false);
|
||||
|
||||
const vd = useRef(null);
|
||||
@ -72,7 +73,7 @@ function FloorOneToTwo(props) {
|
||||
></video>
|
||||
)}
|
||||
|
||||
<TemperatureTop
|
||||
<TemperatureBottom
|
||||
style={{
|
||||
top: "208px",
|
||||
left: "638px",
|
||||
|
@ -2,11 +2,12 @@ import { motion, AnimatePresence } from "framer-motion";
|
||||
import { useRef, useEffect, useMemo, useState } from "react";
|
||||
import FeederStatus from "../../../../Common/Feeder";
|
||||
import TemperatureBottom from "../../../../Common/TemperatureBottom";
|
||||
import TemperatureTop from "../../../../Common/TemperatureTop";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
|
||||
function FloorTwoToOne(props) {
|
||||
const ctx = null;
|
||||
|
||||
const fireDir = ctx?.runState?.fireDirection || null;
|
||||
const fireInfo = useSelector((state) => state.fireInfo);
|
||||
const fireDir = fireInfo?.fireDirection || null;
|
||||
const [fireCanPlay, setFireCanPlay] = useState(false);
|
||||
|
||||
const vd = useRef(null);
|
||||
@ -72,15 +73,15 @@ function FloorTwoToOne(props) {
|
||||
></video>
|
||||
)}
|
||||
|
||||
<TemperatureBottom
|
||||
<TemperatureTop
|
||||
style={{
|
||||
top: "208px",
|
||||
left: "638px",
|
||||
top: "200px",
|
||||
left: "628px",
|
||||
width: "2380px",
|
||||
zIndex: 0,
|
||||
}}
|
||||
/>
|
||||
<FeederStatus />
|
||||
<FeederStatus style={{ left: "680px" }} />
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
@ -40,7 +40,7 @@ export default function useSlider(defaultSize) {
|
||||
|
||||
return () => {
|
||||
document.removeEventListener('keydown', fn);
|
||||
document.getElementById('slider').removeEventListener('mouseleave', fn2);
|
||||
document.getElementById('slider')?.removeEventListener('mouseleave', fn2);
|
||||
};
|
||||
}, [value]);
|
||||
|
||||
|
@ -60,6 +60,8 @@ body {
|
||||
background: url(./assets/moxing.png) no-repeat;
|
||||
background-position: 50% 50%;
|
||||
background-size: 170% 200%;
|
||||
position: relative;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
#FullScreen .Main .Center .Button {
|
||||
|
@ -49,7 +49,7 @@ export default function Home({ active }) {
|
||||
<CenterTopData />
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
<div key="v3d" className="V3DBorder"></div>
|
||||
<div key="v3d" className="V3DBorder" style={{ zIndex: -2 }}></div>
|
||||
|
||||
{fireDir && fireDir == "东火" && (
|
||||
<video
|
||||
@ -58,7 +58,12 @@ export default function Home({ active }) {
|
||||
autoPlay
|
||||
loop
|
||||
width={4200}
|
||||
style={{ position: "absolute", top: "-160px", left: "-910px" }}
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "-160px",
|
||||
left: "-910px",
|
||||
zIndex: -1,
|
||||
}}
|
||||
></video>
|
||||
)}
|
||||
|
||||
@ -69,7 +74,12 @@ export default function Home({ active }) {
|
||||
autoPlay
|
||||
loop
|
||||
width={4200}
|
||||
style={{ position: "absolute", top: "-180px", left: "-910px" }}
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "-180px",
|
||||
left: "-910px",
|
||||
zIndex: -1,
|
||||
}}
|
||||
></video>
|
||||
)}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
|
||||
export const initialState = {
|
||||
checkTypeList: [],
|
||||
checkType: [],
|
||||
dayStatistic: [],
|
||||
monthStatistic: [],
|
||||
yearStatistic: [],
|
||||
@ -12,8 +12,8 @@ const israSlice = createSlice({
|
||||
name: "isra",
|
||||
initialState,
|
||||
reducers: {
|
||||
setCheckTypeList: (state, action) => {
|
||||
state.checkTypeList = action.payload;
|
||||
setCheckType: (state, action) => {
|
||||
state.checkType = action.payload;
|
||||
},
|
||||
setDayStatistic: (state, action) => {
|
||||
state.dayStatistic = action.payload;
|
||||
@ -32,7 +32,7 @@ const israSlice = createSlice({
|
||||
|
||||
export default israSlice.reducer;
|
||||
export const {
|
||||
setCheckTypeList,
|
||||
setCheckType,
|
||||
setDayStatistic,
|
||||
setWeekStatistic,
|
||||
setMonthStatistic,
|
||||
|
41
src/store/features/cuttingSlice.js
Parasts fails
41
src/store/features/cuttingSlice.js
Parasts fails
@ -0,0 +1,41 @@
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
|
||||
export const initialState = {
|
||||
table: [],
|
||||
chart: {
|
||||
year: [],
|
||||
week: [],
|
||||
month: [],
|
||||
day: [],
|
||||
},
|
||||
};
|
||||
|
||||
const cuttingSlice = createSlice({
|
||||
name: "cutting",
|
||||
initialState,
|
||||
reducers: {
|
||||
setCuttingTable: (state, action) => {
|
||||
console.log("setting cuttting table...");
|
||||
state.table = action.payload;
|
||||
},
|
||||
setCuttingChart: (state, action) => {
|
||||
switch (action.payload.dateType) {
|
||||
case "year":
|
||||
state.chart.year = action.payload.detData;
|
||||
break;
|
||||
case "weekly":
|
||||
state.chart.week = action.payload.detData;
|
||||
break;
|
||||
case "month":
|
||||
state.chart.month = action.payload.detData;
|
||||
break;
|
||||
case "day":
|
||||
state.chart.day = action.payload.detData;
|
||||
break;
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default cuttingSlice.reducer;
|
||||
export const { setCuttingTable, setCuttingChart } = cuttingSlice.actions;
|
@ -19,7 +19,7 @@ export const stateNameMap = {
|
||||
combustionAirPressure: "助燃风压力",
|
||||
topTemp: "碹顶加权温度",
|
||||
compressedAirPressure: "压缩气压力",
|
||||
meltTemp: "融化加权温度",
|
||||
meltTemp: "熔化加权温度",
|
||||
};
|
||||
|
||||
const kilnSlice = createSlice({
|
||||
|
@ -12,6 +12,7 @@ import energySlice from "./features/EnergySlice";
|
||||
import israReducer from "./features/QualityIsraSlice";
|
||||
import annealFanFrequenceReducer from "./features/annealFanFrequenceSlice";
|
||||
import annealFanInfoReducer from "./features/annealFanInfoSlice";
|
||||
import cuttingReducer from "./features/cuttingSlice";
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: {
|
||||
@ -41,5 +42,7 @@ export const store = configureStore({
|
||||
energy: energySlice,
|
||||
// 能耗
|
||||
isra: israReducer,
|
||||
// 切割
|
||||
cutting: cuttingReducer
|
||||
},
|
||||
});
|
||||
|
@ -14,7 +14,7 @@ type ProductLineItem = {
|
||||
};
|
||||
|
||||
export type MessageItem = {
|
||||
checkTypeList: string[];
|
||||
checkType: string[];
|
||||
dayStatistic?: ProductLineItem[];
|
||||
weekStatistic?: ProductLineItem[];
|
||||
monthStatistic?: ProductLineItem[];
|
||||
|
@ -214,11 +214,15 @@ new XClient(
|
||||
} catch (error) {
|
||||
console.log("[*] websocket: [unable to serialize] ---> ", msg);
|
||||
}
|
||||
|
||||
console.log("[ISRA DATA] ---> ", serializedData);
|
||||
|
||||
if (serializedData == null) return;
|
||||
|
||||
// 处理 checkTypeList
|
||||
store.dispatch({
|
||||
type: "isra/setCheckTypeList",
|
||||
payload: serializedData.checkTypeList,
|
||||
type: "isra/setCheckType",
|
||||
payload: serializedData.checkType,
|
||||
});
|
||||
// for (const checkType of serializedData.checkTypeList) {
|
||||
// store.dispatch({
|
||||
@ -251,3 +255,50 @@ new XClient(
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
type TableDataType = {
|
||||
name: "table";
|
||||
type: "cutting";
|
||||
data: any[];
|
||||
};
|
||||
type ChartDataType = {
|
||||
name: "chart";
|
||||
type: "cutting";
|
||||
nightPushData: any[];
|
||||
dayPushData: any[];
|
||||
allPushData: any[];
|
||||
dateType: "day" | "week" | "month" | "year";
|
||||
};
|
||||
// 良品率相关数据
|
||||
new XClient(
|
||||
// "ws://10.70.27.122:8080/websocket/message?userId=CUTTING",
|
||||
"ws://10.70.2.2:8080/websocket/message?userId=CUTTING",
|
||||
"CUTTING_DATA",
|
||||
(msg) => {
|
||||
let serializedData: TableDataType | ChartDataType | null = null;
|
||||
try {
|
||||
serializedData = JSON.parse(msg.data);
|
||||
} catch (error) {
|
||||
console.log("[*] websocket: [unable to serialize] ---> ", msg);
|
||||
}
|
||||
|
||||
console.log("[CUTTING DATA] ---> ", serializedData);
|
||||
|
||||
if (serializedData == null) return;
|
||||
|
||||
switch (serializedData.name) {
|
||||
case "table":
|
||||
store.dispatch({
|
||||
type: "cutting/setCuttingTable",
|
||||
payload: serializedData.data,
|
||||
});
|
||||
break;
|
||||
case "chart":
|
||||
store.dispatch({
|
||||
type: "cutting/setCuttingChart",
|
||||
payload: serializedData,
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
Notiek ielāde…
Atsaukties uz šo jaunā problēmā
Block a user