export some plugin config

This commit is contained in:
huangtong.ht 2018-09-17 22:22:42 +08:00
parent 756e8f187f
commit 2f36d5f8e7
12 changed files with 723 additions and 60 deletions

View File

@ -85,7 +85,7 @@ iframe {
#chart-panel {
flex: 1;
overflow: hidden;
padding: 1rem;
padding: 0;
-webkit-transform: translateZ(0);
transform: translateZ(0);
will-change: scroll-position;

View File

@ -45,7 +45,7 @@
<textarea name="code" id="code"></textarea>
</div>
</div>
<div id="resize-handler"></div>
<div id="resize-handler" style="display:none;"></div>
<div id="chart-panel" class="preview"></div>
</div>
</div>

View File

@ -14,43 +14,184 @@
<body>
<div id="mountNode"></div>
<script>
const data = {
roots: [{
label: 'root',
children: [{
label: 'child1',
console.log(G6.version);
G6.registerNode('card', {
collapseButtonUrl:
'https://gw.alipayobjects.com/zos/rmsportal/GGzWwlTjflbJHmXhjMXg.svg',
expandButtonUrl:
'https://gw.alipayobjects.com/zos/rmsportal/DzWdTiwanggjaWKwcnWZ.svg',
draw(item) {
const group = item.getGraphicGroup();
const { main, value, percent, type, collapsed, children } = item.getModel();
const width = 170;
const height = 80;
const buttonWidth = 14;
const buttonHeight = 14;
let button = '';
if (children && children.length > 0) {
button =
'<img class="ce-button" src=' +
(collapsed ? this.expandButtonUrl : this.collapseButtonUrl) +
'>';
}
const html = G6.Util.createDOM(`
<div class="card-container">
<h1 class="main-text">${main}</h1>
<p>
<span class="value-text">${value}</span>
<span class="percent-text">${percent}</span>
</p>
</div>
`);
const keyShape = group.addShape('dom', {
attrs: {
x: 0,
y: 0,
width,
height,
html,
},
});
group.addShape('dom', {
attrs: {
x: width / 2 - buttonWidth / 2,
y: height - buttonHeight + 2,
width: buttonWidth,
height: buttonHeight,
html: button,
},
});
return group;
},
anchor: [[0.5, 0], [0.5, 1]],
});
const data = {
roots: [
{
main: '主指标一',
value: 123111,
percent: '100%',
type: '1',
children: [
{
main: '指标 1',
value: 12312,
percent: '39%',
type: '2',
children: [
{
label: 'child\n1.1'
}
]
}, {
label: 'child2'
}]
}]
};
const tree = new G6.Tree({
container: 'mountNode',
width: 500,
height: 500,
fitView: 'cc',
animate: true,
plugins: [new G6.Plugins['tool.highlightSubgraph']()]
});
tree.read(data);
tree.on('node:mouseenter', evt => {
console.log('node:mouseenter');
tree.highlightSubgraph([ evt.item ]);
});
tree.on('node:mouseleave', () => {
console.log('node:mouseleave');
tree.unhighlightGraph();
});
tree.on('node:click', ev => {
const item = ev.item;
const model = item.getModel();
if(model.collapsed){
main: '指标 1.1',
value: 111,
percent: '90%',
type: '3',
children: [
{
main: '指标 1.11',
value: 111,
percent: '90%',
type: '113',
},
{
main: '指标 1.12',
value: 111,
percent: '90%',
type: '14',
},
],
},
{
main: '指标 1.2',
value: 111,
percent: '90%',
type: '4',
children: [
{
main: '指标 1.21',
value: 111,
percent: '90%',
type: '5',
},
{
main: '指标 1.22',
value: 111,
percent: '90%',
type: '6',
},
{
main: '指标 1.23',
value: 111,
percent: '90%',
type: '7',
},
{
main: '指标 1.24',
value: 111,
percent: '90%',
type: '8',
},
],
},
{
main: '指标 1.3',
value: 111,
percent: '90%',
type: '9',
},
{
main: '指标 1.4',
value: 111,
percent: '90%',
type: '10',
},
],
},
{
main: '指标 2',
value: 12312,
percent: '79%',
type: '11',
},
{
main: '指标 3',
value: 12312,
percent: '79%',
type: '12',
},
],
},
],
};
const tree = new G6.Tree({
container: 'mountNode',
height: 500,
renderer: 'svg',
layout: new G6.Layouts.CompactBoxTree({
// direction: 'LR', // 方向LR/RL/H/TB/BT/V
getHGap: function getHGap() /* d */ {
// 横向间距
return 20;
},
getVGap: function getVGap() /* d */ {
// 竖向间距
return 24;
},
direction: 'TB',
}),
fitView: 'tl',
});
tree.node({
shape: 'card',
});
tree.edge({
shape: 'polyline',
});
tree.on('node:click', ev => {
const { domEvent, item } = ev;
const { target } = domEvent;
const { collapsed, type } = item.getModel();
const parent = item.getParent();
if (target.className === 'ce-button') {
if (collapsed) {
tree.update(item, {
collapsed: false,
});
@ -59,7 +200,22 @@
collapsed: true,
});
}
});
} else {
// 点击展开某个节点 同级其他节点收起
const children = parent && parent.getModel().children;
if (children && children.length > 0 && type) {
const isHideArr = children.filter(elem => type !== elem.type);
const isShowArr = children.filter(elem => type === elem.type);
isHideArr.forEach(element => {
tree.update(element.id, { collapsed: true });
});
isShowArr.forEach(element => {
tree.update(element.id, { collapsed: false });
});
}
}
});
tree.read(data);
</script>
</body>
</html>

