前言
大数据可视化不可绕开的图表便是地图。本章节,我们将简单实现一个完整的中国地图以及简单的交互,并封装成React组件。效果图如下:
组件使用代码如下:render() {
const { clientX, clientY, province } = this.state;
return (
<React.Fragment>
<div style={{top: clientY, left: clientX}} className="tip">
{ province }
</div>
<Map
className="chart"
onClick={this.onMapClick}
/>
</React.Fragment>
)
}
地图图层
地图图层的实现其实很简单,由效果图可以看出,地图由多个多变形拼接组成,所以我们只需计算出各个省市边界的相应坐标,几个绘制地图。
这里我们只需将各个省市的经纬度转换成画布上的坐标即可,各省市geojson数据可以戳这里。
地图图层绘制代码如下:
make() {
this.clearEventListener();
this.childs.splice(0, this.childs.length);
const xStep = this.width / (maxX - minX);
const yStep = this.height / (maxY - minY);
for (let m = 0; m < bound.features.length; m++) {
const coordinates = bound.features[m].geometry.coordinates;
for (let i = 0; i < coordinates.length; i++) {
let item = coordinates[i];
for (let j = 0; j < item.length; j++) {
let dots = item[j];
let polygonPoint = [];
for (let k = 0; k < dots.length; k++) {
polygonPoint.push(
new Point(
(dots[k][0] - minX) * xStep,
(dots[k][1] - minY) * yStep
));
}
let polygon = new Polygon(this.canvas, {
type: Polygon.TYPE.STROKE,
color: this.color,
}, polygonPoint);
this.addChild(polygon);
}
}
}
// 绘制省界线
for (let m = 0; m < full.features.length; m++) {
const coordinates = full.features[m].geometry.coordinates;
for (let i = 0; i < coordinates.length; i++) {
let item = coordinates[i];
for (let j = 0; j < item.length; j++) {
let dots = item[j];
let polygonPoint = [];
for (let k = 0; k < dots.length; k++) {
polygonPoint.push(
new Point(
(dots[k][0] - minX) * xStep,
(dots[k][1] - minY) * yStep
));
}
let polygon = new Polygon(this.canvas, {
type: Polygon.TYPE.STROKE,
color: this.color,
lineDash: [5, 10],
lineWidth: 1,
}, polygonPoint);
polygon.ext = full.features[m].properties;
(this.onClick && (
polygon.addEventListener(Event.EVENT_CLICK, (e) => {
console.log(e);
this.onClick && this.onClick(e);
})
))
this.addChild(polygon);
}
}
}
}
为了减少绘制过程中的计算,我们已经实现计算完成了中国地图的最大最小经纬度maxX, maxY, minX, minY。上述代码中bound为中国地图轮廓的经纬度geo数据,full为各省市自治区的geo数据,geo数据格式不在这里赘述,可自行查看网站数据
React 封装
React封装需要DOM的挂载完成,所以我们在生命周期componentDidMount函数中构建我们的图层。
代码如下:
componentDidMount () {
const { style = {} } = this.props;
this.canvas = new Canvas({
ele: this.ref.current,
canAction: false,
});
this.map = new MapLayer(this.canvas, {
color: style.color,
onClick: this.props.onClick
});
this.map.make();
this.canvas.addChild(this.map);
this.canvas.paint();
}
目录
【实现自己的可视化引擎01】认识Canvas
【实现自己的可视化框架引擎02】抽象图像元素
【实现自己的可视化引擎03】构建基础图元库
【实现自己的可视化引擎04】图像元素动画
【实现自己的可视化引擎05】交互与事件
【实现自己的可视化引擎06】折线图
【实现自己的可视化引擎07】柱状图
【实现自己的可视化引擎08】条形图
【实现自己的可视化引擎09】饼图
【实现自己的可视化引擎10】散点图
【实现自己的可视化引擎11】雷达图
【实现自己的可视化引擎12】K线图
【实现自己的可视化引擎13】仪表盘
【实现自己的可视化引擎14】地图
【实现自己的可视化引擎15】关系图