自定义绘图

<< Click to Display Table of Contents >>

当前位置:  制作可视化报告 > 制作图表 > 图表类型 

自定义绘图

复制链接

1. 概述

1.1 应用场景

自定义绘图组件,是一个支持完全自定义图表样式的组件,帮助用户实现定制化的可视化效果。

1.2 基本要求

图表

数据

自定义绘图

0个或多个数据列

2. 制作图表

自定义绘图组件支持用户自定义编写JS代码来实现图表绘制,系统内置了EchartsAntV_G2PlotAntV_G6,您可以直接调用代码库,相关代码的配置属性以及图表示例请前往官网查看。

2.1 新建自定义绘图组件

从右侧【组件】拖拽自定义绘图组件到画布中,如下图:

js1

2.2 给组件绑定数据

从数据列表中拖拽产品种类、产品名称2个数据列到数据绑定区:

js2

2.3 自定义JS代码

绑定完数据后,我们需要给组件自定义JS代码,以定义图表绘制规则,点击数据绑定区的“自定义JS代码”,在弹窗中进行配置:

js3

自定义JS代码配置:

【chart库】默认可以选择Echarts、AntV_G2Plot、AntV_G6,选择以后,在绘制时会直接调用对应代码库绘制图表。

【代码格式】选择完chart库后,需要选择JS代码格式,Echarts仅支持option格式,AntV_G2Plot、AntV_G6为完整代码,为保证正常绘图,代码格式与所选格式需保持一致。

【JS】在编辑区内输入JS代码,请参考下面的格式:

选择Echarts库时,代码格式为option部分,如下图:

js4

若要使用Echart绘制3D地球类图表,需要定义路径,如下图:

js5

注意:

请不要定义chartDom变量,产品已经定义了DOMid为$container,可能会都导致无法绘制到报告画布中,错误代码格式如下:

js6

正确写法:

js7

说明:

Echarts可以直接定义option部分,前面的引用import * as echarts from 'echarts'可以去掉。

从Echarts官网复制代码时,请将chartDom相关的变量注释掉,仪表组件示例代码:

js22

import * as echarts from 'echarts';

//var chartDom = document.getElementById('main');

//var myChart = echarts.init(chartDom);

var option;

option = {

 tooltip: {

   formatter: '{a} <br/>{b} : {c}%'

 },

 series: [

   {

     name: 'Pressure',

     type: 'gauge',

     detail: {

       formatter: '{value}'

     },

     data: [

       {

         value: 50,

         name: 'SCORE'

       }

     ]

   }

 ]

};

option && myChart.setOption(option);

选择AntV_G2Plot需要输入完整代码,可以参考官网文档说明,格式如下:

js8

基础条形图示例代码:

js23

import { Bar } from '@antv/g2plot';

const data = [

 { year: '1951 年', value: 38 },

 { year: '1952 年', value: 52 },

 { year: '1956 年', value: 61 },

 { year: '1957 年', value: 145 },

 { year: '1958 年', value: 48 },

];

const bar = new Bar('container', {

 data,

 xField: 'value',

 yField: 'year',

 seriesField: 'year',

 legend: {

   position: 'top-left',

 },

});

bar.render();

选择AntV_G6需要输入完整代码,可以参考官网文档说明,格式如下:

js9

自定义边示例代码:

js24

import G6 from '@antv/g6';

G6.registerEdge(

'line-arrow',

{

getPath(points) {

const startPoint = points[0];

const endPoint = points[1];

return [

['M', startPoint.x, startPoint.y],

['L', endPoint.x / 3 + (2 / 3) * startPoint.x, startPoint.y],

['L', endPoint.x / 3 + (2 / 3) * startPoint.x, endPoint.y],

['L', endPoint.x, endPoint.y],

];

},

getShapeStyle(cfg) {

const startPoint = cfg.startPoint;

const endPoint = cfg.endPoint;

const controlPoints = this.getControlPoints(cfg);

let points = [startPoint]; // the start point

if (controlPoints) {

points = points.concat(controlPoints);

}

points.push(endPoint);

const path = this.getPath(points);

const style = Object.assign(

{},

G6.Global.defaultEdge.style,

{

stroke: '#BBB',

lineWidth: 1,

path,

},

cfg.style,

);

return style;

},

},

'line',

);