111
demos/yunqi-1-dark.html Normal file
View File

@ -0,0 +1,111 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="./assets/jquery-3.2.1.min.js"></script>
<script src="../build/g6.js"></script>
<script src="../build/plugins.js"></script>
<title>云栖 demo 1</title>
</head>
<style>
body{
background: #2E2E2E;
}
</style>
<body>
<div id="mountNode"></div>
<script>
$.getJSON('./assets/data/usa-president.json', table => {
setTimeout(()=>{
// table.forEach(sub=>{
// sub.age_decade = parseInt(sub.age_decade/10)*10;
// });
// console.log(JSON.stringify(table, null, ' '));
// table combine field value view
setTimeout(()=>{
const combineFieldViewCfg = {
combine({ field, value }) {
return field + value;
}
};
// table full view cfg
const fullViewCfg = {
combine({ field, value,colIndex,rowIndex }) {
return field + value + colIndex + rowIndex;
}
};
const sankeyPlugin = new G6.Plugins['template.tableSankey']({
padding: [ 40, 24, 24, 40 ],
table,
colNameTextStyle: {
fill: 'white',
fontSize: 16,
fontWeight: 900,
textAlign: 'center'
},
labelStyle: {
fill: 'white',
fontSize: 12,
fillOpacity: 0.65
},
fields: ['president', 'birth_place', 'age_decade', 'party', 'sgin'],
onBeforeRender(graph) {
graph.node({
color(model) {
const colors = ['#003f5c', '#2f4b7c', '#665191', '#a05195', '#d45087', '#f95d6a', '#ff7c43', '#ffa600'];
return colors[model.rowIndex%10];
},
style: {
stroke: null
}
});
graph.edge({
style: {
stroke: '#A3B1BF',
strokeOpacity: 0.45
}
});
},
...fullViewCfg
})
const graph = new G6.Graph({
container: 'mountNode',
height: window.innerHeight, // 画布高
fitView: 'cc',
animate: true,
plugins: [sankeyPlugin]
});
setTimeout(()=>{
// graph.read({});
sankeyPlugin.change(combineFieldViewCfg);
}, 2000);
setTimeout(()=>{
sankeyPlugin.change({
fields: ['president', 'birth_place', 'party', 'sgin'],
});
}, 4000);
setTimeout(()=>{
sankeyPlugin.change({
fields: ['president', 'birth_place', 'party'],
});
}, 6000);
setTimeout(()=>{
sankeyPlugin.change({
fields: ['president', 'birth_place', 'party', 'age_decade'],
});
}, 8000);
}, 0);
}, 2000);
});
</script>
</body>
</html>

133
demos/yunqi-2-dark.html Normal file
View File

