Add VideoDataChart
This commit is contained in:
parent
0a08cf05b9
commit
ccd01ab604
|
@ -13,7 +13,7 @@
|
|||
"copy-to-clipboard": "^3.3.1",
|
||||
"craco-less": "2.0.0",
|
||||
"d3-force": "^3.0.0",
|
||||
"echarts": "^5.4.0",
|
||||
"echarts": "^5.4.2",
|
||||
"echarts-for-react": "^3.0.2",
|
||||
"file-saver": "^2.0.2",
|
||||
"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 LabelTable from "./LabelTable";
|
||||
import * as Papa from "papaparse";
|
||||
import VideoDataChart from "./VideoDataChart";
|
||||
|
||||
const { Option } = Select;
|
||||
|
||||
|
@ -20,6 +21,7 @@ class VideoEditPage extends React.Component {
|
|||
player: null,
|
||||
screen: null,
|
||||
videoObj: null,
|
||||
videoData: null,
|
||||
};
|
||||
|
||||
this.labelTable = React.createRef();
|
||||
|
@ -38,7 +40,7 @@ class VideoEditPage extends React.Component {
|
|||
});
|
||||
|
||||
if (video.dataUrl !== "") {
|
||||
this.parseCsv(video.dataUrl);
|
||||
this.getDataAndParse(video.dataUrl);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -89,34 +91,34 @@ class VideoEditPage extends React.Component {
|
|||
};
|
||||
|
||||
return (
|
||||
<Affix offsetTop={100}>
|
||||
<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>
|
||||
<Video task={task} labels={this.state.video.labels}
|
||||
onUpdateTime={(time) => {this.setState({currentTime: time})}}
|
||||
onCreatePlayer={(player) => {this.setState({player: player})}}
|
||||
onCreateScreen={(screen) => {this.setState({screen: screen})}}
|
||||
onCreateVideo={(videoObj) => {this.setState({videoObj: videoObj})}}
|
||||
onPause={() => {this.onPause()}}
|
||||
/>
|
||||
<div style={{fontSize: 16, marginTop: "10px"}}>
|
||||
{i18next.t("video:Current time (second)")}: {" "}
|
||||
{
|
||||
this.state.currentTime
|
||||
}
|
||||
</div>
|
||||
<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>
|
||||
<Video task={task} labels={this.state.video.labels}
|
||||
onUpdateTime={(time) => {this.setState({currentTime: time})}}
|
||||
onCreatePlayer={(player) => {this.setState({player: player})}}
|
||||
onCreateScreen={(screen) => {this.setState({screen: screen})}}
|
||||
onCreateVideo={(videoObj) => {this.setState({videoObj: videoObj})}}
|
||||
onPause={() => {this.onPause()}}
|
||||
/>
|
||||
<div style={{fontSize: 16, marginTop: "10px"}}>
|
||||
{i18next.t("video:Current time (second)")}: {" "}
|
||||
{
|
||||
this.state.currentTime
|
||||
}
|
||||
</div>
|
||||
</Affix>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
parseCsv(dataUrl) {
|
||||
getDataAndParse(dataUrl) {
|
||||
fetch(dataUrl, {
|
||||
method: "GET",
|
||||
}).then(res => res.text())
|
||||
.then(res => {
|
||||
const results = Papa.parse(res, { header: true });
|
||||
console.log(results);
|
||||
const result = Papa.parse(res, { header: true });
|
||||
this.setState({
|
||||
videoData: result.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -200,24 +202,33 @@ class VideoEditPage extends React.Component {
|
|||
{i18next.t("video:Video")}:
|
||||
</Col>
|
||||
<Col span={11} style={(Setting.isMobile()) ? {maxWidth: "100%"} : {}}>
|
||||
{
|
||||
this.state.video !== null ? this.renderVideoContent() : null
|
||||
}
|
||||
<Row style={{marginTop: '20px'}} >
|
||||
<Col style={{marginTop: '5px'}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{i18next.t("general:Data")}:
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select virtual={false} style={{width: '100%'}} value={this.state.video.dataUrl} onChange={(value => {
|
||||
this.parseCsv(value);
|
||||
this.updateVideoField('dataUrl', value);
|
||||
})}>
|
||||
{
|
||||
this.state.video.dataUrls?.map((dataUrl, index) => <Option key={index} value={dataUrl}>{dataUrl.split("/").pop()}</Option>)
|
||||
}
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
<React.Fragment>
|
||||
<Affix offsetTop={50}>
|
||||
{
|
||||
this.state.video !== null ? this.renderVideoContent() : null
|
||||
}
|
||||
<Row style={{marginTop: '20px'}} >
|
||||
<Col style={{marginTop: '5px'}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{i18next.t("general:Data")}:
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<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>
|
||||
</Col>
|
||||
</Row>
|
||||
{
|
||||
this.state.videoData === null ? null : (
|
||||
<VideoDataChart data={this.state.videoData} />
|
||||
)
|
||||
}
|
||||
</Affix>
|
||||
</React.Fragment>
|
||||
</Col>
|
||||
<Col span={1}>
|
||||
</Col>
|
||||
|
|
|
@ -4219,19 +4219,19 @@ duplexer@^0.1.2:
|
|||
|
||||
echarts-for-react@^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==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.3"
|
||||
size-sensor "^1.0.1"
|
||||
|
||||
echarts@^5.4.0:
|
||||
version "5.4.0"
|
||||
resolved "https://registry.yarnpkg.com/echarts/-/echarts-5.4.0.tgz#a9a8e5367293a397408d3bf3e2638b869249ce04"
|
||||
integrity sha512-uPsO9VRUIKAdFOoH3B0aNg7NRVdN7aM39/OjovjO9MwmWsAkfGyeXJhK+dbRi51iDrQWliXV60/XwLA7kg3z0w==
|
||||
echarts@^5.4.2:
|
||||
version "5.4.2"
|
||||
resolved "https://registry.npmjs.org/echarts/-/echarts-5.4.2.tgz#9f38781c9c6ae323e896956178f6956952c77a48"
|
||||
integrity sha512-2W3vw3oI2tWJdyAz+b8DuWS0nfXtSDqlDmqgin/lfzbkB01cuMEN66KWBlmur3YMp5nEDEEt5s23pllnAzB4EA==
|
||||
dependencies:
|
||||
tslib "2.3.0"
|
||||
zrender "5.4.0"
|
||||
zrender "5.4.3"
|
||||
|
||||
ee-first@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"
|
||||
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
|
||||
|
||||
zrender@5.4.0:
|
||||
version "5.4.0"
|
||||
resolved "https://registry.yarnpkg.com/zrender/-/zrender-5.4.0.tgz#d4f76e527b2e3bbd7add2bdaf27a16af85785576"
|
||||
integrity sha512-rOS09Z2HSVGFs2dn/TuYk5BlCaZcVe8UDLLjj1ySYF828LATKKdxuakSZMvrDz54yiKPDYVfjdKqcX8Jky3BIA==
|
||||
zrender@5.4.3:
|
||||
version "5.4.3"
|
||||
resolved "https://registry.npmjs.org/zrender/-/zrender-5.4.3.tgz#41ffaf835f3a3210224abd9d6964b48ff01e79f5"
|
||||
integrity sha512-DRUM4ZLnoaT0PBVvGBDO9oWIDBKFdAVieNWxWwK0niYzJCMwGchRk21/hsE+RKkIveH3XHCyvXcJDkgLVvfizQ==
|
||||
dependencies:
|
||||
tslib "2.3.0"
|
||||
|
|
Loading…
Reference in New Issue