echarts是比较流行的图标和地图框架,文档清晰,灵活,满足各种自定义。众多的api接口,让使用者犹如大海捞针,每一个细节都需要通过api慢慢调整,耗费开发者大量的时间精力。
在这里补充一种新的图表地图框架,虽然做得不如echarts强大,适合快速开发节奏,让前端程序员在除了echarts以外还可以多一种选择。
antv是蚂蚁金服团队打造的图表和地图框架(用过antd的同学应该知道这个团队)。
官方网站:https://antv.vision/zh/about
antv包含
G2(就是图表渲染,条形图,饼图,折线图等,里面有一些比较好看的图表设计,可以直接拿来用。)
G2地址 https://g2.antv.vision/zh/examples/gallery
G6 (思维导图,流程展示,树状图,)
G6地址 https://g6.antv.vision/zh/examples/tree/compactBox
F2 (针对移动端图表进行适配)
F2地址 https://f2.antv.vision/zh/examples/candlestick/basic
L7(地图,支持全球,全国(目前只支持中国),省,市,)
L7地址 https://l7.antv.vision/zh/examples/gallery
正如最开始所说,antv不如echarts全面,但参照了部分echarts的api借口,在使用过程能看到和echarts类似的api和相似的功能。
antv的优势在于快速生成代码,配置图表的功能chartCub魔方(图表魔方,图表生成器)。
echarts自定义图表,是先写配置api才能看到生成图表的样式,而图表魔方为用户提供预览图表的功能,通过可视化界面,对图表进行样式配置并生成相应的代码。
图表魔方地址 https://chartcube.alipay.com/guide
这是未来前端发展的一种趋势,可视化配置,会慢慢代替许多代码的复制粘贴。虽然目前图表魔方只支持比较基础的图标配置,比较个性化的图表还是需要使用echarts。
笔者只用过G2和L7,其它内容暂不做展示,如果以后也有使用,会更新本篇博客。
安装 @antv/g2plot
yarn add @antv/g2plot
npm i @antv/g2plot --save
以下代码都是通过配置后图表魔方自动生成的代码
//导入G2Plot
import * as G2Plot from '@antv/g2plot';
//选择图表生成的dom节点,图表会生成到这个dom节点内。
//唯一需要注意的是,如果是vue或者react框架,进行这一步操作的时候,一定要确定这dom节点已经渲染成功,并且能够被找到。
const container = document.getElementById('app');
//需要渲染的数据,字段名和数据结构不可更改
const data = [
{
"series": "门店一",
"x": "家具家电",
"y": 185
},
{
"series": "门店一",
"x": "粮油副食",
"y": 509
},
{
"series": "门店一",
"x": "美容洗护",
"y": 901
},
{
"series": "门店一",
"x": "母婴用品",
"y": 645
},
{
"series": "门店一",
"x": "进口食品",
"y": 98
},
{
"series": "门店一",
"x": "食品饮料",
"y": 724
},
{
"series": "门店一",
"x": "家庭清洁",
"y": 471
},
{
"series": "门店二",
"x": "家具家电",
"y": 276
},
{
"series": "门店二",
"x": "粮油副食",
"y": 186
},
{
"series": "门店二",
"x": "美容洗护",
"y": 648
},
{
"series": "门店二",
"x": "母婴用品",
"y": 484
},
{
"series": "门店二",
"x": "进口食品",
"y": 21
},
{
"series": "门店二",
"x": "食品饮料",
"y": 721
},
{
"series": "门店二",
"x": "家庭清洁",
"y": 917
}
];
/** 图表配置,代码由图表魔方自动生成,直接复制粘贴就好了 */
const config = {
/** 标题 */
title: {
visible: true,
text: '考试科目柱状图',
},
/** 副标题 */
description: {
visible: true,
text: '考试科目学生参加百分比',
},
legend: {
flipPage: false,
},
xAxis: {
title: {
visible: false,
},
},
yAxis: {
title: {
visible: false,
},
},
/** 自使用父级的宽高 */
forceFit: true,
/** 也可以自定义图表的宽高 */
// width: 570,
// height: 360,
xField: 'x',
yField: 'y',
stackField: 'series',
/** 两种渲染颜色 */
color: ['#e9e9e9', '#5b8ff9'],
};
/** 渲染实例 */
const plot = new G2Plot.PercentStackedColumn(container, {
data: chartsData,
...config,
});
plot.render();
如果是使用其它框架,就需要考验最基础的代码改造能力,echarts图表魔方,能够提供的是原生的js代码。
改造的完整react框架组件
import React, {
useEffect, useState } from 'react';
import * as G2Plot from '@antv/g2plot';
/** 图标配置,代码由图表魔方自动生成 */
const config = {
/** 标题 */
title: {
visible: true,
text: '考试科目柱状图',
},
/** 副标题 */
description: {
visible: true,
text: '考试科目学生参加百分比',
},
legend: {
flipPage: false,
},
xAxis: {
title: {
visible: false,
},
},
yAxis: {
title: {
visible: false,
},
},
/** 自使用父级的宽高 */
forceFit: true,
/** 也可以自定义图表的宽高 */
// width: 570,
// height: 360,
xField: 'x',
yField: 'y',
stackField: 'series',
/** 两种渲染颜色 */
color: ['#e9e9e9', '#5b8ff9'],
};
const PaperRadar: React.FC = () => {
type ChartsDataType = {
series: string;
x: string;
y: number;
}[];
/** 数据渲染 */
const [chartsData, setChartsData] = useState<ChartsDataType>([] as ChartsDataType);
/** 渲染函数 */
const chartsRender = () => {
const container: HTMLElement = document.getElementById('exam-bar') as HTMLElement;
const plot = new G2Plot.PercentStackedColumn(container, {
data: chartsData,
...config,
});
plot.render();
};
useEffect(() => {
setChartsData([
{
series: '门店一',
x: '家具家电',
y: 777,
},
{
series: '门店一',
x: '粮油副食',
y: 934,
},
{
series: '门店一',
x: '美容洗护',
y: 454,
},
{
series: '门店一',
x: '母婴用品',
y: 999,
},
{
series: '门店一',
x: '进口食品',
y: 98,
},
{
series: '门店一',
x: '食品饮料',
y: 317,
},
{
series: '门店一',
x: '家庭清洁',
y: 307,
},
{
series: '门店二',
x: '家具家电',
y: 142,
},
{
series: '门店二',
x: '粮油副食',
y: 199,
},
{
series: '门店二',
x: '美容洗护',
y: 582,
},
{
series: '门店二',
x: '母婴用品',
y: 64,
},
{
series: '门店二',
x: '进口食品',
y: 89,
},
{
series: '门店二',
x: '食品饮料',
y: 641,
},
{
series: '门店二',
x: '家庭清洁',
y: 984,
},
]);
// chartsRender();
}, []);
useEffect(() => {
if (chartsData.length) {
chartsRender();
}
}, [chartsData]);
return (
<>
<div id="exam-bar" style={
{
width:"100%"}}></div>
</>
);
};
export default PaperRadar;
根据antv的l7的安装教程,分别安装 @antv/l7 @antv/l7-district @antv/l7-maps
yarn add @antv/l7
yarn add @antv/l7-district
yarn add @antv/l7-maps
或
npm i @antv/l7 --save
npm i @antv/l7-district
npm i @antv/l7-maps
react代码
import React, {
useEffect, useState } from 'react';
import {
Scene } from '@antv/l7';
import {
CountryLayer } from '@antv/l7-district';
import {
Mapbox } from '@antv/l7-maps';
/** 地图配置 */
// 我选择的事全国地图,name和对应的code都是antv l7官方提供的,
// value字段及字段名是可以自定义的
const ProvinceData = [
{
name: '云南省',
code: 530000,
value: 0,
},
{
name: '黑龙江省',
code: 230000,
value: 0,
},
{
name: '贵州省',
code: 520000,
value: 0,
},
{
name: '北京市',
code: 110000,
value: 0,
},
{
name: '河北省',
code: 130000,
value: 0,
},
{
name: '山西省',
code: 140000,
value: 0,
},
{
name: '吉林省',
code: 220000,
value: 0,
},
{
name: '宁夏回族自治区',
code: 640000,
value: 0,
},
{
name: '辽宁省',
code: 210000,
value: 0,
},
{
name: '海南省',
code: 460000,
value: 0,
},
{
name: '内蒙古自治区',
code: 150000,
value: 0,
},
{
name: '天津市',
code: 120000,
value: 0,
},
{
name: '新疆维吾尔自治区',
code: 650000,
value: 0,
},
{
name: '上海市',
code: 310000,
value: 0,
},
{
name: '陕西省',
code: 610000,
value: 0,
},
{
name: '甘肃省',
code: 620000,
value: 0,
},
{
name: '安徽省',
code: 340000,
value: 0,
},
{
name: '香港特别行政区',
code: 810000,
value: 0,
},
{
name: '广东省',
code: 440000,
value: 0,
},
{
name: '河南省',
code: 410000,
value: 0,
},
{
name: '湖南省',
code: 430000,
value: 0,
},
{
name: '江西省',
code: 360000,
value: 0,
},
{
name: '四川省',
code: 510000,
value: 0,
},
{
name: '广西壮族自治区',
code: 450000,
value: 0,
},
{
name: '江苏省',
code: 320000,
value: 0,
},
{
name: '澳门特别行政区',
code: 820000,
value: 0,
},
{
name: '浙江省',
code: 330000,
value: 0,
},
{
name: '山东省',
code: 370000,
value: 0,
},
{
name: '青海省',
code: 630000,
value: 0,
},
{
name: '重庆市',
code: 500000,
value: 0,
},
{
name: '福建省',
code: 350000,
value: 0,
},
{
name: '湖北省',
code: 420000,
value: 0,
},
{
name: '西藏自治区',
code: 540000,
value: 0,
},
{
name: '台湾省',
code: 710000,
value: 100,
},
];
const StudentPostion: React.FC = () => {
const draw = () => {
/** scene这个实例一定要在dom渲染完成之后创建 */
const scene = new Scene({
/** 传入需要渲染的dom节点的id */
id: 'student-map',
/** 渲染的地图会有一个antv的logo,可以让其消失 */
logoVisible: false,
map: new Mapbox({
center: [116.2825, 39.9],
pitch: 0,
/** 其实这是一张世界地图,通过blank将除中国外的地方变为空白 */
style: 'blank',
zoom: 3,
minZoom: 0,
maxZoom: 10,
}),
});
scene.on('loaded', () => {
new CountryLayer(scene, {
/** 创建的数据,绑定到data字段进行渲染 */
data: ProvinceData,
joinBy: ['adcode', 'code'],
depth: 1,
/** 省界线颜色 */
provinceStroke: '#fff',
/** 省界线颜色宽度 */
provinceStrokeWidth: 1,
/** 市界线颜色 */
cityStroke: '#EBCCB4',
cityStrokeWidth: 1,
/** 地图文字颜色 */
label: {
/** 文字背景色 */
stroke: 'rgba(0,0,0,0)',
/** 文字颜色 */
color: 'transparent',
},
fill: {
color: {
/** field 字段传入数据里面的具体值的字段名称 */
field: 'value',
/** 根据值的大小会渲染以下的颜色,值越大,会渲染数组靠后的颜色 */
values: ['#BAE7FF', '#69C0FF', '#1890FF', '#0A73DA', '#004599'],
},
},
/** 鼠标放上去的提示框内容渲染,相当于echarts的tooltip */
popup: {
enable: true,
Html: (props: any) => {
return `<span>${
props.NAME_CHN}学生</span>:<span>${
props.value}人</span>`;
},
},
});
});
};
useEffect(() => {
draw();
}, []);
return (
<>
<div id="student-map" style={
{
height: '400px', padding: '20px 0 0 30px', fontWeight: 600 }}>
<div style={
{
fontSize: '18px' }}>学生地理位置分布统计图</div>
</div>
</>
);
};