@ -0,0 +1,133 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="./assets/jquery-3.2.1.min.js"></script>
<script src="../build/g6.js"></script>
<script src="./assets/d3-4.13.0.min.js"></script>
<script src="../build/plugins.js"></script>
<title>云栖 demo 2</title>
</head>
<style>
body{
background: #2E2E2E;
}
</style>
<body>
<div id="mountNode"></div>
<script>
const { forceSimulation, forceLink, forceManyBody, forceX, forceY, forceCollide } = d3;
const {Util} = G6;
setTimeout(()=>{
$.getJSON('./assets/data/tr.json', data => {
const nodeMap = {};
data.nodes.forEach((node, index)=>{
node.rank = node.value;
nodeMap[node.id] = node;
node.id = index;
});
data.edges.forEach(edge=>{
// console.log(nodeMap[edge.source].index, nodeMap[edge.target].index)
edge.source = nodeMap[edge.source].id;
edge.target = nodeMap[edge.target].id;
edge.id = edge.source + '-' + edge.target;
});
let simulation;
const graph = new G6.Graph({
container: 'mountNode',
height: window.innerHeight, // 画布高
fitView: 'cc',
layout: {
auto: 'once',
processer(nodes, edges) {
const forest = Util.maxSpanningForest({nodes, edges});
forest.edges.forEach(edge=>{
edge.isTreeEdge = true;
});
nodes.forEach(node=>{
node.treeEdgeCount = 0;
graph.find(node.id).getEdges().forEach(edge=>{
const edgeModel = edge.getModel()
if(edgeModel.isTreeEdge){
node.treeEdgeCount++;
node.treeEdge = edgeModel;
}
});
if(node.treeEdgeCount === 1){
let fColor;
if(node.id === node.treeEdge.source){
fColor = graph.find(node.treeEdge.target).getModel().color
} else {
fColor = graph.find(node.treeEdge.source).getModel().color
}
graph.update(node.id, {
fColor
});
}
});
if (simulation) {
simulation.alphaTarget(0.3).restart();
} else {
simulation = forceSimulation(nodes)
.force('charge', forceManyBody())
.force('link', forceLink(edges).id(model => {
return model.id;
}))
.force('collision', forceCollide().radius(model => {
return model.size / 2 * 1.2;
}))
.force('y', forceY())
.force('x', forceX())
.on('tick', () => {
graph.updateNodePosition();
graph.emit('afterlayout');
});
}
const noTreeEdges = edges.filter(edge=>{
return !edge.isTreeEdge;
});
setTimeout(()=>{
setInterval(()=>{
const edge = noTreeEdges[parseInt(Math.random()*noTreeEdges.length)];
if(edge) {
graph.find(edge.id).hide();
Util.remove(noTreeEdges, edge);
Util.remove(edges, edge);
simulation
.force('link', forceLink(edges).distance(20).strength(1).id(model => {
return model.id;
}))
.alphaTarget(0.3)
.restart();
}
}, 32)
}, 3000);
}
},
});
graph.node({
size: 6,
color(model) {
const colors = ['#a05195', '#d45087', '#f95d6a', '#ff7c43', '#ffa600'];
return model.fColor ? model.fColor: colors[parseInt(Math.random()*colors.length)];
},
});
graph.edge({
style: {
stroke: '#666',
strokeOpacity: 0.45,
lineWidth: 1
}
});
graph.read(data);
graph.zoom(2)
});
}, 5000);
</script>
</body>
</html>

101
demos/yunqi-3-dark.html Normal file
View File

