TODO: 解决x轴 提示 不显示分妙

This commit is contained in:
eson 2020-12-02 19:10:04 +08:00
parent 7460c41a6f
commit d412715642
6 changed files with 207 additions and 133 deletions

2
.gitignore vendored
View File

@ -15,4 +15,4 @@ build
npm-debug.log
# screen
sceeenlog.*
screenlog.*

View File

@ -11,18 +11,20 @@ import {
Typography,
Space,
Divider,
ConfigProvider,
} from 'antd';
import './App.less';
import Home from './Home';
import HomeRouter from './Router';
const { Option } = Select;
const { Title } = Typography;
import zh_CN from 'antd/lib/locale-provider/zh_CN';
import 'moment/locale/zh-cn';
const App = () => (
<>
<ConfigProvider locale={zh_CN}>
<HomeRouter></HomeRouter>
</>
</ConfigProvider>
);
export default App;

8
src/Config.js Normal file
View File

@ -0,0 +1,8 @@
var config = {
trendurl : "http://localhost:6123/api/data"
}
export default config;

View File

@ -9,7 +9,7 @@ import {
UploadOutlined,
} from '@ant-design/icons';
import { HashRouter, Link, Route, Switch } from 'react-router-dom';
import Trend from './charts/Trend';
const { Header, Sider, Content } = Layout;
@ -26,62 +26,59 @@ class Home extends React.Component {
};
render() {
console.log(window.location.hash);
console.log(window.location.hash);
return (
<Layout style={{background: "#cccccc"}} >
<Sider trigger={null} collapsible collapsed={this.state.collapsed}>
<Layout style={{ background: "#e7e7e7", minHeight: '90vh' }} >
<Sider trigger={null} collapsible collapsed={this.state.collapsed}>
<div className="logo" />
<Button type="primary" onClick={this.toggle} style={{ background: '#333333', width: "100%", colorRendering: "optimizeSpeed" }}>
{React.createElement(this.state.collapsed ? MenuUnfoldOutlined : MenuFoldOutlined)}
</Button>
<Menu theme="dark" mode="inline" defaultSelectedKeys={[window.location.hash ? window.location.hash: "1"]}>
<Menu.Item key="1" icon={<UserOutlined />}>
nav 1
<Menu theme="dark" mode="inline" defaultSelectedKeys={[window.location.hash ? window.location.hash : "1"]}>
<Menu.Item key="1" icon={<UserOutlined />}>
nav 1
<HashRouter>
<Link to="/"></Link>
</HashRouter>
</Menu.Item>
<Menu.Item key="#/playerduo" icon={<VideoCameraOutlined />}>
nav 2
<Link to="/"></Link>
</HashRouter>
</Menu.Item>
<Menu.Item key="#/playerduo" icon={<VideoCameraOutlined />}>
playerduo
<HashRouter>
<Link to={{pathname: "/playerduo"}}></Link>
</HashRouter>
<Link to={{ pathname: "/playerduo" }}></Link>
</HashRouter>
</Menu.Item>
<Menu.Item key="3" icon={<UploadOutlined />}>
nav 3
</Menu.Item>
<Menu.Item key="3" icon={<UploadOutlined />}>
nav 3
</Menu.Item>
</Menu>
</Sider>
<Layout >
<Header style={{ background: "#CCCCCC", margin: "2px 2px", padding: 0 }}>
<Layout >
<Header style={{ background: "#e7e7e7", height: "42px" }}>
</Header>
<Content
style={{
background: "#CCCCCC",
margin: '2px 2px',
padding: 24,
minHeight: '90vh',
background: "#e7e7e7",
marginTop: "2px",
minHeight: '80vh',
}}
>
<HashRouter>
<Switch>
<Route exact path="/playerduo" component={Trend}/>
</Switch>
<Switch>
<Route exact path="/playerduo" component={Trend} />
</Switch>
</HashRouter>
</Content>
</Layout>
</Layout>
);
}
}

34
src/charts/Base.js Normal file
View File

