ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等),底层依赖矢量图形库 ZRender,提供直观,交互丰富,可高度个性化定制的数据可视化图表。ECharts 提供了常规的折线图、柱状图、散点图、饼图、K线图,用于统计的盒形图,用于地理数据可视化的地图、热力图、线图,用于关系数据可视化的关系图、treemap、旭日图,多维数据可视化的平行坐标,还有用于 BI 的漏斗图,仪表盘,并且支持图与图之间的混搭。
官方实例:https://www.echartsjs.com/examples/zh/index.html
需要的包命令为如下↓
yarn add echarts 或者 npm echarts
yarn add echarts-for-react 或者 npm echarts-for-react
选择官方,柱状图下的坐标轴刻度与标签对齐插件。
xAxis 下的 data为 x轴数据
series 下的 data为 对应的参数
俩个data我们只需要替换下面的数据即可
import React, { Component } from 'react';
import { connect } from 'dva';
import config from '../../../public/config';
import { Card, Table } from 'antd';
import moment from "moment";
import ReactEcharts from 'echarts-for-react';
import styles from './AntdOverride.less';
import OrderTable from './OrderTable';
/**
* 首页统计图表
* @author 于公成
*
*/
class IndexPageTable extends Component {
constructor() {
super();
let companyList = [];
let userVolumeList= [];
let option={}
let orderDateList=[];
let orderVolumeList=[];
let option2={}
this.state= {
companyList,
userVolumeList,
option,
orderDateList,
orderVolumeList,
option2
}
}
componentWillMount(){
}
componentDidMount() {
//部门用户量
let companyList = this.state.companyList;
let userVolumeList = this.state.userVolumeList;
let flag = this;
this.props.dispatch(
{
type: "query/querySecret",
payload: {
url: config.dataUrl + "/deptinfo/queryAllDeptUserVolume"
},
callback: (result) => {
console.log(result)
if (result.code === 200 && result.data != null) {
result.data.map((item) => {
companyList.push(
item.company,
)
userVolumeList.push(
item.uservolume
)
})
let option = this.state.option = {
// color: ['#3398DB','#006699', '#4cabce', '#e5323e'],
tooltip: {
trigger: 'axis',
axisPointer: { // 坐标轴指示器,坐标轴触发有效
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
grid: {
left: '1%',
right: '3%',
bottom: '2%',
top:'2%',
containLabel: true
},
xAxis: [
{
type: 'category',
data: companyList,
axisTick: {
alignWithLabel: true,
},
axisLabel: {
interval: 0, //强制显示文字
formatter: (value, index) => {
// 10 6 这些你自定义就行
let v = value.substring(0, 6) + '...'
return value.length > 9 ? v : value
}
}
}
],
yAxis: [
{
type: 'value',
}
],
series: [
{
name: '用户量',
type: 'bar',
barWidth: '60%',
data: userVolumeList,
itemStyle: {
normal: {
//这里是重点
color: (params) => {
//注意,如果颜色太少的话,后面颜色不会自动循环,最好多定义几个颜色
let colorList = ['#c23531', '#2f4554', '#61a0a8', '#d48265', '#91c7ae', '#749f83', '#ca8622'];
return colorList[params.dataIndex]
}
}
}
},
],
triggerEvent: false // 设置为true后,可触发事件。实现x轴文字过长,显示省略号,hover上去显示全部的功能
};
this.setState({
companyList, userVolumeList, option
})
}
}
})
let orderDateList = this.state.orderDateList;
let orderVolumeList = this.state.orderVolumeList;
//订单用户量
this.props.dispatch(
{
type:"query/querySecret",
payload: {
url:config.dataUrl+ "insorder/queryOrderVolume",
},
callback:(result)=>{
console.log(result)
if (result.code === 200 && result.data != null) {
result.data.map((item) => {
orderDateList.push(
moment(item.orderdate).format('YYYY-MM-DD')
)
orderVolumeList.push(
item.ordervolume
)
})
let option2 = this.state.option2 = {
xAxis: {
type: 'category',
data: orderDateList
},
yAxis: {
type: 'value'
},
grid: {
left: '1%',
right: '4%',
bottom: '2%',
top:'2%',
containLabel: true
},
series: [{
data: orderVolumeList,
type: 'line'
}]
}
this.setState({
orderDateList, orderVolumeList, option2
})
console.log("orderDateList:"+orderDateList)
console.log("orderVolumeList:"+orderVolumeList)
}
}
}
)
}
render() {
//显隐控制
if(this.props.layout.status===0){
return (
{/**/}
{/* */}
)
}else{
return (
)
}
}
}
function mapStateToProps(state) {
return {
layout:state.layout,
verify:state.verify,
user:state.user
};
}
export default connect(mapStateToProps)(IndexPageTable);
实现结果
横向柱状图
import React, { Component } from 'react';
import { connect } from 'dva';
import config from '../../../public/config';
import { Card, Table } from 'antd';
import moment from "moment";
import ReactEcharts from 'echarts-for-react';
import styles from './AntdOverride.less';
import OrderTable from './OrderTable';
/**
* 首页统计图表
* @author 于公成
*
*/
class IndexPageTable extends Component {
constructor() {
super();
let companyList = [];
let userVolumeList= [];
let option={}
let orderDateList=[];
let orderVolumeList=[];
let option2={}
this.state= {
companyList,
userVolumeList,
option,
orderDateList,
orderVolumeList,
option2
}
}
componentWillMount(){
}
componentDidMount() {
//部门用户量
let companyList = this.state.companyList;
let userVolumeList = this.state.userVolumeList;
let flag = this;
//柱状图样式2
this.props.dispatch(
{
type: "query/querySecret",
payload: {
url: config.dataUrl + "/deptinfo/queryAllDeptUserVolume"
},
callback: (result) => {
console.log(result)
if (result.code === 200 && result.data != null) {
result.data.map((item) => {
companyList.push(
item.company,
)
userVolumeList.push(
item.uservolume
)
})
let option = this.state.option = {
// title: {
// text: '世界人口总量',
// subtext: '数据来自网络'
// },
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
// legend: {
// data: ['2011年', '2012年']
// },
grid: {
left: '1%',
right: '3%',
bottom: '2%',
top:'2%',
containLabel: true
},
xAxis: {
type: 'value',
boundaryGap: [0, 0.01]
},
yAxis: {
type: 'category',
data: companyList,
//Y轴斜
// axisLabel:{
// interval: 0 ,
// rotate:10
// }
},
series: [
{
type: 'bar',
data: userVolumeList,
itemStyle: {
normal: {
//这里是重点
color: (params) => {
//注意,如果颜色太少的话,后面颜色不会自动循环,最好多定义几个颜色
// let colorList = ['#c23531', '#2f4554', '#61a0a8', '#d48265', '#91c7ae', '#749f83', '#ca8622'];
// let colorList = ['#37a2da', '#32c5e9', '#67e0e3', '#9fe6b8', '#ffdb5c', '#ff9f7f', '#fb7293','#e062ae','#e690d1'];
let colorList = ['#e690d1', '#e062ae', '#fb7293', '#ff9f7f', '#ffdb5c', '#9fe6b8', '#67e0e3','#32c5e9','#37a2da'];
return colorList[params.dataIndex]
}
}
},
}
]
};
this.setState({
companyList, userVolumeList, option
})
}
}
})
//柱状图样式1
// this.props.dispatch(
// {
// type: "query/querySecret",
// payload: {
// url: config.dataUrl + "/deptinfo/queryAllDeptUserVolume"
// },
// callback: (result) => {
// console.log(result)
// if (result.code === 200 && result.data != null) {
// result.data.map((item) => {
// companyList.push(
// item.company,
// )
// userVolumeList.push(
// item.uservolume
// )
// })
// let option = this.state.option = {
// // color: ['#3398DB','#006699', '#4cabce', '#e5323e'],
// tooltip: {
// trigger: 'axis',
// axisPointer: { // 坐标轴指示器,坐标轴触发有效
// type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
// }
// },
// grid: {
// left: '1%',
// right: '3%',
// bottom: '2%',
// top:'2%',
// containLabel: true
// },
//
// xAxis: [
// {
// type: 'category',
// data: companyList,
// axisTick: {
// alignWithLabel: true,
//
// },
// axisLabel: {
// interval: 0, //强制显示文字
// formatter: (value, index) => {
// // 10 6 这些你自定义就行
// let v = value.substring(0, 6) + '...'
// return value.length > 9 ? v : value
// }
// }
// }
// ],
// yAxis: [
// {
// type: 'value',
// }
// ],
//
// series: [
// {
// name: '用户量',
// type: 'bar',
// barWidth: '60%',
// data: userVolumeList,
// itemStyle: {
// normal: {
// //这里是重点
// color: (params) => {
// //注意,如果颜色太少的话,后面颜色不会自动循环,最好多定义几个颜色
// let colorList = ['#c23531', '#2f4554', '#61a0a8', '#d48265', '#91c7ae', '#749f83', '#ca8622'];
// return colorList[params.dataIndex]
// }
// }
// }
// },
//
// ],
// triggerEvent: false // 设置为true后,可触发事件。实现x轴文字过长,显示省略号,hover上去显示全部的功能
// };
// this.setState({
// companyList, userVolumeList, option
// })
// }
// }
// })
let orderDateList = this.state.orderDateList;
let orderVolumeList = this.state.orderVolumeList;
//订单用户量
this.props.dispatch(
{
type:"query/querySecret",
payload: {
url:config.dataUrl+ "insorder/queryOrderVolume",
},
callback:(result)=>{
console.log(result)
if (result.code === 200 && result.data != null) {
result.data.map((item) => {
orderDateList.push(
moment(item.orderdate).format('YYYY-MM')
)
orderVolumeList.push(
item.ordervolume
)
})
let option2 = this.state.option2 = {
tooltip: {
trigger: 'axis',
},
xAxis: {
type: 'category',
data: orderDateList
},
yAxis: {
type: 'value'
},
grid: {
left: '1%',
right: '4%',
bottom: '2%',
top:'2%',
containLabel: true
},
series: [{
data: orderVolumeList,
type: 'line',
}]
}
this.setState({
orderDateList, orderVolumeList, option2
})
console.log("orderDateList:"+orderDateList)
console.log("orderVolumeList:"+orderVolumeList)
}
}
}
)
}
render() {
//显隐控制
if(this.props.layout.status===0){
return (
{/**/}
{/* */}
)
}else{
return (
)
}
}
}
function mapStateToProps(state) {
return {
layout:state.layout,
verify:state.verify,
user:state.user
};
}
export default connect(mapStateToProps)(IndexPageTable);
实现结果
新增饼状图
import React, { Component } from 'react';
import { connect } from 'dva';
import config from '../../../public/config';
import { Card, List, Table, Statistic, Row, Col } from 'antd';
import moment from "moment";
import ReactEcharts from 'echarts-for-react';
import styles from './AntdOverride.less';
import OrderTable from './OrderTable';
import { ArrowUpOutlined, ArrowDownOutlined } from '@ant-design/icons';
/**
* 首页统计图表
* @author 于公成
*
*/
class IndexPageTable extends Component {
constructor() {
super();
//用户量
let companyList = [];
let userVolumeList= [];
let option={}
//订单量
let orderDateList=[];
let orderVolumeList=[];
let option2={}
//用户部门一周访问量
let option3={}
let companyList2=[];
let weeks=[];
let weeksVolume=[];
//socket
let messageData;
this.state= {
companyList,
userVolumeList,
option,
orderDateList,
orderVolumeList,
option2,
companyList2,
weeksVolume,
weeks,
option3,
messageData
}
}
componentWillMount(){
}
componentDidMount() {
//部门用户量
let companyList = this.state.companyList;
let userVolumeList = this.state.userVolumeList;
let flag = this;
//柱状图样式2
this.props.dispatch(
{
type: "query/querySecret",
payload: {
url: config.dataUrl + "/deptinfo/queryAllDeptUserVolume"
},
callback: (result) => {
console.log(result)
if (result.code === 200 && result.data != null) {
result.data.map((item) => {
companyList.push(
item.company,
)
userVolumeList.push(
item.uservolume
)
})
let option = this.state.option = {
// title: {
// text: '世界人口总量',
// subtext: '数据来自网络'
// },
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
// legend: {
// data: ['2011年', '2012年']
// },
grid: {
left: '1%',
right: '3%',
bottom: '2%',
top:'2%',
containLabel: true
},
xAxis: {
type: 'value',
boundaryGap: [0, 0.01]
},
yAxis: {
type: 'category',
data: companyList,
//Y轴斜
// axisLabel:{
// interval: 0 ,
// rotate:10
// }
},
series: [
{
type: 'bar',
data: userVolumeList,
itemStyle: {
normal: {
//这里是重点
color: (params) => {
//注意,如果颜色太少的话,后面颜色不会自动循环,最好多定义几个颜色
// let colorList = ['#c23531', '#2f4554', '#61a0a8', '#d48265', '#91c7ae', '#749f83', '#ca8622'];
// let colorList = ['#37a2da', '#32c5e9', '#67e0e3', '#9fe6b8', '#ffdb5c', '#ff9f7f', '#fb7293','#e062ae','#e690d1'];
let colorList = ['#e690d1', '#e062ae', '#fb7293', '#ff9f7f', '#ffdb5c', '#9fe6b8', '#67e0e3','#32c5e9','#37a2da'];
return colorList[params.dataIndex]
}
}
},
}
]
};
this.setState({
companyList, userVolumeList, option
})
}
}
})
//柱状图样式1
// this.props.dispatch(
// {
// type: "query/querySecret",
// payload: {
// url: config.dataUrl + "/deptinfo/queryAllDeptUserVolume"
// },
// callback: (result) => {
// console.log(result)
// if (result.code === 200 && result.data != null) {
// result.data.map((item) => {
// companyList.push(
// item.company,
// )
// userVolumeList.push(
// item.uservolume
// )
// })
// let option = this.state.option = {
// // color: ['#3398DB','#006699', '#4cabce', '#e5323e'],
// tooltip: {
// trigger: 'axis',
// axisPointer: { // 坐标轴指示器,坐标轴触发有效
// type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
// }
// },
// grid: {
// left: '1%',
// right: '3%',
// bottom: '2%',
// top:'2%',
// containLabel: true
// },
//
// xAxis: [
// {
// type: 'category',
// data: companyList,
// axisTick: {
// alignWithLabel: true,
//
// },
// axisLabel: {
// interval: 0, //强制显示文字
// formatter: (value, index) => {
// // 10 6 这些你自定义就行
// let v = value.substring(0, 6) + '...'
// return value.length > 9 ? v : value
// }
// }
// }
// ],
// yAxis: [
// {
// type: 'value',
// }
// ],
//
// series: [
// {
// name: '用户量',
// type: 'bar',
// barWidth: '60%',
// data: userVolumeList,
// itemStyle: {
// normal: {
// //这里是重点
// color: (params) => {
// //注意,如果颜色太少的话,后面颜色不会自动循环,最好多定义几个颜色
// let colorList = ['#c23531', '#2f4554', '#61a0a8', '#d48265', '#91c7ae', '#749f83', '#ca8622'];
// return colorList[params.dataIndex]
// }
// }
// }
// },
//
// ],
// triggerEvent: false // 设置为true后,可触发事件。实现x轴文字过长,显示省略号,hover上去显示全部的功能
// };
// this.setState({
// companyList, userVolumeList, option
// })
// }
// }
// })
let orderDateList = this.state.orderDateList;
let orderVolumeList = this.state.orderVolumeList;
//订单用户量
this.props.dispatch(
{
type:"query/querySecret",
payload: {
url:config.dataUrl+ "insorder/queryOrderVolume",
},
callback:(result)=>{
console.log(result)
if (result.code === 200 && result.data != null) {
result.data.map((item) => {
orderDateList.push(
moment(item.orderdate).format('YYYY-MM')
)
orderVolumeList.push(
item.ordervolume
)
})
let option2 = this.state.option2 = {
tooltip: {
trigger: 'axis',
},
xAxis: {
type: 'category',
data: orderDateList
},
yAxis: {
type: 'value'
},
grid: {
left: '1%',
right: '4%',
bottom: '2%',
top:'2%',
containLabel: true
},
series: [{
data: orderVolumeList,
type: 'line',
}]
}
this.setState({
orderDateList, orderVolumeList, option2
})
console.log("orderDateList:"+orderDateList)
console.log("orderVolumeList:"+orderVolumeList)
}
}
}
)
//一周部门访问量
//部门用户量
let companyList2 = this.state.companyList2;
//饼状图样式
this.props.dispatch(
{
type: "query/querySecret",
payload: {
url: config.dataUrl + "/syslog/queryDeptWeekVolume"
},
callback: (result) => {
console.log(result)
if (result.code === 200 && result.data != null) {
result.data.map((item) => {
companyList2.push(
{
// name:item.company+"-"+item.weeks,
name:item.company,
value:item.uservolume
}
)
// companyList2.push(
// item.company+"-"+item.weeks,
// )
// weeksVolume.push(
// item.uservolume
// )
})
let option3 = this.state.option3 = {
title: {
text: '最近一周访问量',
// subtext: '纯属虚构',
left: 'center'
},
tooltip: {
trigger: 'item',
// formatter: '{a}
{b} : {c} ({d}%)'
formatter: '
{b} : {c} ({d}%)'
},
series: [
{
// name: '最近一周访问量',
type: 'pie',
radius: '55%',
center: ['50%', '55%'],
data: this.state.companyList2,
label: {
normal: {
position: 'inner',
show : false
}
},
itemStyle: {
normal: {
//这里是重点
color: (params) => {
//注意,如果颜色太少的话,后面颜色不会自动循环,最好多定义几个颜色
// let colorList = ['#c23531', '#2f4554', '#61a0a8', '#d48265', '#91c7ae', '#749f83', '#ca8622'];
let colorList = ['#37a2da', '#32c5e9', '#67e0e3', '#9fe6b8', '#ffdb5c', '#ff9f7f', '#fb7293','#e062ae','#e690d1'];
// let colorList = ['#e690d1', '#e062ae', '#fb7293', '#ff9f7f', '#ffdb5c', '#9fe6b8', '#67e0e3','#32c5e9','#37a2da'];
return colorList[params.dataIndex]
}
}
},
}
]
};
this.setState({
companyList2, option3
})
}
}
})
//webscoket
let ws = new WebSocket("ws://localhost:12935/20191108_V1.0_xdnx/websocket");
if (typeof (WebSocket) == "undefined") {
console.log("遗憾:您的浏览器不支持WebSocket");
} else {
console.log("恭喜:您的浏览器支持WebSocket");
ws.onopen = (evt)=> {
console.log("Connection open ...");
ws.send("管理平台");
ws.send("新增人数");
};
ws.onmessage = (evt)=> {
console.log( "Received Message: " + evt.data);
// alert(evt.data)
let messageData=this.state.messageData;
this.setState({
messageData:evt.data
})
// ws.close();
};
ws.onclose = (evt)=> {
// alert(evt.data)
console.log("Connection closed.");
// ws.close();
};
ws.onerror = (evt)=> {
console.log("error")
};
window.onbeforeunload = (event)=> {
console.log("关闭WebSocket连接!");
ws.send("关闭页面");
event.close();
}
}
}
render() {
//显隐控制
if(this.props.layout.status===0){
return (
//一周访问数,用户在线数量
{/**/}
{/* */}
,
)
}else{
return (
)
}
}
}
function mapStateToProps(state) {
return {
layout:state.layout,
verify:state.verify,
user:state.user
};
}
export default connect(mapStateToProps)(IndexPageTable);
实现结果