@ -0,0 +1,101 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="./assets/jquery-3.2.1.min.js"></script>
<script src="../build/g6.js"></script>
<script src="https://gw.alipayobjects.com/os/antv/pkg/_antv.g2-3.2.6/dist/g2.min.js"></script>
<script src="https://gw.alipayobjects.com/os/antv/pkg/_antv.data-set-0.8.9/dist/data-set.min.js"></script>
<script src="./assets/d3-4.13.0.min.js"></script>
<script src="../build/plugins.js"></script>
<title>云栖 demo 3</title>
</head>
<style>
body{
background: #2E2E2E;
}
</style>
<body>
<div id="mountNode" style="position: relative;">
<!-- <img class="legend" width="220" src="https://gw.alipayobjects.com/zos/rmsportal/AuLKMNbRvKidugdUCaXz.png" style="position: absolute;right: 200px;"/> -->
</div>
<script>
$.getJSON('./assets/data/link-data.json', data => {
const Mapper = G6.Plugins['tool.mapper'];
const colors = ['#2f4b7c', '#665191', '#a05195', '#d45087', '#f95d6a', '#ff7c43', '#ffa600'];
const nodeColorMapper = new Mapper('node', 'color', 'color', colors);
const { Util } = G6;
const graph = new G6.Graph({
container: 'mountNode',
height: window.innerHeight, // 画布高
plugins: [
nodeColorMapper,
new G6.Plugins['tool.highlightSubgraph']({
maskStyle: {
fill: 'black',
fillOpacity: 0.35
}
}),
new G6.Plugins['tool.fisheye']({
radius: 300
}),
new G6.Plugins['tool.textDisplay']({
ratio: 2.3
}),
],
fitView:'autoZoom',
});
graph.node({
style: {
stroke: '#333'
},
label(model) {
return {
text: model.label,
fill: 'white',
}
}
})
graph.on('afteritemdraw', ({ item }) => {
const label = item.getLabel();
if (label) {
label.set('freezePoint', {
x: 0,
y: 0
});
}
});
graph.read(data);
// 画布向左偏移 1/6 的画布kuandu
const width = graph.getWidth();
graph.translate(-width/7, 0);
// 隐藏所有边
graph.getEdges().forEach(edge=>{
graph.hide(edge);
});
// 鼠标悬浮高亮节点,并显示一度关系
let showEdgesCache;
graph.on('node:mouseenter', ({item})=>{
const {
reNodes,
reEdges
} = Util.extract('bi', [item]);
graph.highlightSubgraph(reNodes.concat(reEdges));
reEdges.forEach(edge=>{
graph.show(edge);
})
showEdgesCache=reEdges
});
graph.on('node:mouseleave', ()=>{
graph.unhighlightGraph();
showEdgesCache.forEach(edge=>{
graph.hide(edge)
});
});
});
</script>
</body>
</html>

136
demos/yunqi-4-dark.html Normal file
View File

@ -0,0 +1,136 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="./assets/jquery-3.2.1.min.js"></script>
<script src="../build/g6.js"></script>
<script src="./assets/d3-4.13.0.min.js"></script>
<script src="../build/plugins.js"></script>
<title>云栖 demo 2</title>
</head>
<style>
body{
background: #2E2E2E;
}
</style>
<body>
<div id="mountNode"></div>
<script>
const { forceSimulation, forceLink, forceManyBody, forceX, forceY, forceCollide } = d3;
const {Util} = G6;
setTimeout(()=>{
$.getJSON('./assets/data/g6-actived-system.json', data => {
// for (let index = 0; index < 160; index++) {
// data.nodes.push({
// pv: Math.random()*13920,
// domain: 1
// });
// }
// data.nodes.forEach((node,index)=>{
// node.index = index;
// });
// console.log(JSON.stringify(data, null, ' '));
data.nodes = data.nodes.slice(0, 600);
data.nodes.sort((a, b)=>{
return b.pv-a.pv;
});
data.nodes.forEach((node, index)=>{
node.index = index;
});
// 设置映射
const Mapper = G6.Plugins['tool.mapper'];
const colors = ['#2f4b7c', '#665191', '#a05195', '#d45087', '#f95d6a', '#ff7c43', '#ffa600'];
const nodeColorMapper = new Mapper('node', 'index', 'color', colors);
const nodeSizeMapper = new Mapper('node', 'pv', 'size', [6, 32], {
scaleCfg: {
type: 'log'
}
});
let simulation;
const graph = new G6.Graph({
container: 'mountNode',
height: window.innerHeight,
fitView: 'cc',
plugins: [nodeColorMapper, nodeSizeMapper],
layout: {
auto: 'once',
processer(nodes) {
// 按 100剩余所有分割节点数据集
const nodes_100 = [];
const nodes_left = [];
const width = graph.getWidth();
const height = graph.getHeight();
nodes.forEach(node => {
if (nodes_100.length < 100 && Math.random() < 0.2) {
nodes_100.push(node);
} else {
graph.hide(node.id);
nodes_left.push(node);
}
});
if (simulation) {
simulation.alphaTarget(0.3).restart();
} else {
simulation = forceSimulation(nodes_100)
.force('collision', forceCollide().radius(model => {
return model.size / 2 * 1.2;
}).iterations(2))
.velocityDecay(0.2)
.force("x", d3.forceX().strength(0.001))
.force("y", d3.forceY().strength(0.001))
.on('tick', () => {
graph.updateNodePosition();
});
}
// 每隔一段时间添加一个节点
setTimeout(()=>{
let concatNodes = nodes_100;
const interval = setInterval(()=>{
if(nodes_left.length>0) {
const node = nodes_left[parseInt(Math.random()*nodes_left.length)];
Util.remove(nodes_left, node);
// node.x = 0;
// node.y = 0;
concatNodes = concatNodes.concat(node);
simulation.nodes(concatNodes)
.alpha(2).restart();
setTimeout(()=>{
if(node.x && node.y && node.x !==0 && node.y !== 0) {
graph.find(node.id).show();
}
}, 32);
} else {
console.log(333)
simulation
.force('collision', forceCollide().radius(model => {
return model.size / 2 * 1.4;
}).iterations(2))
.alpha(2).restart();
// clearInterval(interval);
}
}, 16)
}, 3000);
}
},
});
graph.edge({
style: {
stroke: '#A3B1BF',
strokeOpacity: 0.45
}
});
graph.read(data);
graph.translate(-300, 0)
});
}, 5000)
</script>
</body>
</html>

