天天看點

antv,圖表和地圖

前言

echarts是比較流行的圖示和地圖架構,文檔清晰,靈活,滿足各種自定義。衆多的api接口,讓使用者猶如大海撈針,每一個細節都需要通過api慢慢調整,耗費開發者大量的時間精力。

在這裡補充一種新的圖表地圖架構,雖然做得不如echarts強大,适合快速開發節奏,讓前端程式員在除了echarts以外還可以多一種選擇。

antv

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快速生成圖表

antv的優勢在于快速生成代碼,配置圖表的功能chartCub魔方(圖表魔方,圖表生成器)。

echarts自定義圖表,是先寫配置api才能看到生成圖表的樣式,而圖表魔方為使用者提供預覽圖表的功能,通過可視化界面,對圖表進行樣式配置并生成相應的代碼。

圖表魔方位址 https://chartcube.alipay.com/guide

這是未來前端發展的一種趨勢,可視化配置,會慢慢代替許多代碼的複制粘貼。雖然目前圖表魔方隻支援比較基礎的圖示配置,比較個性化的圖表還是需要使用echarts。

筆者隻用過G2和L7,其它内容暫不做展示,如果以後也有使用,會更新本篇部落格。

G2使用

安裝 @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;
           

L7地圖的使用

根據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>
    </>
  );
};

           

效果圖

antv,圖表和地圖

antv的使用大家還是自己去體驗吧。這裡能展示的内容隻是九牛一毛

繼續閱讀