## JavaScript自定义图表 利用大屏的自定义图表控件,编写JavaScript绘制自定义图表的过程与[报告](../4Analyze_data_and_visualize_it/javascript.html)相同,这里给一个echarts 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地图如下: ![map4.png](/uploads/projects/7.11_online/167946f36f26d9f0.png "map4.png") echarts图表控件不只能绘制echarts图表,实际上它有无尽的可能,你可以在里面绘制一个自己的表格,也可以引入外部插件,如d3,antv等可视化框架,完成你想要绘制的任何酷炫图表。下面以antv L7地理空间数据可视化框架为例,绘制一张[3D柱状地图](https://l7.antv.vision/zh/examples/point/column#column_dark): ``` 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](/uploads/projects/7.11_online/167946fd4f2df51e.gif "map5.gif") 需要注意的点是绘制非echarts时,需要手动在代码中监听图表的renderDone事件,保证有数能知道该自定义报表何时绘制完成,否则会影响该报表的导出截图、定时邮件功能;另外如果需要监听报表resize事件,可在代码中监听resize事件自行处理,以上2个事件在上述例子中均有代码实现说明。