@ -0,0 +1,34 @@
function dateFormat(fmt, date) {
let ret;
const opt = {
"Y+": date.getFullYear().toString(), // 年
"m+": (date.getMonth() + 1).toString(), // 月
"d+": date.getDate().toString(), // 日
"H+": date.getHours().toString(), // 时
"M+": date.getMinutes().toString(), // 分
"S+": date.getSeconds().toString() // 秒
// 有其他格式化字符需求可以继续添加,必须转化成字符串
};
for (let k in opt) {
ret = new RegExp("(" + k + ")").exec(fmt);
if (ret) {
fmt = fmt.replace(ret[1], (ret[1].length === 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
};
};
return fmt;
}
function defaultDateFormat(date) {
return dateFormat("YYYY-mm-dd", date)
}
// var colors = [ "#0000FF", "#8A2BE2", "#A52A2A", "#DEB887", "#5F9EA0", "#7FFF00", "#D2691E", "#FF7F50", "#6495ED", "#FFF8DC", "#DC143C", "#00FFFF", "#00008B", "#008B8B", "#B8860B", "#A9A9A9", "#006400", "#BDB76B", "#8B008B", "#556B2F", "#FF8C00", "#9932CC", "#8B0000", "#E9967A", "#8FBC8F", "#483D8B", "#2F4F4F", "#00CED1", "#9400D3", "#FF1493", "#00BFFF", "#696969", "#1E90FF", "#B22222", "#FFFAF0", "#228B22", "#FF00FF", "#DCDCDC", "#F8F8FF", "#FFD700", "#DAA520", "#808080", "#008000", "#ADFF2F", "#F0FFF0", "#FF69B4", "#CD5C5C", "#4B0082", "#FFFFF0"]
const TrendType = {
OneDate: 1,
RangeDate: 2,
}
export {TrendType, dateFormat, defaultDateFormat};

View File

@ -2,41 +2,47 @@
import ReactEcharts from 'echarts-for-react';
import echarts from 'echarts';
import React from 'react';
import { Button, DatePicker, Row } from 'antd';
import zhCN from 'antd/es/locale/zh_CN'; // 引入中文包
import {dateFormat, defaultDateFormat, TrendType} from './Base.js';
import config from '../Config.js';
const { RangePicker } = DatePicker;
class Trend extends React.Component {
state = {
data: [],
type: {
current: TrendType.OneDate,
constructor(props) {
super(props);
this.state = {
data: []
};
}
}
};
componentDidMount() {
fetch('http://localhost:6123/api/data').then(function (response) {
console.log(response);
if (response.ok) {
response.json().then(function (response) {
console.log(response)
this.setState({ data: response.data.trends })
})
}
}
)
var now = new Date()
this.selectDate( defaultDateFormat(now) )
}
getOption(data) {
getOption(trendtype, data) {
var interval;
var fm ;
if(trendtype.current === TrendType.OneDate) {
interval = 3600 * 1000;
fm = function (value, index) {
var tp = new Date(value)
return tp.getFullYear() + "-" + (tp.getMonth() + 1) + "-" + tp.getDate() + " " + tp.getHours()
};
} else {
interval = 3600 * 1000 * 24;
fm = function (value, index) {
var tp = new Date(value)
return tp.getFullYear() + "-" + (tp.getMonth() + 1) + "-" + tp.getDate()
};
}
var option = {
tooltip: {
@ -50,24 +56,48 @@ class Trend extends React.Component {
left: 'center',
text: '趋势数据',
},
toolbox: {
feature: {
dataZoom: {
yAxisIndex: 'none'
},
restore: {},
saveAsImage: {}
}
legend: {
left: 'right',
data: [],
},
// toolbox: {
// feature: {
// dataZoom: {
// yAxisIndex: 'none'
// },
// restore: {},
// saveAsImage: {}
// }
// },
xAxis: {
type: 'time',
boundaryGap: false,
// interval: 10,
interval: interval,
// data: tsdata
axisLabel: {
formatter: fm,
},
},
aria: {
show: true
},
yAxis: {
type: 'value',
boundaryGap: [0, '100%']
// boundaryGap: [0, '100%']
axisLabel: {
formatter: function (value, index) {
if( typeof value == "number") {
if(value >= 100000000) {
return (value / 10000).toFixed(4) + "亿"
} else if(value >= 10000) {
return (value / 10000).toFixed(2) + "万"
} else {
return value
}
}
}
}
},
dataZoom: [{
type: 'inside',
@ -77,60 +107,41 @@ class Trend extends React.Component {
start: 0,
end: 100,
handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
handleSize: '80%',
handleSize: '100%',
handleStyle: {
color: '#fff',
shadowBlur: 3,
shadowColor: 'rgba(0, 0, 0, 0.6)',
shadowColor: 'rgba(0, 0, 0, 0.8)',
shadowOffsetX: 2,
shadowOffsetY: 2
}
}],
series: [
// {
// name: '模拟数据2',
// type: 'line',
// smooth: true,
// symbol: 'none',
// sampling: 'average',
// itemStyle: {
// color: 'rgb(164, 158, 131)'
// },
// areaStyle: {
// color: new echarts.graphic.LinearGradient(1, 1, 0, 1, [{
// offset: 0,
// color: 'rgb(164, 158, 158)'
// }, {
// offset: 1,
// color: 'rgb(164, 158, 131)'
// }])
// },
// data: data2
// }
]
};
for (var d of data) {
for (var i = 0; i < data.length; i++) {
var d = data[i];
// var color = colors[i];
var tvalues = []
for (var value of d.values) {
tvalues.push([value.time_point * 1000, value.value])
}
tvalues.sort()
option.legend.data.push(d.name);
var sdata = {
name: d.name,
type: 'line',
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: {
color: 'rgb(64, 158, 131)'
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgb(64, 158, 158)'
}, {
offset: 1,
color: 'rgb(64, 158, 131)'
}])
},
data: d.values
data: tvalues
}
option.series.push(sdata)
}
@ -138,35 +149,57 @@ class Trend extends React.Component {
return option;
}
selectDate(date) {
fetch(`${config.trendurl}?date=${date}`).then((response) => {
if (response.ok) {
response.json().then((response) => {
if (response.code === 0) {
this.setState({ data: response.data.trends, type: {current: TrendType.OneDate} })
}
})
}
});
}
selectRangeDate(start, end) {
fetch(`${config.trendurl}?start=${start}&end=${end}`).then((response) => {
if (response.ok) {
response.json().then((response) => {
if (response.code === 0) {
this.setState({ data: response.data.trends, type: {current: TrendType.RangeDate }})
}
})
}
});
}
render() {
const { data } = this.state;
// console.log("123");
// var data1 = [];
// var now = new Date();
// data1.push([new Date(now.getTime() + 3600 * 1000), 100])
// data1.push([new Date(now.getTime() + 3600 * 2000), 120])
// data1.push([new Date(now.getTime() + 3600 * 3000), 140])
// var data2 = [];
// data2.push([new Date(now.getTime() + 3600 * 1000), 110])
// data2.push([new Date(now.getTime() + 3600 * 2000), 130])
// data2.push([new Date(now.getTime() + 3600 * 3000), 150])
const { data, type } = this.state;
return (
<div style={{height: "100%"}}>
<Row style={{marginLeft: "6%", marginBottom: "10px"}}>
<Button onClick={ () => this.selectDate(defaultDateFormat(new Date()))} >今天</Button>
<Button onClick={ () => {
var now = new Date();
var end = defaultDateFormat(now)
now -= 3600 * 24 * 1000 * 7
var start = defaultDateFormat(new Date(now))
this.selectRangeDate(start, end);
} }>7</Button>
<Button >30</Button>
<RangePicker size="small" style={{marginLeft: "5px"}} />
<DatePicker size="small" style={{marginLeft: "5px"}} />
</Row>
<ReactEcharts
notMerge={true}
lazyUpdate={true}
option={this.getOption(data)}
style={{ width: "100%", height: "100%" }}
option={this.getOption(type, data)}
style={{ width: "100%", minHeight: "90vh" }}
/>
</ div>
)
}