Add VideoDataChart
This commit is contained in:
parent
0a08cf05b9
commit
ccd01ab604
|
@ -13,7 +13,7 @@
|
||||||
"copy-to-clipboard": "^3.3.1",
|
"copy-to-clipboard": "^3.3.1",
|
||||||
"craco-less": "2.0.0",
|
"craco-less": "2.0.0",
|
||||||
"d3-force": "^3.0.0",
|
"d3-force": "^3.0.0",
|
||||||
"echarts": "^5.4.0",
|
"echarts": "^5.4.2",
|
||||||
"echarts-for-react": "^3.0.2",
|
"echarts-for-react": "^3.0.2",
|
||||||
"file-saver": "^2.0.2",
|
"file-saver": "^2.0.2",
|
||||||
"i18next": "^19.8.9",
|
"i18next": "^19.8.9",
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
import React, { Component } from "react";
|
||||||
|
import ReactEcharts from 'echarts-for-react';
|
||||||
|
|
||||||
|
class VideoDataChart extends Component {
|
||||||
|
drawPic(data, nowTime) {
|
||||||
|
const xAxisData = data.map(item => Number(item.time));
|
||||||
|
const seriesData = data.map(item => ({
|
||||||
|
value: Number(item.data),
|
||||||
|
error: Number(item.confidence)
|
||||||
|
}));
|
||||||
|
|
||||||
|
let dataMax = -Infinity;
|
||||||
|
let dataMin = Infinity;
|
||||||
|
for (let i = 0; i < seriesData.length; i++) {
|
||||||
|
const value = seriesData[i].value;
|
||||||
|
|
||||||
|
if (value > dataMax) {
|
||||||
|
dataMax = value;
|
||||||
|
}
|
||||||
|
if (value < dataMin) {
|
||||||
|
dataMin = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const option = {
|
||||||
|
grid: {
|
||||||
|
top: '5%',
|
||||||
|
left: '3%',
|
||||||
|
right: '4%',
|
||||||
|
bottom: '8%',
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: xAxisData
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
min: dataMin,
|
||||||
|
max: dataMax
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: 'Data',
|
||||||
|
type: 'line',
|
||||||
|
data: seriesData
|
||||||
|
}
|
||||||
|
],
|
||||||
|
markLine: {
|
||||||
|
symbol: 'none',
|
||||||
|
lineStyle: {
|
||||||
|
color: 'red'
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
xAxis: nowTime,
|
||||||
|
yAxis: dataMin,
|
||||||
|
symbol: 'none',
|
||||||
|
lineStyle: {
|
||||||
|
color: 'red'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xAxis: nowTime,
|
||||||
|
yAxis: dataMax,
|
||||||
|
symbol: 'none',
|
||||||
|
lineStyle: {
|
||||||
|
color: 'red'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ReactEcharts
|
||||||
|
option={option}
|
||||||
|
style={{ height: '200px' }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const nowTime = 285;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{this.drawPic(this.props.data, nowTime)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default VideoDataChart;
|
|
@ -7,6 +7,7 @@ import {LinkOutlined} from "@ant-design/icons";
|
||||||
import Video from "./Video";
|
import Video from "./Video";
|
||||||
import LabelTable from "./LabelTable";
|
import LabelTable from "./LabelTable";
|
||||||
import * as Papa from "papaparse";
|
import * as Papa from "papaparse";
|
||||||
|
import VideoDataChart from "./VideoDataChart";
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
|
@ -20,6 +21,7 @@ class VideoEditPage extends React.Component {
|
||||||
player: null,
|
player: null,
|
||||||
screen: null,
|
screen: null,
|
||||||
videoObj: null,
|
videoObj: null,
|
||||||
|
videoData: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.labelTable = React.createRef();
|
this.labelTable = React.createRef();
|
||||||
|
@ -38,7 +40,7 @@ class VideoEditPage extends React.Component {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (video.dataUrl !== "") {
|
if (video.dataUrl !== "") {
|
||||||
this.parseCsv(video.dataUrl);
|
this.getDataAndParse(video.dataUrl);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -89,34 +91,34 @@ class VideoEditPage extends React.Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Affix offsetTop={100}>
|
<div style={{marginTop: "10px"}}>
|
||||||
<div style={{marginTop: "10px"}}>
|
<div className="screen" style={{position: "absolute", zIndex: 100, pointerEvents: "none", width: '440px', height: '472px', marginLeft: '200px', marginRight: '200px', backgroundColor: "rgba(255,0,0,0)" }}></div>
|
||||||
<div className="screen" style={{position: "absolute", zIndex: 100, pointerEvents: "none", width: '440px', height: '472px', marginLeft: '200px', marginRight: '200px', backgroundColor: "rgba(255,0,0,0)" }}></div>
|
<Video task={task} labels={this.state.video.labels}
|
||||||
<Video task={task} labels={this.state.video.labels}
|
onUpdateTime={(time) => {this.setState({currentTime: time})}}
|
||||||
onUpdateTime={(time) => {this.setState({currentTime: time})}}
|
onCreatePlayer={(player) => {this.setState({player: player})}}
|
||||||
onCreatePlayer={(player) => {this.setState({player: player})}}
|
onCreateScreen={(screen) => {this.setState({screen: screen})}}
|
||||||
onCreateScreen={(screen) => {this.setState({screen: screen})}}
|
onCreateVideo={(videoObj) => {this.setState({videoObj: videoObj})}}
|
||||||
onCreateVideo={(videoObj) => {this.setState({videoObj: videoObj})}}
|
onPause={() => {this.onPause()}}
|
||||||
onPause={() => {this.onPause()}}
|
/>
|
||||||
/>
|
<div style={{fontSize: 16, marginTop: "10px"}}>
|
||||||
<div style={{fontSize: 16, marginTop: "10px"}}>
|
{i18next.t("video:Current time (second)")}: {" "}
|
||||||
{i18next.t("video:Current time (second)")}: {" "}
|
{
|
||||||
{
|
this.state.currentTime
|
||||||
this.state.currentTime
|
}
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</Affix>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
parseCsv(dataUrl) {
|
getDataAndParse(dataUrl) {
|
||||||
fetch(dataUrl, {
|
fetch(dataUrl, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
}).then(res => res.text())
|
}).then(res => res.text())
|
||||||
.then(res => {
|
.then(res => {
|
||||||
const results = Papa.parse(res, { header: true });
|
const result = Papa.parse(res, { header: true });
|
||||||
console.log(results);
|
this.setState({
|
||||||
|
videoData: result.data,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,24 +202,33 @@ class VideoEditPage extends React.Component {
|
||||||
{i18next.t("video:Video")}:
|
{i18next.t("video:Video")}:
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={11} style={(Setting.isMobile()) ? {maxWidth: "100%"} : {}}>
|
<Col span={11} style={(Setting.isMobile()) ? {maxWidth: "100%"} : {}}>
|
||||||
{
|
<React.Fragment>
|
||||||
this.state.video !== null ? this.renderVideoContent() : null
|
<Affix offsetTop={50}>
|
||||||
}
|
{
|
||||||
<Row style={{marginTop: '20px'}} >
|
this.state.video !== null ? this.renderVideoContent() : null
|
||||||
<Col style={{marginTop: '5px'}} span={(Setting.isMobile()) ? 22 : 2}>
|
}
|
||||||
{i18next.t("general:Data")}:
|
<Row style={{marginTop: '20px'}} >
|
||||||
</Col>
|
<Col style={{marginTop: '5px'}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
<Col span={22} >
|
{i18next.t("general:Data")}:
|
||||||
<Select virtual={false} style={{width: '100%'}} value={this.state.video.dataUrl} onChange={(value => {
|
</Col>
|
||||||
this.parseCsv(value);
|
<Col span={22} >
|
||||||
this.updateVideoField('dataUrl', value);
|
<Select virtual={false} style={{width: '100%'}} value={this.state.video.dataUrl} onChange={(value => {
|
||||||
})}>
|
this.getDataAndParse(value);
|
||||||
{
|
this.updateVideoField('dataUrl', value);
|
||||||
this.state.video.dataUrls?.map((dataUrl, index) => <Option key={index} value={dataUrl}>{dataUrl.split("/").pop()}</Option>)
|
})}>
|
||||||
}
|
{
|
||||||
</Select>
|
this.state.video.dataUrls?.map((dataUrl, index) => <Option key={index} value={dataUrl}>{dataUrl.split("/").pop()}</Option>)
|
||||||
</Col>
|
}
|
||||||
</Row>
|
</Select>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
{
|
||||||
|
this.state.videoData === null ? null : (
|
||||||
|
<VideoDataChart data={this.state.videoData} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</Affix>
|
||||||
|
</React.Fragment>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={1}>
|
<Col span={1}>
|
||||||
</Col>
|
</Col>
|
||||||
|
|
|
@ -4219,19 +4219,19 @@ duplexer@^0.1.2:
|
||||||
|
|
||||||
echarts-for-react@^3.0.2:
|
echarts-for-react@^3.0.2:
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/echarts-for-react/-/echarts-for-react-3.0.2.tgz#ac5859157048a1066d4553e34b328abb24f2b7c1"
|
resolved "https://registry.npmjs.org/echarts-for-react/-/echarts-for-react-3.0.2.tgz#ac5859157048a1066d4553e34b328abb24f2b7c1"
|
||||||
integrity sha512-DRwIiTzx8JfwPOVgGttDytBqdp5VzCSyMRIxubgU/g2n9y3VLUmF2FK7Icmg/sNVkv4+rktmrLN9w22U2yy3fA==
|
integrity sha512-DRwIiTzx8JfwPOVgGttDytBqdp5VzCSyMRIxubgU/g2n9y3VLUmF2FK7Icmg/sNVkv4+rktmrLN9w22U2yy3fA==
|
||||||
dependencies:
|
dependencies:
|
||||||
fast-deep-equal "^3.1.3"
|
fast-deep-equal "^3.1.3"
|
||||||
size-sensor "^1.0.1"
|
size-sensor "^1.0.1"
|
||||||
|
|
||||||
echarts@^5.4.0:
|
echarts@^5.4.2:
|
||||||
version "5.4.0"
|
version "5.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/echarts/-/echarts-5.4.0.tgz#a9a8e5367293a397408d3bf3e2638b869249ce04"
|
resolved "https://registry.npmjs.org/echarts/-/echarts-5.4.2.tgz#9f38781c9c6ae323e896956178f6956952c77a48"
|
||||||
integrity sha512-uPsO9VRUIKAdFOoH3B0aNg7NRVdN7aM39/OjovjO9MwmWsAkfGyeXJhK+dbRi51iDrQWliXV60/XwLA7kg3z0w==
|
integrity sha512-2W3vw3oI2tWJdyAz+b8DuWS0nfXtSDqlDmqgin/lfzbkB01cuMEN66KWBlmur3YMp5nEDEEt5s23pllnAzB4EA==
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib "2.3.0"
|
tslib "2.3.0"
|
||||||
zrender "5.4.0"
|
zrender "5.4.3"
|
||||||
|
|
||||||
ee-first@1.1.1:
|
ee-first@1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
|
@ -10614,9 +10614,9 @@ yocto-queue@^0.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
|
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
|
||||||
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
|
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
|
||||||
|
|
||||||
zrender@5.4.0:
|
zrender@5.4.3:
|
||||||
version "5.4.0"
|
version "5.4.3"
|
||||||
resolved "https://registry.yarnpkg.com/zrender/-/zrender-5.4.0.tgz#d4f76e527b2e3bbd7add2bdaf27a16af85785576"
|
resolved "https://registry.npmjs.org/zrender/-/zrender-5.4.3.tgz#41ffaf835f3a3210224abd9d6964b48ff01e79f5"
|
||||||
integrity sha512-rOS09Z2HSVGFs2dn/TuYk5BlCaZcVe8UDLLjj1ySYF828LATKKdxuakSZMvrDz54yiKPDYVfjdKqcX8Jky3BIA==
|
integrity sha512-DRUM4ZLnoaT0PBVvGBDO9oWIDBKFdAVieNWxWwK0niYzJCMwGchRk21/hsE+RKkIveH3XHCyvXcJDkgLVvfizQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib "2.3.0"
|
tslib "2.3.0"
|
||||||
|
|
Loading…
Reference in New Issue