const data = {

nodes: [

{

id: '7',

x: 150,

y: 100,

size: 40,

anchorPoints: [

[1, 0.5],

[1, 0],

],

},

{

id: '8',

x: 300,

y: 200,

size: 40,

anchorPoints: [

[0, 0.5],

[0, 1],

],

},

],

edges: [

{

source: '7',

target: '8',

sourceAnchor: 0,

targetAnchor: 0,

},

],

};

const container = document.getElementById($container);

const width = container.scrollWidth;

const height = container.scrollHeight || 500;

const graph = new G6.Graph({

container: $container,

width,

height,

fitCenter: true,

modes: {

default: ['drag-node', 'drag-canvas'],

},

defaultNode: {

type: 'circle',

style: {

fill: '#DEE9FF',

stroke: '#5B8FF9',

},

linkPoints: {

left: true,

right: true,

fill: '#fff',

stroke: '#1890FF',

size: 3,

},

},

defaultEdge: {

type: 'line-arrow',

style: {

stroke: '#F6BD16',

startArrow: {

path: 'M 0,0 L 12,6 L 9,0 L 12,-6 Z',

fill: '#F6BD16',

},

endArrow: {

path: 'M 0,0 L 12,6 L 9,0 L 12,-6 Z',

fill: '#F6BD16',

},

},

},

});

graph.data(data);

graph.render();

 

【Data】绑定的数据列会展示在Data区域,并按照绑定的顺序依次定义为column1、column2......,可以直接在代码中引用,例如绑定了市场级别、产品种类2列数据,如下图:

js10

【执行】输入完JS代码之后,点击代码编辑区右上角的“执行”按钮,会在右侧预览区域绘制图表,若代码存在错误会给出提示。

2.4 数据格式转换

我们可以在代码中直接引用绑定的Data,绑定数据列后,Data区域的数据格式参考上面的示例图;针对不同的图表,所需数据格式有所不同,您需要将格式转换为目标格式后使用。

1)Echart库引用方法:

直接引用列

当原始数据为data:[]格式时,如下

js32

可以修改data部分为data:options.column1,例如我们绑定了产品种类、利润两列,要用来绘制基础柱状图,代码如下:

js11

转换为键值对

Echarts里面部分图表示例的数据格式是键值对,漏斗图所需数据格式如下:

data: [

       { value: 60, name: 'Visit' },

       { value: 40, name: 'Inquiry' },

       { value: 20, name: 'Order' },

       { value: 80, name: 'Click' },

       { value: 100, name: 'Show' }

     ]

js25

假设依次绑定了数据列“产品种类”“销量”,需要将数据处理成键值对的格式以实现数据引用,转换格式方法:

options.data.map(i => ({value: i.column1, name: i.column2}))

引用数据后效果:

js26

转换为坐标点

绘制热力图时使用到的数据包含坐标点,格式如下:

js27

假设我们想对不同省份、市场的总成本做热力渲染,可以依次绑定这3列数据,在产品中数据结构如下:

js28

我们需要根据绑定的两个维度值自动生成坐标点,转换格式方法:

// 每个色块值是唯一的,指定数据列时需要去重

const hours = [...new Set(options.column1)];

const days = [...new Set(options.column2)];

//基于维度列将度量列转换成[0,0,1]格式的数据

const chartData = [];

hours.forEach((h, x) => {

options.column2.forEach((d, y) => {

const item = options.data.find(i => i.column1 == h && i.column2 == d);

item && chartData.push([x, y, item.column3]);

});

});

绘制效果:

js29

完整代码:

const hours = [...new Set(options.column1)];

const days = [...new Set(options.column2)];

// 每个色块值是唯一的,指定数据列时需要去重

const chartData = [];

hours.forEach((h, x) => {

options.column2.forEach((d, y) => {

const item = options.data.find(i => i.column1 == h && i.column2 == d);

item && chartData.push([x, y, item.column3]);

});

});

