|
|
@ -7,7 +7,7 @@ import PerfectScrollbar from "perfect-scrollbar"; |
|
|
|
import repairFQA from '../../means/containers/repairFQA'; |
|
|
|
import { Setup, OutHidden } from "$components"; |
|
|
|
import ReactECharts from 'echarts-for-react'; |
|
|
|
const { Meta } = Card; |
|
|
|
import moment from "moment"; |
|
|
|
|
|
|
|
let newScrollbar; |
|
|
|
let overviewScrollbar; |
|
|
@ -21,21 +21,15 @@ let alarmScrollbar; |
|
|
|
const Control = (props) => { |
|
|
|
const { dispatch, actions, user, loading, socket, pepProjectId } = props |
|
|
|
const { control } = actions |
|
|
|
const stationList = [ |
|
|
|
'url(/assets/images/console/lan_1.png)', |
|
|
|
'url(/assets/images/console/lv_1.png)', |
|
|
|
'url(/assets/images/console/huang_1.png)', |
|
|
|
'url(/assets/images/console/hong_1.png)', |
|
|
|
] |
|
|
|
const [timelineList, setTimelineList] = useState(['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''])//最新动态列表 |
|
|
|
|
|
|
|
const [memberList, setMemberList] = useState(['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''])//相关成员列表 |
|
|
|
const [memberList, setMemberList] = useState([])//相关成员列表 |
|
|
|
|
|
|
|
const [equipmentList, setEquipmentList] = useState(['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''])//平台设备接入列表 |
|
|
|
|
|
|
|
const [webList, setWebList] = useState(['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''])//关联web应用列表 |
|
|
|
const [webList, setWebList] = useState([])//关联web应用列表 |
|
|
|
|
|
|
|
const [problemsList, setProblemsList] = useState(['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''])//异常&问题列表 |
|
|
|
const [problemsList, setProblemsList] = useState([])//异常&问题列表 |
|
|
|
const [setup, setSetup] = useState(false); //设置是否显现 |
|
|
|
const [tableType, setTableType] = useState(''); //localStorage存储名 |
|
|
|
const [tool, setTool] = useState(false); //工具添加修改弹窗 |
|
|
@ -43,7 +37,10 @@ const Control = (props) => { |
|
|
|
const [compile, setCompile] = useState({}); //工具编辑的内容 |
|
|
|
const [toolShow, setToolShow] = useState([]); //工具展示 |
|
|
|
const [tableSetup, setTableSetup] = useState([]); //单一表格设置信息 |
|
|
|
const [workData, setWorkData] = useState(); //我的工作台数据 |
|
|
|
const [workData, setWorkData] = useState({}); //我的工作台数据 |
|
|
|
const [dataBI, setDataBI] = useState({}); //查询BI分析数据-数据 |
|
|
|
const [videoBI, setVideoBI] = useState([]); //查询BI分析数据-视频 |
|
|
|
const [appBI, setAppBI] = useState([]); //查询BI分析数据-应用 |
|
|
|
|
|
|
|
const exhibition = useRef({ workbench: [], statistical: [] }) //页面结构 |
|
|
|
const FormApi = useRef() |
|
|
@ -56,22 +53,60 @@ const Control = (props) => { |
|
|
|
data.map(v => { |
|
|
|
localStorage.getItem(v) == null |
|
|
|
? localStorage.setItem(v, JSON.stringify(show[v])) |
|
|
|
: ""; |
|
|
|
: "" |
|
|
|
attribute(v) |
|
|
|
}) |
|
|
|
|
|
|
|
}, []) |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
// 工作台数据请求 |
|
|
|
dispatch(control.getConsoleCount({ pepProjectId: pepProjectId })).then(res => { |
|
|
|
if (res.success) setWorkData(res.payload.data) |
|
|
|
}) |
|
|
|
// 统计概览--异常&问题 |
|
|
|
dispatch(control.getConsoleAbnormal({ pepProjectId: pepProjectId })).then(res => { |
|
|
|
console.log(res.payload.data); |
|
|
|
if (res.success) setProblemsList([...res.payload.data,...res.payload.data]) |
|
|
|
if (res.success) { |
|
|
|
if (res.payload.data?.length > 4) { |
|
|
|
setProblemsList([...res.payload.data, ...res.payload.data]) |
|
|
|
startmarquee(500, 2000, 'problems') |
|
|
|
} else { |
|
|
|
setProblemsList(res.payload.data) |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
// 统计概览--相关成员与web应用 |
|
|
|
dispatch(control.getConsoleUser({ pepId: pepProjectId })).then(res => { |
|
|
|
if (res.success) { |
|
|
|
if (res.payload.data?.personnel?.length > 5) { |
|
|
|
setMemberList([...res.payload.data?.personnel, ...res.payload.data?.personnel]) |
|
|
|
startmarquee(600, 2000, 'member') |
|
|
|
} else { |
|
|
|
setMemberList(res.payload.data?.personnel) |
|
|
|
} |
|
|
|
if (res.payload.data?.webApp?.length > 3) { |
|
|
|
setWebList([...res.payload.data?.webApp, ...res.payload.data?.webApp]) |
|
|
|
startmarquee(600, 2000, 'web') |
|
|
|
} else { |
|
|
|
setWebList(res.payload.data?.webApp) |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
// 查询BI分析数据-数据 |
|
|
|
dispatch(control.getDataAlarmsAggDay({ pepProjectId: pepProjectId })).then(res => { |
|
|
|
if (res.success) setDataBI(res.payload.data) |
|
|
|
}) |
|
|
|
//查询BI分析数据-视频异常 |
|
|
|
dispatch(control.getVideoAlarmsAggDay({ pepProjectId: pepProjectId })).then(res => { |
|
|
|
if (res.success) setVideoBI(res.payload.data) |
|
|
|
}) |
|
|
|
//查询BI分析数据-应用 |
|
|
|
dispatch(control.getAppAlarmsAggDay({ pepProjectId: pepProjectId })).then(res => { |
|
|
|
// console.log(res.payload.data); |
|
|
|
if (res.success) setAppBI(res.payload.data) |
|
|
|
}) |
|
|
|
}, [pepProjectId]) |
|
|
|
|
|
|
|
}, [pepProjectId]) |
|
|
|
useEffect(() => { |
|
|
|
|
|
|
|
const domProject = document.getElementById("news"); |
|
|
@ -154,25 +189,55 @@ const Control = (props) => { |
|
|
|
if (res.success) setToolShow(res.payload.data) |
|
|
|
}) |
|
|
|
} |
|
|
|
function startmarquee (speed, delay, name) { |
|
|
|
/* |
|
|
|
函数startmarquee的参数: |
|
|
|
lh:文字一次向上滚动的距离或高度; |
|
|
|
speed:滚动速度; |
|
|
|
delay:滚动停顿的时间间隔; |
|
|
|
index:可以使封装后的函数应用于页面当中不同的元素; |
|
|
|
*/ |
|
|
|
var t; |
|
|
|
var p = false; |
|
|
|
let top = 0 |
|
|
|
var o = document.getElementById(name); |
|
|
|
if (o) { |
|
|
|
o.onmouseover = () => p = true |
|
|
|
o.onmouseout = () => p = false |
|
|
|
o.scrollTop = 0; |
|
|
|
const start = () => { |
|
|
|
t = setInterval(() => { |
|
|
|
if (!p) (top += 10, o.scrollTop = top) |
|
|
|
if (p) (clearInterval(t), setTimeout(start, delay)) |
|
|
|
if (o.scrollTop >= o.scrollHeight / 2) (top = 0, o.scrollTop = 0) |
|
|
|
}, speed); |
|
|
|
} |
|
|
|
setTimeout(start, 1000); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let Select = { |
|
|
|
workbench: ['project', 'data', 'app', 'device'], |
|
|
|
statistical: ['milestone', 'personnel', 'DeviceAccess', 'web', 'problem'], |
|
|
|
analyse: ['dataInterrupt', 'dataAnomaly', 'strategyHit', 'videoException', 'appAbnormal', 'unitException', 'problemAnalysis'], |
|
|
|
analyse: ['dataInterrupt', 'dataAbnormal', 'policyHit', 'videoException', 'appAbnormal', 'deviceAbnormal', 'problemAnalysis'], |
|
|
|
dynamic: [], |
|
|
|
} |
|
|
|
let show = { |
|
|
|
workbench: ['project', 'data', 'app', 'device'], |
|
|
|
statistical: ['milestone', 'personnel', 'DeviceAccess', 'web', 'problem'], |
|
|
|
analyse: ['dataInterrupt', 'dataAnomaly', 'strategyHit', 'videoException', 'appAbnormal', 'unitException', 'problemAnalysis'], |
|
|
|
analyse: ['dataInterrupt', 'dataAbnormal', 'policyHit', 'videoException', 'appAbnormal', 'deviceAbnormal', 'problemAnalysis'], |
|
|
|
dynamic: [], |
|
|
|
} |
|
|
|
|
|
|
|
let listAll = [ |
|
|
|
{ name: '关注的项目', sort: 1, key: 'project', data: workData?.projects || 0, img: 'url(/assets/images/console/lan_1.png)' }, |
|
|
|
{ name: '数据告警', sort: 2, key: 'data', data: workData?.dataSurplus || 0, img: 'url(/assets/images/console/lv_1.png)' }, |
|
|
|
{ name: '应用告警', sort: 2, key: 'app', data: workData?.appSurplus || 0, img: 'url(/assets/images/console/hong_1.png)' }, |
|
|
|
{ name: '设备告警', sort: 2, key: 'device', data: workData?.toolSurplus || 0, img: 'url(/assets/images/console/hong_1.png)' }, |
|
|
|
{ name: '数据告警', sort: 2, key: 'data', data: workData?.dataSurplus || 0, img: 'url(/assets/images/console/lv_1.png)', url: '/problem/dataAlarm/dataLnterrupt' }, |
|
|
|
{ name: '应用告警', sort: 2, key: 'app', data: workData?.appSurplus || 0, img: 'url(/assets/images/console/hong_1.png)', url: '/problem/useAlarm/useAbnormal' }, |
|
|
|
{ name: '设备告警', sort: 2, key: 'device', data: workData?.toolSurplus || 0, img: 'url(/assets/images/console/hong_1.png)', url: '/problem/deviceAlarm/deviceAbnormal' }, |
|
|
|
|
|
|
|
{ name: '项目里程碑', sort: 1, key: 'milestone', }, |
|
|
|
{ name: '相关成员', sort: 2, key: 'personnel', }, |
|
|
@ -181,11 +246,11 @@ const Control = (props) => { |
|
|
|
{ name: '异常&问题', sort: 5, key: 'problem', }, |
|
|
|
|
|
|
|
{ name: '数据中断', sort: 1, key: 'dataInterrupt', }, |
|
|
|
{ name: '数据异常', sort: 2, key: 'dataAnomaly', }, |
|
|
|
{ name: '策略命中', sort: 3, key: 'strategyHit', }, |
|
|
|
{ name: '数据异常', sort: 2, key: 'dataAbnormal', }, |
|
|
|
{ name: '策略命中', sort: 3, key: 'policyHit', }, |
|
|
|
{ name: '视频异常', sort: 4, key: 'videoException', }, |
|
|
|
{ name: '应用异常', sort: 5, key: 'appAbnormal', }, |
|
|
|
{ name: '设备异常', sort: 6, key: 'unitException', }, |
|
|
|
{ name: '设备异常', sort: 6, key: 'deviceAbnormal', }, |
|
|
|
{ name: '问题处置效率分析', sort: 7, key: 'problemAnalysis', }, |
|
|
|
] |
|
|
|
|
|
|
@ -209,7 +274,6 @@ const Control = (props) => { |
|
|
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
// 11 ? <img src="/assets/images/install/watting.png" alt="" style={{ width: 'calc(100% + 16px)', position: "relative", top: -12, left: -8, }} /> : |
|
|
|
<> |
|
|
|
<div style={{ padding: '0px 40px', width: '100%' }} className='console'> |
|
|
|
{/* 头部 */} |
|
|
@ -290,7 +354,7 @@ const Control = (props) => { |
|
|
|
<span style={{ fontSize: 12, color: '#4A4A4A' }}>{item.name == '关注的项目' ? ' ( 个 )' : ' ( 条 )'}</span> |
|
|
|
</div> |
|
|
|
<div style={{ marginTop: 15, display: 'flex', alignItems: 'center' }}> |
|
|
|
<div style={{ fontSize: 32, color: index == 0 ? '#0F7EFB' : index == 1 ? '#0091A1' : index == 2 ? '#FE9812' : '#FF7575', fontFamily: 'YouSheBiaoTiHei' }}>{item.data}</div> |
|
|
|
<div onClick={() => dispatch(push(item.url))} style={{ fontSize: 32, color: index == 0 ? '#0F7EFB' : index == 1 ? '#0091A1' : index == 2 ? '#FE9812' : '#FF7575', fontFamily: 'YouSheBiaoTiHei' }}>{item.data}</div> |
|
|
|
{item.name == '关注的项目' ? '' : <div style={{ fontSize: 12, color: '#969799', marginLeft: 4 }}>待处理</div>} |
|
|
|
</div> |
|
|
|
</div> |
|
|
@ -387,7 +451,7 @@ const Control = (props) => { |
|
|
|
相关成员 |
|
|
|
</div> |
|
|
|
<div id='member' style={{ position: 'relative', height: 161 }}> |
|
|
|
{memberList.map((item, index) => { |
|
|
|
{memberList?.map((item, index) => { |
|
|
|
return ( |
|
|
|
<div key={index + 'member'} style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 15 }}> |
|
|
|
<div style={{ display: 'flex', alignItems: 'center' }}> |
|
|
@ -395,7 +459,7 @@ const Control = (props) => { |
|
|
|
<img src="/assets/images/console/member.png" alt="成员" style={{ width: '100%', height: '100%' }} /> |
|
|
|
</div> |
|
|
|
<div style={{ marginLeft: 8, fontSize: 14, color: '#4A4A4A' }}> |
|
|
|
刘昊然 |
|
|
|
{item.name} |
|
|
|
</div> |
|
|
|
<div style={{ fontSize: 12, color: '#969799' }}> |
|
|
|
(负责人) |
|
|
@ -454,17 +518,19 @@ const Control = (props) => { |
|
|
|
{ |
|
|
|
webList.map((item, index) => { |
|
|
|
return ( |
|
|
|
<div key={index + 'web'} style={{ marginBottom: 15, display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}> |
|
|
|
<div key={index + 'webb'} style={{ marginBottom: 15, }}> |
|
|
|
<div style={{ display: 'flex' }}> |
|
|
|
<div style={{ width: 18, height: 18, marginRight: 8 }}> |
|
|
|
<img src="/assets/images/console/icon_webpage.png" alt="web应用" style={{ width: '100%', height: '100%' }} /> |
|
|
|
</div> |
|
|
|
<div style={{ color: '#646566', fontSize: 14, borderBottom: '1px dotted #0F7EFB' }}> |
|
|
|
superchangnan.anxiny |
|
|
|
<a href={item.url} target="_blank"> |
|
|
|
{item.url} |
|
|
|
</a> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div style={{ color: '#4A4A4A', fontSize: 14, marginRight: 40 }}> |
|
|
|
第三方 |
|
|
|
<div style={{ color: '#4A4A4A', fontSize: 14, marginLeft: 26 }}> |
|
|
|
{item.name} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
) |
|
|
@ -481,14 +547,16 @@ const Control = (props) => { |
|
|
|
</div> |
|
|
|
<div id='problems' style={{ position: 'relative', height: 161 }}> |
|
|
|
{ |
|
|
|
problemsList.map((item, index) => { |
|
|
|
problemsList?.map((v, index) => { |
|
|
|
return ( |
|
|
|
<div style={{ marginBottom: 15, paddingRight: 30, }}> |
|
|
|
<div style={{ fontSize: 14, color: '#646566' }}> |
|
|
|
【告警源A】数据信息中断,诊断为 <span style={{ color: '#0F7EFB', borderBottom: '1px dotted #0F7EFB', cursor: "pointer" }}>服务异常,请前往确认</span> |
|
|
|
<div style={{ marginBottom: 15, paddingRight: 30, }} key={'problems' + index} onClick={() => { |
|
|
|
dispatch(push(v.url)) |
|
|
|
}}> |
|
|
|
<div style={{ fontSize: 14, color: '#646566' }} > |
|
|
|
【{v.SourceName}】{v.groupName}{v.groupName == '视频异常' ? "" : ',诊断为 '} <span style={{ color: '#0F7EFB', borderBottom: '1px dotted #0F7EFB', cursor: "pointer" }} >{v.typeName},请前往确认</span> |
|
|
|
</div> |
|
|
|
<div style={{ color: '#969799', fontSize: 12, marginRight: 40, marginTop: 4 }}> |
|
|
|
2022-05-21 15:23:41 |
|
|
|
{moment(v.StartTime).format("YYYY-MM-DD HH:mm:ss")} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
) |
|
|
@ -518,7 +586,37 @@ const Control = (props) => { |
|
|
|
</div> |
|
|
|
<div style={{ width: '100%', height: '100%' }}> |
|
|
|
{exhibition.current?.analyse?.map((v, index) => { |
|
|
|
return <div id={'ReactECharts' + index} style={{ marginTop: 20, padding: 10, width: '50%', display: "inline-block" }}> |
|
|
|
let startValue = '' |
|
|
|
if (v.key !== 'problemAnalysis') { |
|
|
|
switch (v.key) { |
|
|
|
case 'videoException': |
|
|
|
let videos = videoBI?.filter(u => moment(moment().day(moment().day() - 30).format('YYYY-MM-DD')).isBefore(u.day)) || [] |
|
|
|
if (videos.length) { |
|
|
|
startValue = videos[0]?.day |
|
|
|
} else { |
|
|
|
startValue = videoBI?.slice(-1)[0]?.day |
|
|
|
} |
|
|
|
break; |
|
|
|
case 'appAbnormal': |
|
|
|
let apps = appBI?.filter(u => moment(moment().day(moment().day() - 30).format('YYYY-MM-DD')).isBefore(u.day)) || [] |
|
|
|
if (apps.length) { |
|
|
|
startValue = apps[0]?.day |
|
|
|
} else { |
|
|
|
startValue = appBI?.slice(-1)[0]?.day |
|
|
|
} |
|
|
|
break; |
|
|
|
default: |
|
|
|
let datas = dataBI[v.key]?.filter(u => moment(moment().day(moment().day() - 30).format('YYYY-MM-DD')).isBefore(u.day)) || [] |
|
|
|
if (datas.length) { |
|
|
|
startValue = datas[0]?.day |
|
|
|
} else { |
|
|
|
startValue = dataBI[v.key]?.slice(-1)[0]?.day |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
// console.log(startValue); |
|
|
|
return v.key == 'problemAnalysis' ? <div id={'ReactECharts' + index} style={{ marginTop: 20, padding: 10, width: '50%', display: "inline-block" }}> |
|
|
|
<ReactECharts |
|
|
|
option={{ |
|
|
|
title: { |
|
|
@ -532,23 +630,18 @@ const Control = (props) => { |
|
|
|
}, |
|
|
|
dataZoom: [ |
|
|
|
{ |
|
|
|
show: true, |
|
|
|
type: 'inside', |
|
|
|
filterMode: 'none', |
|
|
|
xAxisIndex: [0], |
|
|
|
type: 'slider', |
|
|
|
// startValue: |
|
|
|
}, |
|
|
|
{ |
|
|
|
show: true, |
|
|
|
type: 'inside', |
|
|
|
filterMode: 'none', |
|
|
|
yAxisIndex: [0], |
|
|
|
} |
|
|
|
}, |
|
|
|
], |
|
|
|
tooltip: { |
|
|
|
trigger: 'axis' |
|
|
|
}, |
|
|
|
legend: { |
|
|
|
data: ['次数'], |
|
|
|
data: [v.name, '已处理(含自动恢复)'], |
|
|
|
right: '10%', |
|
|
|
}, |
|
|
|
xAxis: { |
|
|
@ -559,21 +652,18 @@ const Control = (props) => { |
|
|
|
}, |
|
|
|
yAxis: { |
|
|
|
type: 'value', |
|
|
|
name: "次数", |
|
|
|
name: "条数", |
|
|
|
}, |
|
|
|
series: [ |
|
|
|
{ |
|
|
|
data: [], |
|
|
|
type: 'line', |
|
|
|
name: '次数', |
|
|
|
name: v.name, |
|
|
|
smooth: true, |
|
|
|
areaStyle: { |
|
|
|
color: '#0e9cff26', |
|
|
|
}, |
|
|
|
markLine: { |
|
|
|
data: [{ type: 'average', name: 'Avg' }] |
|
|
|
} |
|
|
|
} |
|
|
|
data: [] |
|
|
|
}, |
|
|
|
] |
|
|
|
}} |
|
|
|
notMerge={true} |
|
|
@ -584,6 +674,74 @@ const Control = (props) => { |
|
|
|
// opts={} |
|
|
|
/> |
|
|
|
</div> |
|
|
|
: <div id={'ReactECharts' + index} style={{ marginTop: 20, padding: 10, width: '50%', display: "inline-block" }}> |
|
|
|
<ReactECharts |
|
|
|
option={{ |
|
|
|
title: { |
|
|
|
text: v.name, |
|
|
|
}, |
|
|
|
grid: { |
|
|
|
left: '5%', |
|
|
|
// right: '4%', |
|
|
|
// bottom: '3%', |
|
|
|
// containLabel: true |
|
|
|
}, |
|
|
|
dataZoom: [ |
|
|
|
{ |
|
|
|
type: 'slider', |
|
|
|
startValue: startValue |
|
|
|
}, |
|
|
|
{ |
|
|
|
type: 'inside', |
|
|
|
}, |
|
|
|
], |
|
|
|
tooltip: { |
|
|
|
trigger: 'axis' |
|
|
|
}, |
|
|
|
legend: { |
|
|
|
data: [v.name, '已处理(含自动恢复)'], |
|
|
|
right: '10%', |
|
|
|
}, |
|
|
|
xAxis: { |
|
|
|
type: 'category', |
|
|
|
name: "时间", |
|
|
|
boundaryGap: false, |
|
|
|
data: v.key == 'videoException' ? videoBI?.map(u => u.day) : v.key == 'appAbnormal' ? appBI?.map(u => u.day) : dataBI[v.key]?.map(u => u.day) || [] |
|
|
|
}, |
|
|
|
yAxis: { |
|
|
|
type: 'value', |
|
|
|
name: "条数", |
|
|
|
}, |
|
|
|
series: [ |
|
|
|
{ |
|
|
|
type: 'line', |
|
|
|
name: v.name, |
|
|
|
smooth: true, |
|
|
|
areaStyle: { |
|
|
|
color: '#0e9cff26', |
|
|
|
}, |
|
|
|
data: v.key == 'videoException' ? videoBI?.map(u => u.total) : v.key == 'appAbnormal' ? appBI?.map(u => u.total) : dataBI[v.key]?.map(u => u.total) || [] |
|
|
|
}, |
|
|
|
{ |
|
|
|
type: 'line', |
|
|
|
name: '已处理(含自动恢复)', |
|
|
|
smooth: true, |
|
|
|
areaStyle: { |
|
|
|
color: '#0e9cff26', |
|
|
|
}, |
|
|
|
data: v.key == 'videoException' ? videoBI?.map(u => u.done) : v.key == 'appAbnormal' ? appBI?.map(u => u.done) : dataBI[v.key]?.map(u => u.done) || [] |
|
|
|
}, |
|
|
|
|
|
|
|
] |
|
|
|
}} |
|
|
|
notMerge={true} |
|
|
|
lazyUpdate={true} |
|
|
|
theme={'ReactEChart' + index} |
|
|
|
// onChartReady={this.onChartReadyCallback} |
|
|
|
// onEvents={EventsDict} |
|
|
|
// opts={} |
|
|
|
/> |
|
|
|
</div> |
|
|
|
})} |
|
|
|
</div> |
|
|
|
|
|
|
|