将知识、内容转换为图的形式进行归纳输出,成为越来越主流的方式。使用图可视化技术可以帮助我们更好的整理日常面对的大量信息。而手机,作为我们携带率最高的设备,天然的是一个优秀的图可视化输出载体。
现有的移动端图可视化技术有Antv旗下的F2、F6。F2主要专注于数据分析的统计图,而F6专注与各种场景的关系图。两者各有侧重。F6 是一个简单、易用、完备的移动端图可视化引擎,它在高定制能力的基础上,提供了一系列设计优雅、便于使用的图可视化解决方案。能帮助开发者搭建属于自己的图可视化、图分析、或图编辑器应用。如果您希望将内容通过流程图、知识图谱、思维导图等形式进行输出,并希望可以方便的实现对图的操控,那么建议您一定要尝试一下F6。
欢迎star和提交issue
基本概念
对于图的分类,不同的角度会有不同的分类。我们从功能特点的角度,对图进行分类的话,可以分为以下几类
图的种类很多,但是都有一个共同的特点,就是都是由若干节点和边组成的。节点表示我们绘制的实体,而边表示实体之间的关系。举个例子,下图就是我们今天将要带大家绘制的环形弧线图。图中带英文的圆圈就是节点,表示一个特定的实体。而连接不同圆圈的弧线就是边,表示实体与实体间由联系。
所谓环形弧线图,环形,指节点围绕同一个圆心排列。而弧线,指节点与节点之间的边是弧线的形式表现。
如何使用F6绘制可视化图
那么我们应该如何通过F6来绘制这个看着很复杂的环形弧线图呢?首先可以想到,我们要给F6提供数据。我们要告诉F6,我们需要画哪些节点,哪些边,这些节点的名字,哪些节点之间有关系。具体在代码层面,我们需要提供以下结构的数据
{
nodes:[],
edges:[]
}
nodes是一个对象数组,里面的每一个对象都表示一个节点
edges是一个对象数组,里面的每一个对象都表示一条边
更具体一点,下面一段数据,就可以表示有“sea”和“water”两个节点,以及一条连接这两个节点的边。
{
"nodes": [
{
"id":"water"
},
{
"id":"sea"
}
],
"edges": [
{
"source":"water",
"target":"sea"
}
]
}
有了数据之后,我们就需要调用F6来进行绘图。这时候我们就需要引入数据,调用F6接口,并把数据给F6,让它帮我们画出想要的图。从代码层面的角度来看,我们需要在js文件中完成以下三件事:
新建实例:new F6.Graph( )来新建一个图的实例graph
传入数据:graph.data( ) 传入画图的数据
画图:graph.render( ) 进行绘制。
怎么说,是不是很简单!其实核心的部分也就在第一步,新建实例。在这一步需要传递一些参数,比如图是否居中,自定义点,自定义边,整个图的大小,使用的插件,布局等~,举个栗子🌰
this.graph = new F6.Graph({
context: this.context,
renderer: this.renderer,
width,
height,
pixelRatio,
fitView,
modes: {
default:['drag-canvas', 'drag-node']
}
defaultNode:{},
defaultEdge:{},
layout:{},
plugin:[]
})
上面就是一个简单的新建图的实例的例子,参数看着有点多,但是每一个都非常好理解:
width和height就是设置画出来的图的宽和高
pixelRatio就是缩放比例
fitView, 适应屏幕
modes 图的拖拽模式,如可选拖拽canvas、拖拽节点
defaultnode:默认的节点样式
defaultEdge:默认的边样式
layout,设置整个图的布局
plugin,使用拓展的插件功能,如时间轴,鱼眼放大镜等拓展功能
新建好实例后,我们给这个实例传递我们前面写好的数据。然后再调用实例的render方法,就能够将我们想要的图画出来了!
前面介绍了使用F6画图的一些核心步骤。可以说看到这里,F6画图的流程你都以及掌握了。接下来我们就进入实战环节,将我们之前立的flag:环形弧线图给实现出来!
支付宝小程序上使用F6
我们以支付宝小程序为例,首先我们在支付宝小程序开发者工具上,新建一个支付宝小程序的应用:选择支付宝小程序
选择一个最简单的空白模版,并为这个项目起一个响亮的名字,名字最好使用英文命名
完成之后,我们就能得到一个支付宝小程序的空白模版了。接着,我们去控制台,使用npm安装两个需要的包:@antv/f6
和@antv/f6-alipay
npm init
npm install @antv/f6
npm install @antv/f6-alipay
安装好之后,就可以开始写代码啦~
我们在pages/ 下新建一个文件夹 circularArcDiagram/。并且创建一些必要的文件。文件的结构如下:
pages/ circularArcDiagram/ index.js index.axml index.acss index.json data.js
绘制一个图大概需要的文件就是上面的5个文件。 没错,我们这次要画一个环形弧线图,最终的实现目录如下:
index.axml
我们首先来看一下index.axml。F6绘图是绘制在canavs上的,我们需要设定canvas画布的宽,高,放缩比例,回调函数等基本信息。
<f6-canvas
width="{{width}}"
height="{{height}}"
forceMini="{{forceMini}}"
pixelRatio="{{pixelRatio}}"
onTouchEvent="handleTouch"
onInit="handleInit"
></f6-canvas>
index.css
然后就是平平无奇的css,这个主要是控制页面的一个背景颜色和绘制出来的canvas图的padding
page {
background-color: #f7f7f7;
border: 1px solid rgba(0,0,0,0);
box-sizing: border-box;
}
.page-section-demo {
padding: 32rpx;
}
index.json
index.json: 这里主要是控制使用的组件,我们在axml中使用的就是在这里引入的。
{
"defaultTitle": "环形弧线图",
"usingComponents": {
"f6-canvas": "@antv/f6-alipay/es/container/container"
}
}
index.js
最后是控制主要逻辑的index.js文件,由于js文件是我们使用F6的大头,我们一点点说 首先是我们先前提到的,使用F6的三部曲,new、data、render
//new,新建F6实例
this.graph = new F6.Graph({
context: this.ctx,
renderer: this.renderer,
width,
height,
pixelRatio,
linkCenter: true,
fitView: true,
modes: {
default: [
{
type: 'edge-tooltip',
formatText: function formatText(model) {
const text = `source: ${model.sourceName}<br/> target: ${model.targetName}`;
return text;
},
},
],
},
defaultNode: {
style: {
opacity: 0.8,
lineWidth: 1,
stroke: '#999',
},
},
defaultEdge: {
size: 1,
color: '#e2e2e2',
style: {
opacity: 0.6,
lineAppendWidth: 3,
},
},
});
//data,处理数据
this.graph.data(data)
//render,绘图
this.render()
以上就是主体结构,完整的代码如下:
import F6 from '@antv/f6';
import data from './data';
import mds from '@antv/f6/dist/extends/layout/mdsLayout';
/**
* 环形弧线图
*/
Page({
canvas: null,
ctx: null,
renderer: '', // mini、mini-native等,F6需要,标记环境
isCanvasInit: false, // canvas是否准备好了
graph: null,
data: {
width: 375,
height: 600,
pixelRatio: 2,
forceMini: false,
},
onLoad() {
// 注册布局
F6.registerLayout('mds', mds);
// 同步获取window的宽高
const { windowWidth, windowHeight, pixelRatio } = my.getSystemInfoSync();
this.setData({
width: windowWidth,
height: windowHeight,
pixelRatio,
});
},
/**
* 初始化cnavas回调,缓存获得的context
* @param {*} ctx 绘图context
* @param {*} rect 宽高信息
* @param {*} canvas canvas对象,在render为mini时为null
* @param {*} renderer 使用canvas 1.0还是canvas 2.0,mini | mini-native
*/
handleInit(ctx, rect, canvas, renderer) {
this.isCanvasInit = true;
this.ctx = ctx;
this.renderer = renderer;
this.canvas = canvas;
this.updateChart();
},
/**
* canvas派发的事件,转派给graph实例
*/
handleTouch(e) {
this.graph && this.graph.emitEvent(e);
},
updateChart() {
const { width, height, pixelRatio } = this.data;
const colors = [
'rgb(91, 143, 249)',
'rgb(90, 216, 166)',
'rgb(93, 112, 146)',
'rgb(246, 189, 22)',
'rgb(232, 104, 74)',
'rgb(109, 200, 236)',
'rgb(146, 112, 202)',
'rgb(255, 157, 77)',
'rgb(38, 154, 153)',
'rgb(227, 137, 163)',
];
// 创建F6实例
this.graph = new F6.Graph({
context: this.ctx,
renderer: this.renderer,
width,
height,
pixelRatio,
linkCenter: true,
fitView: true,
modes: {
default: [
{
type: 'edge-tooltip',
formatText: function formatText(model) {
const text = `source: ${model.sourceName}<br/> target: ${model.targetName}`;
return text;
},
},
],
},
defaultNode: { //默认节点样式
style: {
opacity: 0.8,
lineWidth: 1,
stroke: '#999',
},
},
defaultEdge: { //默认边样式
size: 1,
color: '#e2e2e2',
style: {
opacity: 0.6,
lineAppendWidth: 3,
},
},
});
// 处理数据
function scaleNodeProp(nodes, propName, refPropName, dataRange, outRange) {
const outLength = outRange[1] - outRange[0];
const dataLength = dataRange[1] - dataRange[0];
nodes.forEach(function(n) {
n[propName] = ((n[refPropName] - dataRange[0]) * outLength) / dataLength + outRange[0];
});
}
const origin = [width / 2, height / 2];
const radius = width < height ? width / 3 : height / 3;
const { edges } = data;
const { nodes } = data;
const nodeMap = new Map();
const clusterMap = new Map();
let clusterId = 0;
const n = nodes.length;
const angleSep = (Math.PI * 2) / n;
nodes.forEach(function(node, i) {
const angle = i * angleSep;
node.x = radius * Math.cos(angle) + origin[0];
node.y = radius * Math.sin(angle) + origin[1];
node.angle = angle;
nodeMap.set(node.id, node);
// cluster
if (node.cluster && clusterMap.get(node.cluster) === undefined) {
clusterMap.set(node.cluster, clusterId);
clusterId++;
}
const id = clusterMap.get(node.cluster);
if (node.style) {
node.style.fill = colors[id % colors.length];
} else {
node.style = {
fill: colors[id % colors.length],
};
}
// label
node.label = node.name;
node.labelCfg = {
position: 'center',
style: {
rotate: angle,
rotateCenter: 'lefttop',
textAlign: 'start',
},
};
});
edges.forEach((edge) => {
edge.type = 'quadratic';
const source = nodeMap.get(edge.source);
const target = nodeMap.get(edge.target);
edge.controlPoints = [
{
x: origin[0],
y: origin[1],
},
];
edge.color = source.style.fill;
edge.sourceName = source.name;
edge.targetName = target.name;
});
// map the value to node size
let maxValue = -9999;
let minValue = 9999;
nodes.forEach(function(k) {
if (maxValue < k.value) maxValue = k.value;
if (minValue > k.value) minValue = k.value;
});
const sizeRange = [3, 30];
const sizeDataRange = [minValue, maxValue];
scaleNodeProp(nodes, 'size', 'value', sizeDataRange, sizeRange);
this.graph.data(data);
this.graph.render();
this.graph.fitView();
},
});
data.json
最后,本次绘图使用的数据如下:
export default {
nodes: [
{
id: '0',
name: 'analytics.cluster',
cluster: 'analytics',
value: 21,
},
{
id: '1',
name: 'analytics.graph',
cluster: 'analytics',
value: 34,
},
{
id: '2',
name: 'analytics.optimization',
cluster: 'analytics',
value: 8,
},
{
id: '3',
name: 'animate',
cluster: 'animate',
value: 40,
},
{
id: '4',
name: 'animate.interpolate',
cluster: 'animate',
value: 18,
},
{
id: '5',
name: 'data.converters',
cluster: 'data',
value: 25,
},
{
id: '6',
name: 'data',
cluster: 'data',
value: 10,
},
{
id: '7',
name: 'display',
cluster: 'display',
value: 4,
},
{
id: '8',
name: 'flex',
cluster: 'flex',
value: 6,
},
{
id: '9',
name: 'physics',
cluster: 'physics',
value: 22,
},
{
id: '10',
name: 'query',
cluster: 'query',
value: 67,
},
{
id: '11',
name: 'query.methods',
cluster: 'query',
value: 71,
},
{
id: '12',
name: 'scale',
cluster: 'scale',
value: 33,
},
{
id: '13',
name: 'util',
cluster: 'util',
value: 23,
},
{
id: '14',
name: 'util.heap',
cluster: 'util',
value: 2,
},
{
id: '15',
cluster: 'util',
name: 'util.math',
value: 2,
},
{
id: '16',
name: 'util.palette',
cluster: 'util',
value: 5,
},
{
id: '17',
name: 'vis.axis',
cluster: 'vis',
value: 24,
},
{
id: '18',
name: 'vis.controls',
cluster: 'vis',
value: 28,
},
{
id: '19',
name: 'vis.data',
cluster: 'vis',
value: 70,
},
{
id: '20',
name: 'vis.data.render',
cluster: 'vis',
value: 11,
},
{
id: '21',
name: 'vis.events',
cluster: 'vis',
value: 8,
},
{
id: '22',
name: 'vis.legend',
cluster: 'vis',
value: 27,
},
{
id: '23',
name: 'vis.operator.distortion',
cluster: 'vis',
value: 9,
},
{
id: '24',
name: 'vis.operator.encoder',
cluster: 'vis',
value: 30,
},
{
id: '25',
name: 'vis.operator.filter',
cluster: 'vis',
value: 17,
},
{
id: '26',
name: 'vis.operator',
cluster: 'vis',
value: 27,
},
{
id: '27',
name: 'vis.operator.label',
cluster: 'vis',
value: 18,
},
{
id: '28',
name: 'vis.operator.layout',
cluster: 'vis',
value: 91,
},
{
id: '29',
name: 'vis',
cluster: 'vis',
value: 13,
},
],
edges: [
{
source: '10',
target: '10',
sourceWeight: 61,
targetWeight: 61,
},
{
source: '11',
target: '11',
sourceWeight: 39,
targetWeight: 39,
},
{
source: '3',
target: '3',
sourceWeight: 30,
targetWeight: 30,
},
{
source: '19',
target: '19',
sourceWeight: 26,
targetWeight: 26,
},
{
source: '13',
target: '13',
sourceWeight: 23,
targetWeight: 23,
},
{
source: '9',
target: '9',
sourceWeight: 22,
targetWeight: 22,
},
{
source: '12',
target: '12',
sourceWeight: 19,
targetWeight: 19,
},
{
source: '28',
target: '19',
sourceWeight: 34,
targetWeight: 0,
},
{
source: '4',
target: '4',
sourceWeight: 16,
targetWeight: 16,
},
{
source: '11',
target: '10',
sourceWeight: 32,
targetWeight: 0,
},
{
source: '28',
target: '28',
sourceWeight: 14,
targetWeight: 14,
},
{
source: '18',
target: '18',
sourceWeight: 12,
targetWeight: 12,
},
{
source: '26',
target: '26',
sourceWeight: 11,
targetWeight: 11,
},
{
source: '28',
target: '13',
sourceWeight: 20,
targetWeight: 0,
},
{
source: '5',
target: '6',
sourceWeight: 17,
targetWeight: 2,
},
{
source: '19',
target: '13',
sourceWeight: 17,
targetWeight: 0,
},
{
source: '17',
target: '17',
sourceWeight: 7,
targetWeight: 7,
},
{
source: '6',
target: '6',
sourceWeight: 7,
targetWeight: 7,
},
{
source: '12',
target: '13',
sourceWeight: 14,
targetWeight: 0,
},
{
source: '1',
target: '19',
sourceWeight: 14,
targetWeight: 0,
},
{
source: '5',
target: '5',
sourceWeight: 7,
targetWeight: 7,
},
{
source: '21',
target: '19',
sourceWeight: 6,
targetWeight: 4,
},
{
source: '25',
target: '19',
sourceWeight: 10,
targetWeight: 0,
},
{
source: '0',
target: '0',
sourceWeight: 5,
targetWeight: 5,
},
{
source: '3',
target: '13',
sourceWeight: 9,
targetWeight: 0,
},
{
source: '20',
target: '19',
sourceWeight: 5,
targetWeight: 4,
},
{
source: '19',
target: '12',
sourceWeight: 9,
targetWeight: 0,
},
{
source: '0',
target: '19',
sourceWeight: 8,
targetWeight: 0,
},
{
source: '24',
target: '19',
sourceWeight: 8,
targetWeight: 0,
},
{
source: '22',
target: '22',
sourceWeight: 4,
targetWeight: 4,
},
{
source: '24',
target: '24',
sourceWeight: 4,
targetWeight: 4,
},
{
source: '26',
target: '3',
sourceWeight: 7,
targetWeight: 0,
},
{
source: '24',
target: '16',
sourceWeight: 7,
targetWeight: 0,
},
{
source: '16',
target: '16',
sourceWeight: 3,
targetWeight: 3,
},
{
source: '10',
target: '13',
sourceWeight: 6,
targetWeight: 0,
},
{
source: '7',
target: '7',
sourceWeight: 3,
targetWeight: 3,
},
{
source: '22',
target: '13',
sourceWeight: 6,
targetWeight: 0,
},
{
source: '20',
target: '20',
sourceWeight: 3,
targetWeight: 3,
},
{
source: '1',
target: '26',
sourceWeight: 6,
targetWeight: 0,
},
{
source: '27',
target: '19',
sourceWeight: 6,
targetWeight: 0,
},
{
source: '28',
target: '12',
sourceWeight: 6,
targetWeight: 0,
},
{
source: '22',
target: '7',
sourceWeight: 6,
targetWeight: 0,
},
{
source: '28',
target: '3',
sourceWeight: 6,
targetWeight: 0,
},
{
source: '17',
target: '7',
sourceWeight: 5,
targetWeight: 0,
},
{
source: '26',
target: '13',
sourceWeight: 5,
targetWeight: 0,
},
{
source: '27',
target: '13',
sourceWeight: 5,
targetWeight: 0,
},
{
source: '1',
target: '13',
sourceWeight: 5,
targetWeight: 0,
},
{
source: '1',
target: '3',
sourceWeight: 5,
targetWeight: 0,
},
{
source: '26',
target: '29',
sourceWeight: 3,
targetWeight: 2,
},
{
source: '22',
target: '16',
sourceWeight: 5,
targetWeight: 0,
},
{
source: '18',
target: '21',
sourceWeight: 4,
targetWeight: 0,
},
{
source: '22',
target: '12',
sourceWeight: 4,
targetWeight: 0,
},
{
source: '23',
target: '23',
sourceWeight: 2,
targetWeight: 2,
},
{
source: '17',
target: '29',
sourceWeight: 2,
targetWeight: 2,
},
{
source: '28',
target: '17',
sourceWeight: 4,
targetWeight: 0,
},
{
source: '15',
target: '15',
sourceWeight: 2,
targetWeight: 2,
},
{
source: '17',
target: '12',
sourceWeight: 4,
targetWeight: 0,
},
{
source: '27',
target: '27',
sourceWeight: 2,
targetWeight: 2,
},
{
source: '14',
target: '14',
sourceWeight: 2,
targetWeight: 2,
},
{
source: '18',
target: '29',
sourceWeight: 3,
targetWeight: 1,
},
{
source: '25',
target: '26',
sourceWeight: 3,
targetWeight: 0,
},
{
source: '28',
target: '9',
sourceWeight: 3,
targetWeight: 0,
},
{
source: '27',
target: '7',
sourceWeight: 3,
targetWeight: 0,
},
{
source: '24',
target: '12',
sourceWeight: 3,
targetWeight: 0,
},
{
source: '17',
target: '13',
sourceWeight: 3,
targetWeight: 0,
},
{
source: '18',
target: '13',
sourceWeight: 3,
targetWeight: 0,
},
{
source: '20',
target: '13',
sourceWeight: 3,
targetWeight: 0,
},
{
source: '0',
target: '13',
sourceWeight: 3,
targetWeight: 0,
},
{
source: '24',
target: '13',
sourceWeight: 3,
targetWeight: 0,
},
{
source: '19',
target: '6',
sourceWeight: 3,
targetWeight: 0,
},
{
source: '29',
target: '3',
sourceWeight: 3,
targetWeight: 0,
},
{
source: '25',
target: '3',
sourceWeight: 3,
targetWeight: 0,
},
{
source: '24',
target: '3',
sourceWeight: 3,
targetWeight: 0,
},
{
source: '17',
target: '3',
sourceWeight: 3,
targetWeight: 0,
},
{
source: '0',
target: '15',
sourceWeight: 2,
targetWeight: 0,
},
{
source: '28',
target: '26',
sourceWeight: 2,
targetWeight: 0,
},
{
source: '24',
target: '26',
sourceWeight: 2,
targetWeight: 0,
},
{
source: '16',
target: '13',
sourceWeight: 2,
targetWeight: 0,
},
{
source: '1',
target: '14',
sourceWeight: 2,
targetWeight: 0,
},
{
source: '29',
target: '21',
sourceWeight: 2,
targetWeight: 0,
},
{
source: '21',
target: '21',
sourceWeight: 1,
targetWeight: 1,
},
{
source: '29',
target: '19',
sourceWeight: 2,
targetWeight: 0,
},
{
source: '19',
target: '14',
sourceWeight: 2,
targetWeight: 0,
},
{
source: '4',
target: '13',
sourceWeight: 2,
targetWeight: 0,
},
{
source: '19',
target: '15',
sourceWeight: 2,
targetWeight: 0,
},
{
source: '8',
target: '17',
sourceWeight: 2,
targetWeight: 0,
},
{
source: '2',
target: '13',
sourceWeight: 2,
targetWeight: 0,
},
{
source: '18',
target: '19',
sourceWeight: 2,
targetWeight: 0,
},
{
source: '1',
target: '1',
sourceWeight: 1,
targetWeight: 1,
},
{
source: '23',
target: '17',
sourceWeight: 2,
targetWeight: 0,
},
{
source: '23',
target: '19',
sourceWeight: 2,
targetWeight: 0,
},
{
source: '0',
target: '3',
sourceWeight: 2,
targetWeight: 0,
},
{
source: '18',
target: '3',
sourceWeight: 2,
targetWeight: 0,
},
{
source: '19',
target: '3',
sourceWeight: 2,
targetWeight: 0,
},
{
source: '29',
target: '13',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '8',
target: '29',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '21',
target: '3',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '22',
target: '3',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '3',
target: '4',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '2',
target: '29',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '22',
target: '19',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '23',
target: '3',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '2',
target: '26',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '2',
target: '19',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '26',
target: '19',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '2',
target: '17',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '27',
target: '3',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '5',
target: '13',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '2',
target: '12',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '28',
target: '20',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '18',
target: '28',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '23',
target: '21',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '8',
target: '6',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '2',
target: '3',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '1',
target: '29',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '23',
target: '28',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '6',
target: '13',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '25',
target: '13',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '8',
target: '7',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '7',
target: '13',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '27',
target: '26',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '18',
target: '7',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '0',
target: '26',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '19',
target: '7',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '8',
target: '19',
sourceWeight: 1,
targetWeight: 0,
},
{
source: '28',
target: '29',
sourceWeight: 1,
targetWeight: 0,
},
],
};
微信小程序
微信小程序和支付宝小程序的代码基本是一致的。对于在微信小程序上使用F6画图,大家可以参考我们写好的一些demos:github.com/antvis/F6/t…
对于更加丰富的图感兴趣,可以访问官网:f6.antv.vision/ 或者github:github.com/antvis/F6
作者:AntCredit
链接:https://juejin.cn/post/7012161348293525534
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
共同学习,写下你的评论
评论加载中...
作者其他优质文章