option = {

tooltip: {

position: 'top'

},

grid: {

height: '70%',

top: '10%',

left:'15%',

},

xAxis: {

type: 'category',

data: hours,

splitArea: {

show: true

}

},

yAxis: {

type: 'category',

data: days,

splitArea: {

show: true

}

},

visualMap: {

min: 0,

max: 50000,

calculable: false,

orient: 'horizontal',

left: 'center',

bottom: 10

},

series: [

{

name: 'Punch Card',

type: 'heatmap',

data: chartData,

label: {

show: true

},

emphasis: {

itemStyle: {

shadowBlur:10,

shadowColor: 'rgba(0, 0, 0, 0.5)'

}

}

}

]

};

转换为二维数组

Echarts里面绘制多个度量的柱状图时,通常将数据设置在dataset中,原始格式如下:

dataset: {

   // 提供一份数据。

   source: [

     ['Matcha Latte', 43.3, 85.8, 93.7],

     ['Milk Tea', 83.1, 73.4, 55.1],

     ['Cheese Cocoa', 86.4, 65.2, 82.5],

     ['Walnut Brownie', 72.4, 53.9, 39.1]

   ]

 },

数据一共包含一个维度列、三个度量列;

转换格式方法:

先在option前面添加

const source = options.data.map(o => {return Object.values(o);});

然后把source部分改为

source: [ [ "省份","总成本","销售额","利润" ],...source]//前面依次为绑定的四列数据

绘制效果:

js30

完整代码:

//请先依次绑定一个维度、三个度量列

const source = options.data.map(o => {

return Object.values(o);

});

option = {

legend: {},

tooltip: {},

dataset: {

// 提供一份数据。

source: [ [ "省份","总成本","销售额","利润" ],...source]

},

xAxis: { type: 'category' },

yAxis: {},

series: [{ type: 'bar' }, { type: 'bar' }, { type: 'bar' }]

};

2)AntV_G2Plot、AntV_G6库数据引用方法:

常见的数据格式如下:

