如何小程序上绘制树状图
前言
现有的移动端图可视化技术有Antv旗下的F2、F6。F2主要专注于数据分析的统计图,而F6专注与各种场景的关系图。两者各有侧重。F6 是一个简单、易用、完备的移动端图可视化引擎,它在高定制能力的基础上,提供了一系列设计优雅、便于使用的图可视化解决方案。能帮助开发者搭建属于自己的图可视化、图分析、或图编辑器应用。如果您希望将内容通过流程图、知识图谱、思维导图等形式进行输出,并希望可以方便的实现对图的操控,那么建议您一定要尝试一下F6。
欢迎star和提交issue
什么是树图?
树图,表现形式如下,
具体原理可以参考 emr.cs.iit.edu/~reingold/t… ,由根节点不断的派生,形成一个树状结构,是一种可以很好表达层级关系的可视化方法。
举个例子:
什么场景下使用
名称 | 应用 |
---|---|
分解树 | 在人口调查中,将人口样本分解为人口统计信息 |
关键质量特性树 | 将顾客的需求转化为产品的可测量参数和过程特性 |
决策树或逻辑图 | 绘制出思维过程以便于决策 |
树干图 | 在产品的设计和开发阶段,用于识别产品的特性 |
故障树分析 | 识别故障的潜在原因 |
装配图 | 在制造过程中,描绘产品零部件的装配 |
方法-方法图 | 解决问题 |
工作或任务分析 | 识别一项工作或任务的要求 |
组织图 | 识别管理和汇报间的关联水平 |
过程决策程序图 | 确定潜在的问题和复杂计划中的对策 |
需求测量树 | 确定顾客、需求以及对测量产品或服务的测量 |
原因一原因图或five whys | 识别问题的根本原因 |
生产分类结构(WBS) | 识别项目的所有方面,分解成具体工作包水平 |
可见树图在实际场景中有很多应用,不论是在日常生活中,还是在生产中都有多种用途。我们最熟悉的脑图(mind map)也是树图的一种形式,
F6中如何绘制
演示示例可以参考f6.antv.vision/zh/docs/exa…
本节代码已经开源,感兴趣可以查看
支付宝中
首先安装
npm install @antv/f6 @antv/f6-alipay -S
index.json
{
"defaultTitle": "紧凑树",
"usingComponents": {
"f6-canvas": "@antv/f6-alipay/es/container/container"
}
}
index.js
import F6 from '@antv/f6';
import TreeGraph from '@antv/f6/dist/extends/graph/treeGraph';
import data from './data.js';
/**
* 紧凑树
*/
Page({
canvas: null,
ctx: null, // 延迟获取的2d context
renderer: '', // mini、mini-native等,F6需要,标记环境
isCanvasInit: false, // canvas是否准备好了
graph: null,
data: {
width: 375,
height: 600,
pixelRatio: 2,
forceMini: false,
},
onLoad() {
// 注册自定义树,节点等
F6.registerGraph('TreeGraph', TreeGraph);
// 同步获取window的宽高
const { windowWidth, windowHeight, pixelRatio } = my.getSystemInfoSync();
this.setData({
width: windowWidth,
height: windowHeight,
pixelRatio,
});
},
/**
* 初始化canvas回调,缓存获得的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;
// 创建F6实例
this.graph = new F6.TreeGraph({
context: this.ctx,
renderer: this.renderer,
width,
height,
pixelRatio,
fitView: true,
modes: {
default: [
{
type: 'collapse-expand',
onChange: function onChange(item, collapsed) {
const model = item.getModel();
model.collapsed = collapsed;
return true;
},
},
'drag-canvas',
'zoom-canvas',
],
},
defaultNode: {
size: 26,
anchorPoints: [
[0, 0.5],
[1, 0.5],
],
},
defaultEdge: {
type: 'cubic-horizontal',
},
layout: {
type: 'compactBox',
direction: 'LR',
getId: function getId(d) {
return d.id;
},
getHeight: function getHeight() {
return 16;
},
getWidth: function getWidth() {
return 16;
},
getVGap: function getVGap() {
return 10;
},
getHGap: function getHGap() {
return 100;
},
},
});
this.graph.node(function(node) {
return {
label: node.id,
labelCfg: {
offset: 10,
position: node.children && node.children.length > 0 ? 'left' : 'right',
},
};
});
this.graph.data(data);
this.graph.render();
this.graph.fitView();
},
});
index.axml
<f6-canvas
width="{{width}}"
height="{{height}}"
forceMini="{{forceMini}}"
pixelRatio="{{pixelRatio}}"
onTouchEvent="handleTouch"
onInit="handleInit"
></f6-canvas>
微信中
首先安装
npm install @antv/f6-wx -S
@antv/f6-wx
由于微信对npm包不是很友好,所以我们封装了 @antv/f6-wx
帮助用户简化操作。
index.json
{
"defaultTitle": "紧凑树",
"usingComponents": {
"f6-canvas": "@antv/f6-wx/canvas/canvas"
}
}
index.wxml
<f6-canvas
width="{{width}}"
height="{{height}}"
forceMini="{{forceMini}}"
pixelRatio="{{pixelRatio}}"
bind:onTouchEvent="handleTouch"
bind:onInit="handleInit"
></f6-canvas>
index.js
import F6 from '@antv/f6-wx';
import TreeGraph from '@antv/f6-wx/extends/graph/treeGraph';
import data from './data.js';
Page({
canvas: null,
ctx: null, // 延迟获取的2d context
renderer: '', // mini、mini-native等,F6需要,标记环境
isCanvasInit: false, // canvas是否准备好了
graph: null,
data: {
width: 375,
height: 600,
pixelRatio: 2,
forceMini: false,
},
onLoad() {
// 注册自定义树,节点等
F6.registerGraph('TreeGraph', TreeGraph);
// 同步获取window的宽高
const { windowWidth, windowHeight, pixelRatio } = wx.getSystemInfoSync();
this.setData({
width: windowWidth * pixelRatio,
height: windowHeight * pixelRatio,
pixelRatio,
});
},
/**
* 初始化canvas回调,缓存获得的context
* @param {*} ctx 绘图context
* @param {*} rect 宽高信息
* @param {*} canvas canvas对象,在render为mini时为null
* @param {*} renderer 使用canvas 1.0还是canvas 2.0,mini | mini-native
*/
handleInit(event) {
const { ctx, rect, canvas, renderer } = event.detail;
this.isCanvasInit = true;
this.ctx = ctx;
this.renderer = renderer;
this.canvas = canvas;
this.updateChart();
},
/**
* canvas派发的事件,转派给graph实例
*/
handleTouch(e) {
this.graph && this.graph.emitEvent(e.detail);
},
updateChart() {
const { width, height, pixelRatio } = this.data;
// 创建F6实例
this.graph = new F6.TreeGraph({
context: this.ctx,
renderer: this.renderer,
width,
height,
pixelRatio,
fitView: true,
modes: {
default: [
{
type: 'collapse-expand', // 点击后展开/收缩
onChange: function onChange(item, collapsed) {
const model = item.getModel();
model.collapsed = collapsed;
return true;
},
},
'drag-canvas',
'zoom-canvas',
],
},
defaultNode: {
size: 26,
anchorPoints: [
[0, 0.5],
[1, 0.5],
],
},
defaultEdge: {
type: 'cubic-horizontal',
},
layout: {
type: 'compactBox',
direction: 'LR',
getId: function getId(d) {
return d.id;
},
getHeight: function getHeight() {
return 16;
},
getWidth: function getWidth() {
return 16;
},
getVGap: function getVGap() {
return 10;
},
getHGap: function getHGap() {
return 100;
},
},
});
this.graph.node(function(node) {
return {
label: node.id,
labelCfg: {
offset: 10,
position: node.children && node.children.length > 0 ? 'left' : 'right',
},
};
});
this.graph.data(data);
this.graph.render();
this.graph.fitView();
},
});
作者:AntCredit
链接:https://juejin.cn/post/7011374414394556452