引入geo数据
地图JSON数据来源:
在tsconfig.json中添加配置,允许TS中导入json文件
"resolveJsonModule": true,
显示地图及Tooltip轮播
import React, { useRef, useEffect, useState } from 'react'
import XHData from '../geo/geoData.json'
import * as echarts from 'echarts'
import { createEchartsOptions } from '../shared/create-echart-options'
export const Chart6 = () => {
const divRef = useRef(null)
useEffect(() => {
let index = -1
const myChart = echarts.init(divRef.current)
// myChart.hideLoading()
// @ts-ignore
echarts.registerMap('XH', XHData)
let mTime = null
// 实现ToolTip高亮轮播
function mapActive() {
const dataLength = XHData.features.length
// 用定时器控制高亮
mTime = setInterval(() => {
// 清除之前的高亮
myChart.dispatchAction({
type: 'downplay',
seriesIndex: 0,
dataIndex: index,
})
index++
// 当前下标高亮
myChart.dispatchAction({
type: 'highlight',
seriesIndex: 0,
dataIndex: index,
})
myChart.dispatchAction({
type: 'showTip',
seriesIndex: 0,
dataIndex: index,
})
if (index > dataLength) {
index = 0
}
}, 2000)
}
mapActive()
myChart.on('mouseover', () => {
// 停止定时器,清除之前的高亮
console.log('mouseover')
clearInterval(mTime)
mTime = null
myChart.dispatchAction({
type: 'downplay',
seriesIndex: 0,
dataIndex: index,
})
})
// 鼠标划出重新定时器开始
myChart.on('mouseout', () => {
mapActive()
})
const option = {
xAxis: { show: false },
yAxis: { show: false },
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(0,0,0,0)',
},
visualMap: {
show: false,
min: 800,
max: 50000,
text: ['High', 'Low'],
realtime: false,
calculable: true,
inRange: {
color: ['lightskyblue', 'yellow', 'orangered'],
},
},
series: [
{
tooltip: {
trigger: 'item',
// 自定义tooltip样式
formatter: function (item) {
var tipHtml = ''
tipHtml = `<div style="padding: .6rem .8rem;font-size: .325rem;color:#fff;border-radius:4px;
background-size: .08rem .3rem, .3rem .08rem;background-color:rgba(6, 79, 111,.6);">${item.data.name} <span style="color:#f9eb59;font-size:.4rem">${item.data.value}</span> </div>`
return tipHtml
},
// borderWidth: 0,
},
label: { show: false },
data: [],
name: '西虹市地图',
type: 'map',
mapType: 'XH', // 自定义扩展图表类型
aspectScale: 1,
layoutCenter: ['49%', '47%'], //地图位置
layoutSize: '90%', // 缩放比例
itemStyle: {
color: 'transparent', // 去除坐标小圆点
emphasis: {
label: {
show: true,
},
},
},
},
],
}
option.series[0].data = XHData.features.map((item) => {
// 显示窗口的数据转换
return {
value: (Math.random() * 5000).toFixed(0),
name: item.properties.name,
}
})
myChart.setOption(createEchartsOptions(option))
return () => clearInterval(mTime)
}, [])
return (
<div className="bordered 籍贯">
<h2>全市案件侦破实时记录</h2>
<div ref={divRef} className="chart" />
</div>
)
}
监控扫描动画
<div className="scan-animation">
<div className="ring">
<div className="radar" />
</div>
<span>数据实时监控中</span>
</div>
> .scan-animation {
position: absolute;
bottom: px(20);
left: px(24);
display: flex;
align-items: center;
flex-direction: column;
gap: px(10);
> span {
font-size: px(4);
color: #a1d1f1;
}
> .ring {
border: 1px solid #0c2939;
width: px(96);
height: px(96);
border-bottom: none;
border-radius: 50%;
overflow: hidden;
animation: spin infinite 5s linear;
> .radar {
border: 2px solid #103142;
position: absolute;
width: px(81);
height: px(81);
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
&::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: px(42);
height: px(42);
border: 2px solid #082132;
border-radius: 50%;
}
&::after {
content: '';
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: px(3);
height: px(36);
z-index: 1;
background: #007cc0;
border-radius: 50%;
box-shadow: 0 0 5px 1px #0094e4, -3px -10px 5px 1px #0094e4,
-7px -15px 10px 1px #0094e4, -3px -3px 10px 1px #0094e4,
-7px -7px 20px 1px #0094e4, -11px -11px 30px 1px #0094e4,
-11px -11px 40px 1px #0094e4, -11px -11px 30px 1px #0094e4,
-11px -11px 30px 1px #0094e4;
}
}
}
@keyframes spin {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
}
}
显示访问数量
- 重点是要在 useEffect 中返回清除函数,清除掉上一个 setInterval, 否则每次重新渲染都会新增一个 setInterval
- 使用
number.toLocaleString()
将数字格式化,每三位显示一个逗号,也可以使用toLocaleString('en-US')
import React, { useRef, useEffect, useState } from 'react'
export const Chart6 = () => {
const [count, setCount] = useState(325920)
useEffect(() => {
const timer = setInterval(() => {
setCount(count + 1)
}, 500)
return () => {
clearInterval(timer)
}
}, [count])
return (
<div className="bordered note">
<span>{count.toLocaleString()}</span>
<span>接待访客</span>
</div>
)
}
[