View File

@ -65,7 +65,9 @@ G6.registerGuide('col-names', {
const group = item.getGraphicGroup();
const graph = item.getGraph();
const nodes = graph.getNodes();
const model = item.getModel();
const colMap = {};
const { textStyle } = model;
let minY = Infinity;
nodes.forEach(node => {
const model = node.getModel();
@ -86,8 +88,7 @@ G6.registerGuide('col-names', {
text: field,
x,
y: minY - 12,
fill: '#333',
textAlign: 'center'
...textStyle
}
});
});
@ -118,6 +119,21 @@ class Plugin {
*/
showColName: true,
/**
* @type {object} colNameTextStyle - col name text style
*/
colNameTextStyle: {
fill: '#333',
textAlign: 'center'
},
/**
* @type {object} labelStyle - label style
*/
labelStyle: {
},
/**
* @type {string} align - could be `sankeyLeft` `sankeyRight` `sankeyCenter` `sankeyJustify`
*/
@ -234,19 +250,19 @@ class Plugin {
const graph = this.graph;
const width = graph.getWidth();
graph.node({
label(model) {
if (model.x > width / 2) {
return {
text: model.fieldValue,
textAlign: 'right'
};
}
return {
label: model => {
const label = {
text: model.fieldValue,
textAlign: 'left'
...this.labelStyle
};
if (model.x > width / 2) {
label.textAlign = 'right';
} else {
label.textAlign = 'left';
}
return label;
},
labelOffsetX(model) {
labelOffsetX: model => {
const labelGap = 8;
if (model.x > width / 2) {
return -(model.x1 - model.x0) / 2 - labelGap;
@ -259,7 +275,8 @@ class Plugin {
const guides = [];
if (this.showColName) {
guides.push({
shape: 'col-names'
shape: 'col-names',
textStyle: this.colNameTextStyle
});
}
return guides;

View File

@ -8,8 +8,8 @@ const Util = G6.Util;
const Fisheye = require('./tool');
class Plugin {
constructor(options) {
Util.mix(this, {
}, options);
Util.mix(this, options);
this.options = options;
}
init() {
const graph = this.graph;

View File

@ -30,11 +30,12 @@ G6.registerGuide('mask', {
const group = item.getGraphicGroup();
const graph = item.getGraph();
const maskRect = getMaskRect(graph);
const model = item.getModel();
const { style } = model;
return group.addShape('rect', {
attrs: {
...maskRect,
fill: 'rgb(255, 255, 255)',
fillOpacity: 0.8
...style
},
capture: false
});
@ -44,7 +45,12 @@ G6.registerGuide('mask', {
class Plugin {
constructor(options) {
Util.mix(this, options);
Util.mix(this, {
maskStyle: {
fill: 'rgb(255, 255, 255)',
fillOpacity: 0.8
}
}, options);
}
init() {
const graph = this.graph;
@ -58,7 +64,8 @@ class Plugin {
if (!mask) {
mask = graph.add('guide', {
shape: 'mask',
id: 'mask'
id: 'mask',
style: this.maskStyle
});
mask.hide();
}

View File

@ -8,7 +8,9 @@ const Util = G6.Util;
class Plugin {
constructor(options) {
Util.mix(this, options);
Util.mix(this, {
ratio: 2
}, options);
}
init() {
this.graph.on('afterchange', () => {
@ -37,7 +39,7 @@ class Plugin {
if (labelWidth === 0) return;
const ratio = labelWidth / nodeWidth;
if (ratio > 2) {
if (ratio > this.ratio) {
label.hide();
} else {
label.show();

View File

@ -1 +1 @@
module.exports = '2.1.1-beta.1';
module.exports = '2.1.1';