1. 概述

利用大屏的自定义图表控件,编写JavaScript绘制自定义图表的过程与报告相同,这里给一个echarts 3D地图的案例。
JavaScript自定义图表 - 图1

2. 3D地图

将经纬度数据、想要展示的度量值,和地理坐标对应的城市名称维度拖入数据面板,然后利用外部请求获取地理位置信息,加上刚刚引入的数据,通过echarts gl绘制如下3D地图:

var barDataSet = dataSet.map(function (dataItem) {
    return [dataItem[0], dataItem[1], Math.sqrt(dataItem[2])];
});
var maxValue = Math.max(...barDataSet.map(d => d[2]));
window.top.fetch('https://ydcdn.nosdn.127.net/echarts/assets/map/json/china.json').then(e => e.json()).then(chinaJson => {
    echarts.registerMap('china', chinaJson);
    myChart.setOption({
        backgroundColor: 'transparent',
        geo3D: {
            map: 'china',
            shading: 'lambert',
            label: {
                show: true,
                textStyle: {
                    color: '#fff', //地图初始化区域字体颜色
                    fontSize: 12,
                    opacity: 1,
                    backgroundColor: 'rgba(0,0,0,0)'
                },
            },
            light: {
                main: {
                    intensity: 3,
                    shadow: true,
                    shadowQuality: 'high',
                    alpha: 30
                },
                ambient: {
                    intensity: 0.3
                },
            },
            viewControl: {
                distance: 80,
                center: [0, -10, 0],
                panMouseButton: 'left',
                rotateMouseButton: 'right'
            },
            groundPlane: {
                show: false,
                color: '#999'
            },
            postEffect: {
                enable: true,
                bloom: {
                    enable: false
                },
                SSAO: {
                    radius: 1,
                    intensity: 1,
                    enable: true
                },
                depthOfField: {
                    enable: false,
                    focalRange: 10,
                    blurRadius: 10,
                    fstop: 1
                }
            },
            temporalSuperSampling: {
                enable: true
            },
            itemStyle: {
                color: '#222535',
                borderWidth: 1,
                borderColor: '#4B516D',
            },

            regionHeight: 2
        },
        visualMap: {
            max: maxValue,
            calculable: true,
            realtime: false,
            inRange: {
                color: ['#0B1F4C', '#303369', '#3D429A', '#A02B3B', '#C8352C', '#D04E32', '#D76638', '#E0823F', '#E89D46', '#EDAD49', '#F6C750']
            },
            outOfRange: {
                colorAlpha: 0
            }
        },
        series: [{
            type: 'bar3D',
            coordinateSystem: 'geo3D',
            shading: 'lambert',
            data: barDataSet,
            barSize: 0.5,
            minHeight: 0.2,
            silent: false,
            itemStyle: {
                color: 'orange'
            },
            emphasis: {
                label: {
                    show: true,
                    formatter: p => dataSet[p.dataIndex][3] + ': ' + p.data[2]
                }
            }
        }]
    });

})

绘制完成的3D地图如下:

JavaScript自定义图表 - 图2

3. 3D柱状地图

echarts图表控件不只能绘制echarts图表,实际上它有无尽的可能,你可以在里面绘制一个自己的表格,也可以引入外部插件,如d3,antv等可视化框架,完成你想要绘制的任何酷炫图表。下面以antv L7地理空间数据可视化框架为例,绘制一张3D柱状地图

const script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://unpkg.com/@antv/l7'; // 引入antv L7框架
document.getElementsByTagName('head')[0].appendChild(script);
script.onload = function () {
    const map = document.querySelector('#main');
    map.style = 'position:absolute;top:0;bottom:0;width:100%;'
    emitter.emit('renderDone');
    const scene = new L7.Scene({
      id: 'main',
      map: new L7.GaodeMap({
        pitch: 35.210526315789465,
        style: 'dark',
        center: [ 104.288144, 31.239692 ],
        zoom: 4.4
      })
    });
    scene.on('loaded', () => emitter.emit('renderDone')); // 图表加载完成后手动触发图表renderDone
    fetch('https://gw.alipayobjects.com/os/rmsportal/oVTMqfzuuRFKiDwhPSFL.json')
      .then(res => res.json())
      .then(data => {
        const pointLayer = new L7.PointLayer({})
          .source(data.list, {
            parser: {
              type: 'json',
              x: 'j',
              y: 'w'
            }
          })
          .shape('cylinder')
          .size('t', function(level) {
            return [ 1, 2, level * 2 + 20 ];
          })
          .active(true)
          .color('t', [
            '#094D4A',
            '#146968',
            '#1D7F7E',
            '#289899',
            '#34B6B7',
            '#4AC5AF',
            '#5FD3A6',
            '#7BE39E',
            '#A1EDB8',
            '#CEF8D6'
          ])
          .style({
            opacity: 1.0
          });
        scene.addLayer(pointLayer);
      });
}
emitter.on('resize', () => {
    // 在这里处理报表resize事件
});

绘制完成的3D地图如下:
map5.gif

需要注意的点是绘制非echarts时,需要手动在代码中监听图表的renderDone事件,保证有数能知道该自定义报表何时绘制完成,否则会影响该报表的导出截图、定时邮件功能;另外如果需要监听报表resize事件,可在代码中监听resize事件自行处理,以上2个事件在上述例子中均有代码实现说明。