const columnPlot = new Column('container', {

 data,

 xField: 'type',

 yField: 'sales',

 label: {

   // 可手动配置 label 数据标签位置

   position: 'middle', // 'top', 'bottom', 'middle',

   // 配置样式

   style: {

     fill: '#FFFFFF',

     opacity: 0.6,

   },

 },

直接修改data部分为data:options.data,对应轴绑定为'column1'、'column2'......

绘制效果:

js12

完整代码:

//请先依次绑定一个维度、一个度量

import { Column } from '@antv/g2plot';

const columnPlot = new Column($container, {

data:options.data,

xField: 'column1',

yField: 'column2',

label: {

// 可手动配置 label 数据标签位置

position: 'middle', // 'top', 'bottom', 'middle',

// 配置样式

style: {

fill: '#FFFFFF',

opacity: 0.6,

},

},

xAxis: {

label: {

autoHide: true,

autoRotate: false,

},

},

meta: {

type: {

alias: '类别',

},

sales: {

alias: '销售额',

},

},

});

columnPlot.render();

其余数据格式的转换方式参考Echarts的示例这里不再赘述。

注意:

为了保证图表正常在报告画布中,保存时会自动替换DOMid为变量$container,代码编辑时这'container'为$container两种写法都支持,保存后如下:

js13

除了引用数据外,您也可以在JS中引用图片文件,常见的方法包括以下几种:

若图片存放在本地服务器上,可以使用'image://' + '网络地址'实现引用;

例如:

将柱状图的柱子设置为本地图片样式,引用后执行效果如下图:

js17

用同样的方法可以引用其它网络图片,后面改成对应网络图片地址即可。

若图片不在服务器上,您可以先将图片转base64编码,使用'image://' + '图片路径base64'引用;

例如:

将本地茶杯图片转base64后作为标记样式,如下图:

js18

您也可以通过 'path://' 将图标设置为任意的矢量路径,路径图形会自适应调整为合适的大小,图片矢量路径可以从 Adobe Illustrator 等工具编辑导出。

例如:

通过矢量路径引入一个图片作为标记样式,如下图:

js19

2.5 chart库版本

在预览区域顶部,会显示当前运行的chart库版本,低版本有时会绘制失败,您可以下载最新的jar包,前往永洪安装目录\bihome\plugins\lib进行替换;

js14

2.6 扩展库引用

如果您需要引起其它第三方库,可以下载对应的jar包,放到永洪安装目录\bihome\plugins\lib下,在代码内添加引用即可。

antV_G2的引用库下载地址:https://unpkg.com/@antv/g2@4.2.2/dist/g2.min.js

引用其他库请到对应官网下载。

例如:

将下载好的g2.min.js直接放到安装目录\bihome\plugins\lib下:

js20

然后在js代码最前面添加引用:

options.loadDepends(["g2.min.js"],false);//第一个参数为您放到lib下的js文件名,false代表引用本地库

import { Chart } from '@antv/G2'; //注意这里的G2为大写,和引用的js文件里面保持一致

绘图效果:

js21

您在antV_G2的官网上看到好看的图表示例,可以复制相关代码,通过该方法引用本地库快速进行绘制。

如果您不想新增引用库到本地,也可以通过URL引用在线库;

例如:

引用在线的antV_G2,直接在js代码最前面添加引用:

options.loadDepends(["https://gw.alipayobjects.com/os/lib/antv/g2/4.0.9/dist/g2.min.js"], true);

import { Chart } from '@antv/G2';

绘制效果:

js31

说明:

引用在线库时需要保证网络连接正常,否则会绘制失败。

不同库的引用地址请前往对应官网查看。

2.7 自定义样式

您可以在代码编辑区内自定义图表样式,包括标题、图例、坐标系、缩放、提示等。

3. 图表的其他设置

3.1 图表组件的的通用操作与设置

具体参考下表中的参考文档。

设置内容

参考文档

组件绑定字段、移除字段

绑定字段、移除字段

替换组件数据集

替换数据集

查看与设置组件层级关系

组件层级

组件全屏模式下编辑

组件全屏

设置组件格式

格式

设置图表标题

图表元素-标题

3.2 图表组件的数据处理与分析

具体参考下表中的参考文档。

设置内容

参考文档

对绑定的维度字段进行排序

数据处理与分析- 排序

设置图表过滤

数据处理分析-过滤汇总过滤

对绑定的度量字段进行计算

数据处理与分析-同环比动态计算

设置图表的高亮、超链接、预警

数据处理与分析-预警

查看图表数据

数据处理分析-查看数据

3.3 永洪全局函数与图表组件的脚本、函数

具体参考下表中的参考文档。

设置内容

参考文档

永洪脚本的全局函数

永洪脚本的全局函数函数-基本函数日期时间函数财务函数文本函数数学函数逻辑函数统计函数聚合函数对象自定义全局函数

组件级别的脚本

组件级别的脚本

组件通用函数

组件级别的函数-通用

图表组件的函数

组件级别的函数-图表

4. 常见问题

请尽量使用Chrome、火狐浏览器,IE浏览器可能会由于兼容问题导致绘制失败。

由于Echarts存在新旧两个版本,部分新版本的代码写法在IE浏览器会绘制失败,如果您在Chrome、火狐浏览器能够正常绘制,IE浏览器中绘制失败,请调整代码写法。

如需将图表导出为图片、CSV等,请使用组件自带的导出功能,不要在JS代码中单独定义,否则可能会导致白屏,例如下图:

js15

如需导出,请使用组件自带的导出功能,如下图:

js16

数据资源引用时,可能会出现跨域的情况,Echarts官网示例中常使用ROOT_PATH+相对路径来引用数据,比如引用json:$.getJSON(ROOT_PATH + '/data/asset/data/life-expectancy-table.json'),由于Echarts的限制,您需要先将json数据文件下载到本地,放到安装目录\bihome下面,引用方式: $.getJSON('?proc=2&resource=life-expectancy-table.json'),如果放在了其他文件夹,以bihome为根目录把resource后面的路径改为相对路径即可。