diff --git a/demos/gallery-case1.html b/demos/gallery-case1.html
index e5822f05d7..d6966b6a91 100644
--- a/demos/gallery-case1.html
+++ b/demos/gallery-case1.html
@@ -58,7 +58,7 @@
graph = new G6.Graph({
id: 'mountNode', // dom id
fitView: 'autoZoom',
- plugins: [new Plugin({max_iteration: 1000, kg: 2, kr: 40, prev_overlapping: true}),
+ plugins: [new Plugin({maxIteration: 1000, kg: 2, kr: 40, prevOverlapping: true}),
new FisheyePlugin({radius: 200}),
nodeSizeMapper, nodeColorMapper
],
diff --git a/demos/gallery-graphanalyzer.html b/demos/gallery-graphanalyzer.html
index 2af038134c..2e56ba1435 100644
--- a/demos/gallery-graphanalyzer.html
+++ b/demos/gallery-graphanalyzer.html
@@ -25,11 +25,11 @@
const Mapper = G6.Plugins['tool.mapper'];
const MaxSpanningForestPlugin = G6.Plugins['template.maxSpanningForest'];
//the instances of plugins
- const maxSpanningForest = new MaxSpanningForestPlugin({
+ let maxSpanningForest = new MaxSpanningForestPlugin({
layoutCfg: {
- max_iteration: 600,
+ maxIteration: 600,
kg: 10,
- prev_overlapping: true,
+ prevOverlapping: true,
onLayoutComplete: function () {
const minimap = document.getElementById('minimap');
const legend = document.getElementById('legend');
@@ -38,24 +38,34 @@
}
}
});
- const nodeSizeMapper = new Mapper('node', 'userview', 'size', [20, 50], {
+ let nodeSizeMapper = new Mapper('node', 'userview', 'size', [20, 50], {
legendCfg: {
containerId: 'legend',
title: 'UV',
- layout: 'horizontal'
+ layout: 'horizontal',
+ // formatter: function(num) {
+ // console.log(num);
+ // num = num * num;
+ // if (num >= 100000000) {
+ // return num / 100000000 + '亿';
+ // } if (num >= 10000) {
+ // return num / 10000 + '万';
+ // }
+ // return num;
+ // }
}
});
- const edgeSizeMapper = new Mapper('edge', 'userview', 'size', [1, 16], {
+ let edgeSizeMapper = new Mapper('edge', 'userview', 'size', [1, 16], {
legendCfg: null
});
- const nodeColorMapper = new Mapper('node', 'stayTime', 'color', ['#BAE7FF', '#1890FF', '#0050B3'], {
+ let nodeColorMapper = new Mapper('node', 'stayTime', 'color', ['#BAE7FF', '#1890FF', '#0050B3'], {
legendCfg: {
containerId: 'legend',
title: 'Stay Time',
layout: 'horizontal'
}
});
- const minimapPlugin = new G6.Plugins['tool.minimap']({
+ let minimapPlugin = new G6.Plugins['tool.minimap']({
container: 'minimap',
width: 180,
height: 120
@@ -67,14 +77,14 @@
id: 'mountNode', // dom id
fitView: 'autoZoom',
plugins: [
- maxSpanningForest, nodeSizeMapper, nodeColorMapper, edgeSizeMapper, minimapPlugin
+ maxSpanningForest, nodeColorMapper, minimapPlugin, edgeSizeMapper, nodeSizeMapper,
],
modes: {
default: ['panCanvas', 'wheelZoom']
},
height: 500,
});
- graph.read(data);
+ graph.read(Util.cloneDeep(data));
const minimap = document.getElementById('minimap');
const legend = document.getElementById('legend');
if (minimap !== undefined) minimap.style.display = 'none';
diff --git a/demos/plugin-fisheye.html b/demos/plugin-fisheye.html
index 5454c6fba3..1928c23934 100644
--- a/demos/plugin-fisheye.html
+++ b/demos/plugin-fisheye.html
@@ -32,13 +32,13 @@
nodes.forEach((node, index) => {
if (parseInt(index / col) % 2 === 0) {
node.x = (col - index % col) * hgap;
- node.ori_x = node.x;
+ node.oriX = node.x;
} else {
node.x = index % col * hgap + hgap;
- node.ori_x = node.x;
+ node.oriX = node.x;
}
node.y = parseInt(index / col) * vgap + vgap / 2;
- node.ori_y = node.y;
+ node.oriY = node.y;
});
}
});
diff --git a/demos/plugin-forceAtlas2.html b/demos/plugin-forceAtlas2.html
index e92c445257..92d8c21ebe 100644
--- a/demos/plugin-forceAtlas2.html
+++ b/demos/plugin-forceAtlas2.html
@@ -15,19 +15,19 @@
diff --git a/demos/plugin-mapper.html b/demos/plugin-mapper.html
index 8073e5c1b0..b1ad47397f 100644
--- a/demos/plugin-mapper.html
+++ b/demos/plugin-mapper.html
@@ -20,6 +20,7 @@
scale: 0.5
}
});
+ const nodeSizeMapper = new Mapper('node', 'weight', 'size', [20, 40]);
const edgeSizeMapper = new Mapper('edge', 'weight', 'size', [2, 20], {
legendCfg: null
});
@@ -28,21 +29,25 @@
id: 'node1',
x: 100,
y: 200,
+ weight: 10,
class: 'class_1'
}, {
id: 'node2',
x: 300,
y: 200,
+ weight: 2,
class: 'class_1'
}, {
id: 'node3',
x: 100,
y: 100,
+ weight: 15,
class: 'class_2'
}, {
id: 'node4',
x: 300,
y: 100,
+ weight: 5,
class: 'class_2'
}],
edges: [{
@@ -61,7 +66,7 @@
};
const graph = new G6.Graph({
id: 'mountNode', // dom id
- plugins: [nodeColorMapper, edgeSizeMapper],
+ plugins: [nodeColorMapper, edgeSizeMapper, nodeSizeMapper],
height: 1000,
});
graph.read(data);
diff --git a/demos/quick-net-svg.html b/demos/quick-net-svg.html
deleted file mode 100644
index b94da8cbaa..0000000000
--- a/demos/quick-net-svg.html
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
-
-
- 快速上手-网图-SVG
-
-
-
-
-
-
-
-
diff --git a/package.json b/package.json
index 89b81de6cb..1dc554741c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@antv/g6",
- "version": "2.1.0-beta",
+ "version": "2.1.0-beta.3",
"description": "graph visualization frame work",
"main": "build/g6.js",
"homepage": "https://github.com/antvis/g6",
@@ -97,7 +97,7 @@
"screenshot": "node ./bin/screenshot.js",
"start": "npm run dev",
"test": "torch --compile --renderer --recursive ./test/unit",
- "test-live": "torch --compile --interactive --watch --recursive ./test/unit/plugins/tool.mapper-spec.js",
+ "test-live": "torch --compile --interactive --watch --recursive ./test/unit/plugins/layout.forceAtlas2-spec.js",
"watch": "webpack --config webpack-dev.config.js",
"win-dev": "node ./bin/win-dev.js"
},
diff --git a/plugins/layout.forceAtlas2/BlobBuilder.js b/plugins/layout.forceAtlas2/BlobBuilder.js
deleted file mode 100644
index 679cdb444b..0000000000
--- a/plugins/layout.forceAtlas2/BlobBuilder.js
+++ /dev/null
@@ -1,128 +0,0 @@
-/* BlobBuilder.js
- * A complete BlobBuilder shim
- * By Eli Grey
- * License: MIT/X11
- */
-
-self.BlobBuilder || self.WebKitBlobBuilder || self.MozBlobBuilder || function(view) {
-
- let
- get_class = function(object) {
- return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
- },
- FakeBlobBuilder = view.BlobBuilder = function() {},
- FakeBlob = view.Blob = function(data, type) {
- this.data = data;
- this.size = data.length;
- this.type = type;
- },
- FBB_proto = FakeBlobBuilder.prototype = [],
- FB_proto = FakeBlob.prototype,
- FileReaderSync = view.FileReaderSync,
- FileException = function(type) {
- this.code = this[this.name = type];
- },
- file_ex_codes = (
- 'NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR ' +
- 'NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR'
- ).split(' '),
- file_ex_code = file_ex_codes.length,
- URL = view.URL = view.URL || view.webkitURL || view,
- real_create_object_url,
- real_revoke_object_url,
- btoa = view.btoa,
- ArrayBuffer = view.ArrayBuffer,
- can_apply_typed_arrays = false,
- can_apply_typed_arrays_test = function(pass) {
- can_apply_typed_arrays = !pass;
- };
- while (file_ex_code--) {
- FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
- }
- try {
- if (ArrayBuffer) {
- can_apply_typed_arrays_test.apply(0, new Uint8Array(1));
- }
- } catch (ex) {}
- if (!URL.createObjectURL) {
- URL = {};
- }
- real_create_object_url = URL.createObjectURL;
- real_revoke_object_url = URL.revokeObjectURL;
- URL.createObjectURL = function(blob) {
- let type = blob.type;
- if (type === null) {
- type = 'application/octet-stream';
- }
- if (blob instanceof FakeBlob) {
- if (btoa) {
- return 'data:' + type + ';base64,' + btoa(blob.data);
- }
- return 'data:' + type + ',' + encodeURIComponent(blob.data);
-
- } else if (real_create_object_url) {
- return real_create_object_url.call(URL, blob);
- }
- };
- URL.revokeObjectURL = function(object_url) {
- if (object_url.substring(0, 5) !== 'data:' && real_revoke_object_url) {
- real_revoke_object_url.call(URL, object_url);
- }
- };
- FBB_proto.append = function(data /* , endings*/) {
- const bb = this;
- // decode data to a binary string
- if (ArrayBuffer && data instanceof ArrayBuffer) {
- if (can_apply_typed_arrays) {
- bb.push(String.fromCharCode.apply(String, new Uint8Array(data)));
- } else {
- let
- str = '',
- buf = new Uint8Array(data),
- i = 0,
- buf_len = buf.length;
- for (; i < buf_len; i++) {
- str += String.fromCharCode(buf[i]);
- }
- }
- } else if (get_class(data) === 'Blob' || get_class(data) === 'File') {
- if (FileReaderSync) {
- const fr = new FileReaderSync();
- bb.push(fr.readAsBinaryString(data));
- } else {
- // async FileReader won't work as BlobBuilder is sync
- throw new FileException('NOT_READABLE_ERR');
- }
- } else if (data instanceof FakeBlob) {
- bb.push(data.data);
- } else {
- if (typeof data !== 'string') {
- data += ''; // convert unsupported types to strings
- }
- // decode UTF-16 to binary string
- bb.push(unescape(encodeURIComponent(data)));
- }
- };
- FBB_proto.getBlob = function(type) {
- if (!arguments.length) {
- type = null;
- }
- return new FakeBlob(this.join(''), type);
- };
- FBB_proto.toString = function() {
- return '[object BlobBuilder]';
- };
- FB_proto.slice = function(start, end, type) {
- const args = arguments.length;
- if (args < 3) {
- type = null;
- }
- return new FakeBlob(
- this.data.slice(start, args > 1 ? end : this.data.length), type
- );
- };
- FB_proto.toString = function() {
- return '[object Blob]';
- };
- return FakeBlobBuilder;
-}(self);
diff --git a/plugins/layout.forceAtlas2/README.md b/plugins/layout.forceAtlas2/README.md
index e9d4b5d956..04c93dbada 100644
--- a/plugins/layout.forceAtlas2/README.md
+++ b/plugins/layout.forceAtlas2/README.md
@@ -7,17 +7,17 @@ ForceAtlas2(https://medialab.sciencespo.fr/publications/Jacomy_Heymann_Venturini
- mode: 'normal'/'linlog'
'normal': normal layout
'linlog': the cluster will be more compact
-- pre_overlapping: true/false.
+- preOverlapping: true/false.
true: prevents node overlapping, result in non-node-overlapping layout
false: allows node overlapping.
-- dissuade_hubs: true/false. whether active the dissuade hub mode
+- dissuadeHubs: true/false. whether active the dissuade hub mode
true: grant authorities(nodes with a high indegree) a more central position than hubs(nodes with a high outdegree)
false: without dissuade hub mode
-- barnes_hut: true/false. Whether active the barnes hut optimization on computing repulsive foces. We implemented the paper 'A hierarchical O(N log N) force-calculation algorithm strategy'(https://www.nature.com/articles/324446a0).
+- barnesHut: true/false. Whether active the barnes hut optimization on computing repulsive foces. We implemented the paper 'A hierarchical O(N log N) force-calculation algorithm strategy'(https://www.nature.com/articles/324446a0).
- ks: controls the global velocity. Default: 0.1
- ksmax: the max global velocity. Default: 10
- tao: the tolerance for the global swinging. Default: 0.1
-- max_iteration: the iteration to terminate the algorithm. We suggest 700 for the graph with less than 50 nodes; 1000 for 100 nodes; Upper than 1500 for more nodes.
+- maxIteration: the iteration to terminate the algorithm. We suggest 700 for the graph with less than 50 nodes; 1000 for 100 nodes; Upper than 1500 for more nodes.
## use
@@ -26,18 +26,18 @@ simple use.
```js
$.getJSON('../../test/fixtures/viralMarketing.json', data => {
const Plugin = G6.Plugins['layout.forceAtlas2'];
- const layout_params = {
- max_iteration: 1500,
- prev_overlapping: true,
+ const layoutParams = {
+ maxIteration: 1500,
+ prevOverlapping: true,
kr: 15,
mode: 'normal',
- barnes_hut: false, // may be counter-productive on small networks
+ barnesHut: false, // may be counter-productive on small networks
ks: 0.1,
- dissuade_hubs: false
+ dissuadeHubs: false
};
graph = new G6.Graph({
id: 'mountNode', // dom id
- plugins: [new Plugin(layout_params)],
+ plugins: [new Plugin(layoutParams)],
height: 1000,
});
graph.read(data);
diff --git a/plugins/layout.forceAtlas2/body.js b/plugins/layout.forceAtlas2/body.js
index 847d618fc9..d741d894cc 100644
--- a/plugins/layout.forceAtlas2/body.js
+++ b/plugins/layout.forceAtlas2/body.js
@@ -77,14 +77,14 @@ class Body {
}
// returns a new body
add(bo) {
- const nenw_mass = this.mass + bo.mass;
- const x = (this.rx * this.mass + bo.rx * bo.mass) / nenw_mass;
- const y = (this.ry * this.mass + bo.ry * bo.mass) / nenw_mass;
+ const nenwMass = this.mass + bo.mass;
+ const x = (this.rx * this.mass + bo.rx * bo.mass) / nenwMass;
+ const y = (this.ry * this.mass + bo.ry * bo.mass) / nenwMass;
const dg = this.degree + bo.degree;
const params = {
rx: x,
ry: y,
- mass: nenw_mass,
+ mass: nenwMass,
degree: dg
};
return new Body(params);
diff --git a/plugins/layout.forceAtlas2/layout.js b/plugins/layout.forceAtlas2/layout.js
index b87f160dd8..b997886f87 100644
--- a/plugins/layout.forceAtlas2/layout.js
+++ b/plugins/layout.forceAtlas2/layout.js
@@ -54,7 +54,7 @@ class Layout {
* whether preventing the node overlapping
* @type {boolean}
*/
- prev_overlapping: false,
+ prevOverlapping: false,
/**
* whether active the dissuade hub mode
@@ -62,19 +62,19 @@ class Layout {
* a more central position than hubs (nodes with a high outdegree)
* @type {boolean}
*/
- dissuade_hubs: false,
+ dissuadeHubs: false,
/**
* whether active the barnes hut optimization on computing repulsive forces
* @type {boolean}
*/
- barnes_hut: false,
+ barnesHut: false,
/**
* the max iteration number
* @type {number}
*/
- max_iteration: 1500,
+ maxIteration: 1500,
/**
* control the global velocity
@@ -111,18 +111,18 @@ class Layout {
kr,
kg,
mode,
- prev_overlapping,
- dissuade_hubs,
- barnes_hut,
- max_iteration,
+ prevOverlapping,
+ dissuadeHubs,
+ barnesHut,
+ maxIteration,
ks,
ksmax,
tao,
onLayoutComplete
} = this;
- if (!barnes_hut && nodes.length > 300) barnes_hut = true;
- else if (barnes_hut && nodes.length <= 300) barnes_hut = false;
+ if (!barnesHut && nodes.length > 300) barnesHut = true;
+ else if (barnesHut && nodes.length <= 300) barnesHut = false;
const width = this.width ? this.width : graph.getWidth();
const height = this.height ? this.height : graph.getHeight();
@@ -142,10 +142,10 @@ class Layout {
kr,
kg,
mode,
- prev_overlapping,
- dissuade_hubs,
- barnes_hut,
- max_iteration,
+ prevOverlapping,
+ dissuadeHubs,
+ barnesHut,
+ maxIteration,
ks,
ksmax,
tao,
@@ -153,38 +153,39 @@ class Layout {
widths
};
- // a loading dom before worker
+ // a loading dom before worker
const loading = document.createElement('div');
loading.id = 'loading';
loading.style.setProperty('background-color', '#fff');
loading.style.setProperty('position', 'absolute');
- const parent = graph.getGraphContainer();
- loading.style.setProperty('width', parent.width() + 'px');
- loading.style.setProperty('height', parent.height() + 'px');
- loading.style.setProperty('margin-top', (-parent.height()) + 'px');
+ const parent = graph.getGraphContainer().parentNode;
+ loading.style.setProperty('width', parent.offsetWidth + 'px');
+ loading.style.setProperty('height', parent.offsetHeight + 'px');
+ loading.style.setProperty('margin-top', (-parent.offsetHeight) + 'px');
+ loading.style.zIndex = 999;
parent.appendChild(loading);
// the loading image
- const loading_img = document.createElement('img');
- loading_img.src = 'https://gw.alipayobjects.com/zos/rmsportal/mnEmjOmrHbghTsZNeTmI.gif';
- loading_img.style.setProperty('width', 120 + 'px');
- loading_img.style.setProperty('height', 120 + 'px');
- const Cw = 120;
- const Pw = parent.width();
+ const loadingImg = document.createElement('img');
+ loadingImg.src = 'https://gw.alipayobjects.com/zos/rmsportal/mnEmjOmrHbghTsZNeTmI.gif';
+ loadingImg.style.setProperty('width', 200 + 'px');
+ loadingImg.style.setProperty('height', 200 + 'px');
+ const Cw = loadingImg.offsetWidth;
+ const Pw = loading.offsetWidth;
const left = (Pw - Cw) / 2;
- loading_img.style.setProperty('margin-left', left + 'px');
- const Ch = 120;
- const Ph = parent.height();
+ loadingImg.style.setProperty('margin-left', left + 'px');
+ const Ch = loadingImg.offsetHeight;
+ const Ph = loading.offsetHeight;
const top = (Ph - Ch) / 2;
- loading_img.style.setProperty('margin-top', top + 'px');
- loading.appendChild(loading_img);
+ loadingImg.style.setProperty('margin-top', top + 'px');
+ loading.appendChild(loadingImg);
const worker = new Worker();// { type: 'module' }
worker.postMessage(obj);
worker.onmessage = function(event) {
this.nodes = event.data;
- const graph_nodes = graph.getNodes();
+ const graphNodes = graph.getNodes();
for (let i = 0; i < size; i += 1) {
- const model = graph_nodes[i].getModel();
+ const model = graphNodes[i].getModel();
model.x = this.nodes[i].x;
model.y = this.nodes[i].y;
}
diff --git a/plugins/layout.forceAtlas2/layout.worker.js b/plugins/layout.forceAtlas2/layout.worker.js
index eeb1619ad7..482cb0b68e 100644
--- a/plugins/layout.forceAtlas2/layout.worker.js
+++ b/plugins/layout.forceAtlas2/layout.worker.js
@@ -8,10 +8,10 @@ onmessage = function(event) {
kr,
kg,
mode,
- prev_overlapping,
- dissuade_hubs,
- barnes_hut,
- max_iteration,
+ prevOverlapping,
+ dissuadeHubs,
+ barnesHut,
+ maxIteration,
ks,
ksmax,
tao,
@@ -30,8 +30,6 @@ onmessage = function(event) {
for (let i = 0; i < size; i += 1) {
idmap[nodes[i].id] = i;
degrees[i] = 0;
- // nodes[i].index = i;
- // nodes[i].degree = 0;
nodes[i].x = Math.random() * 1000;
nodes[i].y = Math.random() * 1000;
}
@@ -45,24 +43,20 @@ onmessage = function(event) {
node2 = nodes[j];
}
}
- // // const node1 = graph.find(edges[i].source).getModel();
- // // const node2 = graph.find(edges[i].target).getModel();
- // nodes[node1.index].degree += 1;
- // nodes[node2.index].degree += 1;
degrees[idmap[node1.id]] += 1;
degrees[idmap[node2.id]] += 1;
}
- const kr_prime = 100;
- let iter = max_iteration;
- const prevo_iter = 50;
+ const krPrime = 100;
+ let iter = maxIteration;
+ const prevoIter = 50;
let Forces = [];
- const pre_Forces = [];
+ const preForces = [];
for (let i = 0; i < size; i += 1) {
Forces[2 * i] = 0;
Forces[2 * i + 1] = 0;
- if (barnes_hut) {
+ if (barnesHut) {
let params = {
id: i,
rx: nodes[i].x,
@@ -78,22 +72,22 @@ onmessage = function(event) {
do {
for (let i = 0; i < size; i += 1) {
- pre_Forces[2 * i] = Forces[2 * i];
- pre_Forces[2 * i + 1] = Forces[2 * i + 1];
+ preForces[2 * i] = Forces[2 * i];
+ preForces[2 * i + 1] = Forces[2 * i + 1];
Forces[2 * i] = 0;
Forces[2 * i + 1] = 0;
}
// // attractive forces, existing on every actual edge
- Forces = getAttrForces(nodes, edges, size, esize, prev_overlapping, dissuade_hubs, mode, iter, prevo_iter, Forces, widths, idmap, degrees);
+ Forces = getAttrForces(nodes, edges, size, esize, prevOverlapping, dissuadeHubs, mode, iter, prevoIter, Forces, widths, idmap, degrees);
// // // repulsive forces and Gravity, existing on every node pair
- // // // if prev_overlapping, using the no-optimized method in the last prevo_iter instead.
- if (barnes_hut && ((prev_overlapping && iter > prevo_iter) || !prev_overlapping)) {
- Forces = getOptRepGraForces(nodes, edges, size, esize, prev_overlapping, dissuade_hubs, mode, iter, prevo_iter, Forces, kr, kr_prime, kg, center, bodies, degrees);
+ // // // if prevOverlapping, using the no-optimized method in the last prevoIter instead.
+ if (barnesHut && ((prevOverlapping && iter > prevoIter) || !prevOverlapping)) {
+ Forces = getOptRepGraForces(nodes, edges, size, esize, prevOverlapping, dissuadeHubs, mode, iter, prevoIter, Forces, kr, krPrime, kg, center, bodies, degrees);
} else {
- Forces = getRepGraForces(nodes, edges, size, esize, prev_overlapping, dissuade_hubs, mode, iter, prevo_iter, Forces, kr, kr_prime, kg, center, widths, degrees);
+ Forces = getRepGraForces(nodes, edges, size, esize, prevOverlapping, dissuadeHubs, mode, iter, prevoIter, Forces, kr, krPrime, kg, center, widths, degrees);
}
// // update the positions
- const res = updatePos(size, nodes, Forces, pre_Forces, SG, ks, ksmax, tao, degrees);
+ const res = updatePos(size, nodes, Forces, preForces, SG, ks, ksmax, tao, degrees);
nodes = res[0];
SG = res[1];
iter -= 1;
@@ -101,81 +95,75 @@ onmessage = function(event) {
self.postMessage(nodes);
};
-function getAttrForces(nodes, edges, size, esize, prev_overlapping, dissuade_hubs, mode, iter, prevo_iter, Forces, widths, idmap, degrees) {
+function getAttrForces(nodes, edges, size, esize, prevOverlapping, dissuadeHubs, mode, iter, prevoIter, Forces, widths, idmap, degrees) {
for (let i = 0; i < esize; i += 1) {
- // const source_node = graph.find(edges[i].source).getModel();
- // const target_node = graph.find(edges[i].target).getModel();
- let source_node;
- let target_node;
- let source_idx;
- let target_idx;
+ // const sourceNode = graph.find(edges[i].source).getModel();
+ // const targetNode = graph.find(edges[i].target).getModel();
+ let sourceNode;
+ let targetNode;
+ let sourceIdx;
+ let targetIdx;
for (let j = 0; j < size; j += 1) {
if (nodes[j].id === edges[i].source) {
- source_node = nodes[j];
- source_idx = j;
+ sourceNode = nodes[j];
+ sourceIdx = j;
} else if (nodes[j].id === edges[i].target) {
- target_node = nodes[j];
- target_idx = j;
+ targetNode = nodes[j];
+ targetIdx = j;
}
}
- let dir = [ target_node.x - source_node.x, target_node.y - source_node.y ];
- let eucli_dis = Math.hypot(dir[0], dir[1]);
- eucli_dis = eucli_dis < 0.0001 ? 0.0001 : eucli_dis;
- dir[0] = dir[0] / eucli_dis;
- dir[1] = dir[1] / eucli_dis;
+ let dir = [ targetNode.x - sourceNode.x, targetNode.y - sourceNode.y ];
+ let eucliDis = Math.hypot(dir[0], dir[1]);
+ eucliDis = eucliDis < 0.0001 ? 0.0001 : eucliDis;
+ dir[0] = dir[0] / eucliDis;
+ dir[1] = dir[1] / eucliDis;
// the force
- if (prev_overlapping && iter < prevo_iter) eucli_dis = eucli_dis - widths[source_idx] - widths[target_idx];
- let Fa1 = eucli_dis;
+ if (prevOverlapping && iter < prevoIter) eucliDis = eucliDis - widths[sourceIdx] - widths[targetIdx];
+ let Fa1 = eucliDis;
let Fa2 = Fa1;
if (mode === 'linlog') {
- Fa1 = Math.log(1 + eucli_dis);
+ Fa1 = Math.log(1 + eucliDis);
Fa2 = Fa1;
}
- if (dissuade_hubs) {
- // Fa1 = eucli_dis / source_node.degree;
- // Fa2 = eucli_dis / target_node.degree;
- Fa1 = eucli_dis / degrees[source_idx];
- Fa2 = eucli_dis / degrees[target_idx];
+ if (dissuadeHubs) {
+ Fa1 = eucliDis / degrees[sourceIdx];
+ Fa2 = eucliDis / degrees[targetIdx];
}
- if (prev_overlapping && iter < prevo_iter && eucli_dis <= 0) {
+ if (prevOverlapping && iter < prevoIter && eucliDis <= 0) {
Fa1 = 0;
Fa2 = 0;
- } else if (prev_overlapping && iter < prevo_iter && eucli_dis > 0) {
- Fa1 = eucli_dis;
- Fa2 = eucli_dis;
+ } else if (prevOverlapping && iter < prevoIter && eucliDis > 0) {
+ Fa1 = eucliDis;
+ Fa2 = eucliDis;
}
- // Forces[2 * source_node.index] += Fa1 * dir[0];
- // Forces[2 * target_node.index] -= Fa2 * dir[0];
- // Forces[2 * source_node.index + 1] += Fa1 * dir[1];
- // Forces[2 * target_node.index + 1] -= Fa2 * dir[1];
- Forces[2 * idmap[source_node.id]] += Fa1 * dir[0];
- Forces[2 * idmap[target_node.id]] -= Fa2 * dir[0];
- Forces[2 * idmap[source_node.id] + 1] += Fa1 * dir[1];
- Forces[2 * idmap[target_node.id] + 1] -= Fa2 * dir[1];
+ Forces[2 * idmap[sourceNode.id]] += Fa1 * dir[0];
+ Forces[2 * idmap[targetNode.id]] -= Fa2 * dir[0];
+ Forces[2 * idmap[sourceNode.id] + 1] += Fa1 * dir[1];
+ Forces[2 * idmap[targetNode.id] + 1] -= Fa2 * dir[1];
dir = null;
}
return Forces;
}
-function getRepGraForces(nodes, edges, size, esize, prev_overlapping, dissuade_hubs, mode, iter, prevo_iter, Forces, kr, kr_prime, kg, center, widths, degrees) {
+function getRepGraForces(nodes, edges, size, esize, prevOverlapping, dissuadeHubs, mode, iter, prevoIter, Forces, kr, krPrime, kg, center, widths, degrees) {
for (let i = 0; i < size; i += 1) {
for (let j = i + 1; j < size; j += 1) {
let dir = [ nodes[j].x - nodes[i].x, nodes[j].y - nodes[i].y ];
- let eucli_dis = Math.hypot(dir[0], dir[1]);
- eucli_dis = eucli_dis < 0.0001 ? 0.0001 : eucli_dis;
- dir[0] = dir[0] / eucli_dis;
- dir[1] = dir[1] / eucli_dis;
+ let eucliDis = Math.hypot(dir[0], dir[1]);
+ eucliDis = eucliDis < 0.0001 ? 0.0001 : eucliDis;
+ dir[0] = dir[0] / eucliDis;
+ dir[1] = dir[1] / eucliDis;
- if (prev_overlapping && iter < prevo_iter) eucli_dis = eucli_dis - widths[i] - widths[j];
+ if (prevOverlapping && iter < prevoIter) eucliDis = eucliDis - widths[i] - widths[j];
- let Fr = kr * (degrees[i] + 1) * (degrees[j] + 1) / eucli_dis;
+ let Fr = kr * (degrees[i] + 1) * (degrees[j] + 1) / eucliDis;
- if (prev_overlapping && iter < prevo_iter && eucli_dis < 0) {
- Fr = kr_prime * (degrees[i] + 1) * (degrees[j] + 1);
- } else if (prev_overlapping && iter < prevo_iter && eucli_dis === 0) {
+ if (prevOverlapping && iter < prevoIter && eucliDis < 0) {
+ Fr = krPrime * (degrees[i] + 1) * (degrees[j] + 1);
+ } else if (prevOverlapping && iter < prevoIter && eucliDis === 0) {
Fr = 0;
- } else if (prev_overlapping && iter < prevo_iter && eucli_dis > 0) {
- Fr = kr * (degrees[i] + 1) * (degrees[j] + 1) / eucli_dis;
+ } else if (prevOverlapping && iter < prevoIter && eucliDis > 0) {
+ Fr = kr * (degrees[i] + 1) * (degrees[j] + 1) / eucliDis;
}
Forces[2 * i] -= Fr * dir[0];
Forces[2 * j] += Fr * dir[0];
@@ -186,9 +174,9 @@ function getRepGraForces(nodes, edges, size, esize, prev_overlapping, dissuade_h
// gravity
let dir = [ nodes[i].x - center.x, nodes[i].y - center.y ];
- const eucli_dis = Math.hypot(dir[0], dir[1]);
- dir[0] = dir[0] / eucli_dis;
- dir[1] = dir[1] / eucli_dis;
+ const eucliDis = Math.hypot(dir[0], dir[1]);
+ dir[0] = dir[0] / eucliDis;
+ dir[1] = dir[1] / eucliDis;
const Fg = kg * (degrees[i] + 1);
Forces[2 * i] -= Fg * dir[0];
Forces[2 * i + 1] -= Fg * dir[1];
@@ -197,7 +185,7 @@ function getRepGraForces(nodes, edges, size, esize, prev_overlapping, dissuade_h
return Forces;
}
-function getOptRepGraForces(nodes, edges, size, esize, prev_overlapping, dissuade_hubs, mode, iter, prevo_iter, Forces, kr, kr_prime, kg, ct, bodies, degrees) {
+function getOptRepGraForces(nodes, edges, size, esize, prevOverlapping, dissuadeHubs, mode, iter, prevoIter, Forces, kr, krPrime, kg, ct, bodies, degrees) {
let minx = 9e10,
maxx = -9e10,
miny = 9e10,
@@ -212,75 +200,75 @@ function getOptRepGraForces(nodes, edges, size, esize, prev_overlapping, dissuad
let width = Math.max(maxx - minx, maxy - miny);
- let quad_params = {
+ let quadParams = {
xmid: (maxx + minx) / 2,
ymid: (maxy + miny) / 2,
length: width,
- mass_center: ct,
+ massCenter: ct,
mass: size
};
- let quad = new Quad(quad_params);
- let quad_tree = new QuadTree(quad);
+ let quad = new Quad(quadParams);
+ let quadTree = new QuadTree(quad);
// build the tree, insert the nodes(quads) into the tree
for (let i = 0; i < size; i += 1) {
- if (bodies[i].in(quad)) quad_tree.insert(bodies[i]);
+ if (bodies[i].in(quad)) quadTree.insert(bodies[i]);
}
// update the repulsive forces and the gravity.
for (let i = 0; i < size; i += 1) {
bodies[i].resetForce();
- quad_tree.updateForce(bodies[i]);
+ quadTree.updateForce(bodies[i]);
Forces[2 * i] -= bodies[i].fx;
Forces[2 * i + 1] -= bodies[i].fy;
// gravity
let dir = [ nodes[i].x - ct.x, nodes[i].y - ct.y ];
- let eucli_dis = Math.hypot(dir[0], dir[1]);
- eucli_dis = eucli_dis < 0.0001 ? 0.0001 : eucli_dis;
- dir[0] = dir[0] / eucli_dis;
- dir[1] = dir[1] / eucli_dis;
+ let eucliDis = Math.hypot(dir[0], dir[1]);
+ eucliDis = eucliDis < 0.0001 ? 0.0001 : eucliDis;
+ dir[0] = dir[0] / eucliDis;
+ dir[1] = dir[1] / eucliDis;
let Fg = kg * (degrees[i] + 1);
Forces[2 * i] -= Fg * dir[0];
Forces[2 * i + 1] -= Fg * dir[1];
- eucli_dis = null;
+ eucliDis = null;
Fg = null;
dir = null;
}
- quad_params = null;
+ quadParams = null;
quad = null;
- quad_tree = null;
+ quadTree = null;
width = null;
return Forces;
}
-function updatePos(size, nodes, Forces, pre_Forces, SG, ks, ksmax, tao, degrees) {
+function updatePos(size, nodes, Forces, preForces, SG, ks, ksmax, tao, degrees) {
let swgns = [];
let trans = [];
// swg(G) and tra(G)
let swgG = 0;
let traG = 0;
for (let i = 0; i < size; i += 1) {
- const minus = [ Forces[2 * i] - pre_Forces[2 * i],
- Forces[2 * i + 1] - pre_Forces[2 * i + 1]
+ const minus = [ Forces[2 * i] - preForces[2 * i],
+ Forces[2 * i + 1] - preForces[2 * i + 1]
];
- const minus_norm = Math.hypot(minus[0], minus[1]);
- const add = [ Forces[2 * i] + pre_Forces[2 * i],
- Forces[2 * i + 1] + pre_Forces[2 * i + 1]
+ const minusNorm = Math.hypot(minus[0], minus[1]);
+ const add = [ Forces[2 * i] + preForces[2 * i],
+ Forces[2 * i + 1] + preForces[2 * i + 1]
];
- const add_norm = Math.hypot(add[0], add[1]);
+ const addNorm = Math.hypot(add[0], add[1]);
- swgns[i] = minus_norm;
- trans[i] = add_norm / 2;
+ swgns[i] = minusNorm;
+ trans[i] = addNorm / 2;
swgG += (degrees[i] + 1) * swgns[i];
traG += (degrees[i] + 1) * trans[i];
}
- let pre_SG = SG;
+ let preSG = SG;
SG = tao * traG / swgG;
- if (pre_SG !== 0) {
- SG = SG > (1.5 * pre_SG) ? (1.5 * pre_SG) : SG;
+ if (preSG !== 0) {
+ SG = SG > (1.5 * preSG) ? (1.5 * preSG) : SG;
}
// update the node positions
for (let i = 0; i < size; i += 1) {
@@ -289,13 +277,13 @@ function updatePos(size, nodes, Forces, pre_Forces, SG, ks, ksmax, tao, degrees)
absForce = absForce < 0.0001 ? 0.0001 : absForce;
const max = ksmax / absForce;
Sn = Sn > max ? max : Sn;
- const Dn_x = Sn * Forces[2 * i];
- const Dn_y = Sn * Forces[2 * i + 1];
- nodes[i].x += Dn_x;
- nodes[i].y += Dn_y;
+ const Dnx = Sn * Forces[2 * i];
+ const Dny = Sn * Forces[2 * i + 1];
+ nodes[i].x += Dnx;
+ nodes[i].y += Dny;
}
swgns = null;
trans = null;
- pre_SG = null;
+ preSG = null;
return [ nodes, SG ];
}
diff --git a/plugins/layout.forceAtlas2/quad.js b/plugins/layout.forceAtlas2/quad.js
index a8f1bd9756..fb468fd8ac 100644
--- a/plugins/layout.forceAtlas2/quad.js
+++ b/plugins/layout.forceAtlas2/quad.js
@@ -24,7 +24,7 @@ class Quad {
* the mass center of this quad
* @type {number}
*/
- this.mass_center = params.mass_center;
+ this.massCenter = params.massCenter;
/**
* the mass of this quad
* @type {number}
diff --git a/plugins/layout.forceAtlas2/quadTree/body.js b/plugins/layout.forceAtlas2/quadTree/body.js
deleted file mode 100644
index 8cdf842fa5..0000000000
--- a/plugins/layout.forceAtlas2/quadTree/body.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * @fileOverview body
- * @author shiwu.wyy@antfin.com
- */
-const G6 = require('@antv/g6');
-const Util = G6.Util;
-
-// represents a body(a point mass) and its position
-class Body {
- constructor(options) {
- Util.mix(this, {
- /**
- * the id of this body, the same with the node id
- * @type {number}
- */
- id: -1,
- /**
- * the position of this body
- * @type {number}
- */
- rx: null,
- /**
- * the position of this body
- * @type {number}
- */
- ry: null,
- /**
- * the force acting on this body
- * @type {number}
- */
- fx: 0,
- /**
- * the force acting on this body
- * @type {number}
- */
- fy: 0,
- /**
- * the mass of this body, =1 for a node
- * @type {number}
- */
- mass: 1,
- /**
- * the degree of the node represented by this body
- * @type {number}
- */
- degree: 1,
- /**
- * the parameter for repulsive force, = kr
- * @type {number}
- */
- G: 1
- }, options);
- }
- // returns the euclidean distance
- distanceTo(bo) {
- const dx = this.rx - bo.rx;
- const dy = this.ry - bo.ry;
- return Math.hypot(dx, dy);
- }
- setPos(x, y) {
- this.rx = x;
- this.ry = y;
- }
- // resets the forces
- resetForce() {
- this.fx = 0;
- this.fy = 0;
- }
- addForce(b) {
- const dx = b.rx - this.rx;
- const dy = b.ry - this.ry;
- let dist = Math.hypot(dx, dy);
- dist = dist < 0.0001 ? 0.0001 : dist;
- // the repulsive defined by force atlas 2
- const F = (this.G * (this.degree + 1) * (b.degree + 1)) / dist;
- this.fx += F * dx / dist;
- this.fy += F * dy / dist;
- }
- // if quad contains this body
- in(quad) {
- return quad.contains(this.rx, this.ry);
- }
- // returns a new body
- add(bo) {
- const nenw_mass = this.mass + bo.mass;
- const x = (this.rx * this.mass + bo.rx * bo.mass) / nenw_mass;
- const y = (this.ry * this.mass + bo.ry * bo.mass) / nenw_mass;
- const dg = this.degree + bo.degree;
- const params = { rx: x, ry: y, mass: nenw_mass, degree: dg };
- return new Body(params);
- }
-}
-
-module.exports = Body;
diff --git a/plugins/layout.forceAtlas2/quadTree/quad.js b/plugins/layout.forceAtlas2/quadTree/quad.js
deleted file mode 100644
index 5458cc8981..0000000000
--- a/plugins/layout.forceAtlas2/quadTree/quad.js
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * @fileOverview quad
- * @author shiwu.wyy@antfin.com
- */
-const G6 = require('@antv/g6');
-const Util = G6.Util;
-
-class Quad {
- constructor(options) {
- Util.mix(this, {
- /**
- * the center position of this quad
- * @type {number}
- */
- xmid: null,
- /**
- * the center position of this quad
- * @type {number}
- */
- ymid: null,
- /**
- * the length of this quad
- * @type {number}
- */
- length: 0,
- /**
- * the mass center of this quad
- * @type {number}
- */
- mass_center: [ 0, 0 ],
- /**
- * the mass of this quad
- * @type {number}
- */
- mass: 0
- }, options);
- }
- getLength() {
- return this.length;
- }
- contains(x, y) {
- const halfLen = this.length / 2;
- return (x <= this.xmid + halfLen &&
- x >= this.xmid - halfLen &&
- y <= this.ymid + halfLen &&
- y >= this.ymid - halfLen);
- }
- // northwest quadrant
- NW() {
- const x = this.xmid - this.length / 4;
- const y = this.ymid + this.length / 4;
- const len = this.length / 2;
- const params = { xmid: x, ymid: y, length: len };
- const NW = new Quad(params);
- return NW;
- }
- // northeast
- NE() {
- const x = this.xmid + this.length / 4;
- const y = this.ymid + this.length / 4;
- const len = this.length / 2;
- const params = { xmid: x, ymid: y, length: len };
- const NE = new Quad(params);
- return NE;
- }
- // southwest
- SW() {
- const x = this.xmid - this.length / 4;
- const y = this.ymid - this.length / 4;
- const len = this.length / 2;
- const params = { xmid: x, ymid: y, length: len };
- const SW = new Quad(params);
- return SW;
- }
- // southeast
- SE() {
- const x = this.xmid + this.length / 4;
- const y = this.ymid - this.length / 4;
- const len = this.length / 2;
- const params = { xmid: x, ymid: y, length: len };
- const SE = new Quad(params);
- return SE;
- }
-}
-module.exports = Quad;
diff --git a/plugins/layout.forceAtlas2/quadTree/quadTree.js b/plugins/layout.forceAtlas2/quadTree/quadTree.js
deleted file mode 100644
index 147221bdae..0000000000
--- a/plugins/layout.forceAtlas2/quadTree/quadTree.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * @fileOverview quadTree
- * @author shiwu.wyy@antfin.com
- */
-const G6 = require('@antv/g6');
-const Util = G6.Util;
-class QuadTree {
- // each quadtree represents a quadrant and an aggregate body
- // that represents all bodies inside the quadrant
- constructor(options) {
- Util.mix(this, {
- /**
- * (aggregated) body in this quad
- * @type {object}
- */
- body: null,
- /**
- * tree representing the northwest quadrant
- * @type {object}
- */
- quad: null,
- NW: null,
- NE: null,
- SW: null,
- SE: null,
- /**
- * threshold
- * @type {number}
- */
- theta: 0.5
- }, options);
- if (options != null) this.quad = options;
- }
- // insert a body(node) into the tree
- insert(bo) {
- // if this node does not contain a body, put the new body bo here
- if (this.body == null) {
- this.body = bo;
- return;
- }
- // internal node
- if (!this._isExternal()) {
- // update mass info
- this.body = this.body.add(bo);
- // insert body into quadrant
- this._putBody(bo);
- } else { // external node
- // divide this region into four children
- this.NW = new QuadTree(this.quad.NW());
- this.NE = new QuadTree(this.quad.NE());
- this.SW = new QuadTree(this.quad.SW());
- this.SE = new QuadTree(this.quad.SE());
-
- // insert this body and bo
- this._putBody(this.body);
- this._putBody(bo);
- // update the mass info
- this.body = this.body.add(bo);
-
- }
- }
- // inserts bo into a quad
- _putBody(bo) {
- if (bo.in(this.quad.NW())) this.NW.insert(bo);
- else if (bo.in(this.quad.NE())) this.NE.insert(bo);
- else if (bo.in(this.quad.SW())) this.SW.insert(bo);
- else if (bo.in(this.quad.SE())) this.SE.insert(bo);
- }
- _isExternal() {
- // four children are null
- return (this.NW == null && this.NE == null && this.SW == null && this.SE == null);
- }
- // update the forces
- updateForce(bo) {
- if (this.body == null || bo === this.body) {
- return;
- }
- // if the current node is external
- if (this._isExternal()) bo.addForce(this.body);
- // internal nodes
- else {
- const s = this.quad.getLength();
- const d = this.body.distanceTo(bo);
- // b is far enough
- if ((s / d) < this.theta) bo.addForce(this.body);
- else {
- this.NW.updateForce(bo);
- this.NE.updateForce(bo);
- this.SW.updateForce(bo);
- this.SE.updateForce(bo);
- }
- }
- }
-}
-module.exports = QuadTree;
diff --git a/plugins/template.maxSpanningForest/README.md b/plugins/template.maxSpanningForest/README.md
index 7f4ec71a60..c965bb0b94 100644
--- a/plugins/template.maxSpanningForest/README.md
+++ b/plugins/template.maxSpanningForest/README.md
@@ -13,9 +13,9 @@ template.maxSpanningForest for jiuselu graph analyzer, which is a plugin for gra
parameter for this plugin:
- layoutCfg: the configuration for layout.
- - max_iteration: the number of iteration for terminating the layout algorithm
+ - maxIteration: the number of iteration for terminating the layout algorithm
- kg: the gravity parameter for layout. The larger kg, more compact the graph, expecialy for the isolated subgraphs.
- - prev_overlapping: whether preventing the node overlapping
+ - prevOverlapping: whether preventing the node overlapping
- onLayoutComplete: a listener for layout completement. When the layout is complete, the loading div and img disappear.
- menuCfg: the configuration for menu
example:
@@ -46,10 +46,10 @@ To navigate an item (a node or edge) by id or item, if this item is not in the v
graph.navigate(item); // item or id
To create the menu which follows the mouse click:
- graph.createMenu(func, container_id);
+ graph.createMenu(func, containerId);
params:
- func is the onclick listener for the li '查看单页分析详情'
- - container_id is the DOM id of the menu container.
+ - containerId is the DOM id of the menu container.
## use
@@ -60,9 +60,9 @@ const MaxSpanningForestPlugin = G6.Plugins['template.maxSpanningForest'];
//the instances of plugins
const maxSpanningForest = new MaxSpanningForestPlugin({
layoutCfg: {
- max_iteration: 600,
+ maxIteration: 600,
kg: 10,
- prev_overlapping: true,
+ prevOverlapping: true,
onLayoutComplete: function () {
const minimap = document.getElementById('minimap');
const legend = document.getElementById('legend');
diff --git a/plugins/template.maxSpanningForest/index.js b/plugins/template.maxSpanningForest/index.js
index acf751a46f..4d9a728fd1 100644
--- a/plugins/template.maxSpanningForest/index.js
+++ b/plugins/template.maxSpanningForest/index.js
@@ -43,10 +43,10 @@ class Plugin {
kr: 120,
kg: 8.0,
mode: 'common',
- prev_overlapping: true,
- dissuade_hubs: false,
- max_iteration: 1000,
- barnes_hut: true,
+ prevOverlapping: true,
+ dissuadeHubs: false,
+ maxIteration: 1000,
+ barnesHut: true,
ks: 0.1,
ksmax: 10,
tao: 0.1,
@@ -55,13 +55,13 @@ class Plugin {
},
fisheye: true,
menu: null,
- pre_navi: {},
- edge_style: {
+ preNavi: {},
+ edgeStyle: {
endArrow: true,
stroke: '#4F7DAB',
strokeOpacity: 0.65
},
- node_style: {
+ nodeStyle: {
stroke: '#696969',
strokeOpacity: 0.4,
lineWidth: 1
@@ -148,21 +148,21 @@ class Plugin {
if (!model.isTreeEdge || typeof model.isTreeEdge === 'undefined') model.shape = 'quadraticCurve';
}
graph.edge({
- style: this.edge_style
+ style: this.edgeStyle
});
graph.node({
label: this.node_label,
- style: this.node_style
+ style: this.nodeStyle
});
}
activeItem(item) {
const graph = this.graph;
- const pre_navi = this.pre_navi;
+ const preNavi = this.preNavi;
if (Util.isString(item)) {
item = graph.find(item);
}
let style = {};
- let pre_style = {};
+ let preStyle = {};
if (item.type === 'node') {
style = {
stroke: '#fff',
@@ -170,29 +170,29 @@ class Plugin {
shadowColor: '#6a80aa',
shadowBlur: 20
};
- pre_style = this.node_style;
+ preStyle = this.nodeStyle;
} else if (item.type === 'edge') {
style = {
endArrow: true,
stroke: '#4C7295',
strokeOpacity: 1
};
- pre_style = this.edge_style;
+ preStyle = this.edgeStyle;
} else return;
// unactive the previous navigate node
- if (pre_navi !== {} && pre_navi !== null && pre_navi !== undefined && pre_navi.item !== null) {
- graph.update(pre_navi.item, {
- style: pre_navi.style
+ if (preNavi !== {} && preNavi !== null && preNavi !== undefined && preNavi.item !== null) {
+ graph.update(preNavi.item, {
+ style: preNavi.style
});
}
graph.update(item, {
style
});
- this.pre_navi = {
+ this.preNavi = {
item,
- style: pre_style
+ style: preStyle
};
}
setListener() {
@@ -207,7 +207,7 @@ class Plugin {
});
graph.on('node:mouseleave', ev => {
graph.update(ev.item, {
- style: this.node_style
+ style: this.nodeStyle
});
graph.css({
cursor: '-webkit-grab'
@@ -221,7 +221,7 @@ class Plugin {
});
graph.on('edge:mouseleave', ev => {
graph.update(ev.item, {
- style: this.edge_style
+ style: this.edgeStyle
});
});
@@ -230,9 +230,9 @@ class Plugin {
item
}) => {
if (shape && item.isNode) {
- const menu_x = item.getModel().x * graph.getMatrix()[0] + graph.getMatrix()[6];
- const menu_y = item.getModel().y * graph.getMatrix()[0] + graph.getMatrix()[7];
- this.menu.show(item, menu_x, menu_y);
+ const menuX = item.getModel().x * graph.getMatrix()[0] + graph.getMatrix()[6];
+ const menuY = item.getModel().y * graph.getMatrix()[0] + graph.getMatrix()[7];
+ this.menu.show(item, menuX, menuY);
graph.draw();
} else {
this.menu.hide();
diff --git a/plugins/template.maxSpanningForest/menu.js b/plugins/template.maxSpanningForest/menu.js
index 80e313a06a..c9c8385c8e 100644
--- a/plugins/template.maxSpanningForest/menu.js
+++ b/plugins/template.maxSpanningForest/menu.js
@@ -9,7 +9,7 @@ const Util = G6.Util;
class Menu {
constructor(options) {
Util.mix(this, {
- container_id: '',
+ containerId: '',
clickType: 'in'
}, options);
this.createMenu();
@@ -26,15 +26,15 @@ class Menu {
createMenu() {
const graph = this.graph;
const menuCfg = this.menuCfg;
- const container_id = this.container_id;
+ const containerId = this.containerId;
const menuHtml = ``;
const menu = Util.createDOM(menuHtml);
let parent = graph.getGraphContainer();
- if (container_id !== '' && container_id !== undefined) {
- parent = document.getElementById(container_id);
+ if (containerId !== '' && containerId !== undefined) {
+ parent = document.getElementById(containerId);
}
parent.appendChild(menu);
@@ -62,12 +62,12 @@ class Menu {
showSource(node) {
const graph = this.graph;
const {
- re_nodes,
- re_edges
+ reNodes,
+ reEdges
} = Util.extract(graph, 'in', 1, [ node ]);
graph.highlightSubgraph({
- re_nodes,
- re_edges
+ reNodes,
+ reEdges
});
// show the hided edge, which is not tree edge and it is in the es
// and the source and targert of the edge are both visible
@@ -75,7 +75,7 @@ class Menu {
Util.each(edges, edge => {
if (!edge.isVisible() && !edge.getModel().isTreeEdge &&
edge.getSource().isVisible() && edge.getTarget().isVisible()) {
- Util.each(re_edges, e => {
+ Util.each(reEdges, e => {
if (edge.id === e.id) {
edge.show();
}
@@ -89,12 +89,12 @@ class Menu {
showTargets(node) {
const graph = this.graph;
const {
- re_nodes,
- re_edges
+ reNodes,
+ reEdges
} = Util.extract(graph, 'out', 1, [ node ]);
graph.highlightSubgraph({
- re_nodes,
- re_edges
+ reNodes,
+ reEdges
});
// show the hided edge, which is not tree edge and it is in the es
// and the source and targert of the edge are both visible
@@ -102,7 +102,7 @@ class Menu {
Util.each(edges, edge => {
if (!edge.isVisible() && !edge.getModel().isTreeEdge &&
edge.getSource().isVisible() && edge.getTarget().isVisible()) {
- Util.each(re_edges, e => {
+ Util.each(reEdges, e => {
if (edge.id === e.id) {
edge.show();
}
@@ -115,12 +115,12 @@ class Menu {
showAll(node) {
const graph = this.graph;
const {
- re_nodes,
- re_edges
+ reNodes,
+ reEdges
} = Util.extract(graph, 'bi', 1, [ node ]);
graph.highlightSubgraph({
- re_nodes,
- re_edges
+ reNodes,
+ reEdges
});
// show the hided edge, which is not tree edge and it is in the es
// and the source and targert of the edge are both visible
@@ -128,7 +128,7 @@ class Menu {
Util.each(edges, edge => {
if (!edge.isVisible() && !edge.getModel().isTreeEdge &&
edge.getSource().isVisible() && edge.getTarget().isVisible()) {
- Util.each(re_edges, e => {
+ Util.each(reEdges, e => {
if (edge.id === e.id) {
edge.show();
}
diff --git a/plugins/tool.fisheye/index.js b/plugins/tool.fisheye/index.js
index 7f08df4053..c1025cfc12 100644
--- a/plugins/tool.fisheye/index.js
+++ b/plugins/tool.fisheye/index.js
@@ -9,8 +9,8 @@ const Fisheye = require('./tool');
class Plugin {
constructor(options) {
Util.mix(this, {
- ori_xs: [],
- ori_ys: []
+ oriXs: [],
+ oriYs: []
}, options);
}
init() {
@@ -23,10 +23,10 @@ class Plugin {
graph.on('mousemove', Util.throttle(ev => {
const nodes = graph.getNodes();
const size = nodes.length;
- if (this.ori_xs.length !== size) return;
+ if (this.oriXs.length !== size) return;
for (let i = 0; i < size; i += 1) {
- nodes[i].getModel().x = this.ori_xs[i];
- nodes[i].getModel().y = this.ori_ys[i];
+ nodes[i].getModel().x = this.oriXs[i];
+ nodes[i].getModel().y = this.oriYs[i];
}
fisheye.zoom(ev.x, ev.y);
graph.updateNodePosition();
@@ -39,16 +39,16 @@ class Plugin {
if (ev === undefined || ev.item === undefined) {
for (let i = 0; i < size; i++) {
if (nodes[i].getModel().x === undefined) return;
- this.ori_xs[i] = nodes[i].getModel().x;
- this.ori_ys[i] = nodes[i].getModel().y;
+ this.oriXs[i] = nodes[i].getModel().x;
+ this.oriYs[i] = nodes[i].getModel().y;
}
} else if (ev.item.type !== 'node' || (!ev.updateModel.x && !ev.updateModel.y)) return;
else {
const item = graph.find(ev.originModel.id);
for (let i = 0; i < size; i++) {
if (nodes[i].getModel().id === item.id) {
- this.ori_x[i] = ev.updateModel.x;
- this.ori_y[i] = ev.updateModel.y;
+ this.oriXs[i] = ev.updateModel.x;
+ this.oriYs[i] = ev.updateModel.y;
}
}
}
diff --git a/plugins/tool.fisheye/tool.js b/plugins/tool.fisheye/tool.js
index cd9567e462..c5889cf19d 100644
--- a/plugins/tool.fisheye/tool.js
+++ b/plugins/tool.fisheye/tool.js
@@ -42,9 +42,9 @@ class Tool {
const dist = Math.hypot(node.x - center[0], node.y - center[1]);
if (dist < radius) {
// take the center as the origin
- const moved_coords = [ node.x - center[0], node.y - center[1] ];
+ const movedCoords = [ node.x - center[0], node.y - center[1] ];
// transform to polar coordinates
- const { p, theta } = Rect2Polar(moved_coords[0], moved_coords[1]);
+ const { p, theta } = Rect2Polar(movedCoords[0], movedCoords[1]);
const pf = radius * (((d + 1) * (p / radius)) / (d * (p / radius) + 1)); // after fisheye zooming
// transform to rect coordinates
const { x, y } = Polar2Rect(pf, theta);
diff --git a/plugins/tool.highlightSubgraph/README.md b/plugins/tool.highlightSubgraph/README.md
index 7e3bca17d1..29e774187e 100644
--- a/plugins/tool.highlightSubgraph/README.md
+++ b/plugins/tool.highlightSubgraph/README.md
@@ -3,10 +3,10 @@
Highlight a subgraph and weaken the rest of the graph.
interface:
-- highlightSubgraph(hl_items)
+- highlightSubgraph(hlItems)
hightlight a subgraph
params:
- - hl_items: the items which will be highlighted
+ - hlItems: the items which will be highlighted
- restoreGraph()
restore the graph to the un-lighlighted style.
@@ -58,7 +58,7 @@ const graph = new G6.Graph({
graph.read(data);
const nodes = graph.getNodes();
const edges = graph.getEdges();
-const re_nodes = [nodes[0], nodes[1]];
-const re_edges = [edges[0]];
-graph.highlightSubgraph({re_nodes, re_edges});
+const reNodes = [nodes[0], nodes[1]];
+const reEdges = [edges[0]];
+graph.highlightSubgraph({reNodes, reEdges});
```
\ No newline at end of file
diff --git a/plugins/tool.highlightSubgraph/index.js b/plugins/tool.highlightSubgraph/index.js
index b7764aa796..1457eed394 100644
--- a/plugins/tool.highlightSubgraph/index.js
+++ b/plugins/tool.highlightSubgraph/index.js
@@ -35,11 +35,11 @@ class Plugin {
this.graph.restoreGraph = this.restoreGraph;
});
}
- highlightSubgraph(hl_items) {
+ highlightSubgraph(hlItems) {
this.restoreGraph();
// sort the group items
- const ns = hl_items.re_nodes;
- const es = hl_items.re_edges;
+ const ns = hlItems.reNodes;
+ const es = hlItems.reEdges;
const group = this.getItemGroup();
const items = this.getItems();
Util.each(items, i => {
diff --git a/plugins/tool.mapper/index.js b/plugins/tool.mapper/index.js
index ce20b2fe22..f99eb64891 100644
--- a/plugins/tool.mapper/index.js
+++ b/plugins/tool.mapper/index.js
@@ -58,7 +58,8 @@ class Plugin {
* 是否数据对齐
* @type {boolean}
*/
- nice: true
+ nice: true,
+ curRange: [ 0, 100 ]
}, {
itemType,
dim,
@@ -145,16 +146,12 @@ class Plugin {
domain = this._trainNumberScale(itemType, data);
}
}
-
const rangeLength = range.length;
const domainLength = domain.length;
- if (rangeLength !== domainLength) {
- const domainStep = (domain[1] - domain[0]) / (rangeLength - 1);
- Util.each(range, (v, i) => {
- domain[i] = domain[0] + i * domainStep;
- });
+ if (rangeLength !== domainLength && scaleType === 'Category') {
+ throw new Error('please set the same length of range to the domain!');
}
- if (domain[0] === domain[1]) {
+ if (domainLength === 2 && domain[0] === domain[1]) {
if (domain[0] > 0) {
domain[0] = 0;
} else if (domain[0] < 0) {
@@ -176,10 +173,18 @@ class Plugin {
const scaleType = this._getScaleType(data);
const channel = this.channel;
const graph = this.graph;
+
const containerId = this.legendCfg.containerId;
let legendContainer = this.legendCfg.container;
- if (containerId === undefined && legendContainer === undefined) {
- legendContainer = Util.createDOM('');
+ if (legendContainer === undefined) {
+ if (containerId === undefined) {
+ legendContainer = Util.createDOM('');
+ } else {
+ legendContainer = document.getElementById(containerId);
+ if (legendContainer === undefined || legendContainer === null) {
+ throw new Error('please set the container for the graph !');
+ }
+ }
const container = graph.getGraphContainer();
container.appendChild(legendContainer);
}
@@ -201,27 +206,30 @@ class Plugin {
}
// the listener to filter nodes and edges
const slider = legend.get('slider');
- slider.on('sliderchange', Util.throttle(ev => {
- const domain = this.scale.values;
- const cur_range = ev.range;
- const dim = this.dim;
- graph.addFilter(item => {
- if (item.isNode) {
- const val = item.model[dim];
- const percent = 100 * (val - domain[0]) / (domain[domain.length - 1] - domain[0]);
- if (percent > cur_range[1] || percent < cur_range[0]) return false;
- return true;
- } else if (item.isEdge) {
- const source_val = item.source.model[dim];
- const source_percent = 100 * (source_val - domain[0]) / (domain[domain.length - 1] - domain[0]);
- const source_visible = (source_percent <= cur_range[1] && source_percent >= cur_range[0]);
- const target_val = item.target.model[dim];
- const target_percent = 100 * (target_val - domain[0]) / (domain[domain.length - 1] - domain[0]);
- const target_visible = (target_percent <= cur_range[1] && target_percent >= cur_range[0]);
- if (!source_visible || !target_visible) return false;
- return true;
+ const domain = this.scale.values;
+ const dim = this.dim;
+ graph.addFilter(item => {
+ if (item.isNode) {
+ const val = item.model[dim];
+ const percent = 100 * (val - domain[0]) / (domain[domain.length - 1] - domain[0]);
+ if (percent > this.curRange[1] || percent < this.curRange[0]) {
+ return false;
}
- });
+ return true;
+ } else if (item.isEdge) {
+ const sourceVal = item.source.model[dim];
+ const sourcePercent = 100 * (sourceVal - domain[0]) / (domain[domain.length - 1] - domain[0]);
+ const sourceVisible = (sourcePercent <= this.curRange[1] && sourcePercent >= this.curRange[0]);
+ const targetVal = item.target.model[dim];
+ const targetPercent = 100 * (targetVal - domain[0]) / (domain[domain.length - 1] - domain[0]);
+ const targetVisible = (targetPercent <= this.curRange[1] && targetPercent >= this.curRange[0]);
+ if (!sourceVisible || !targetVisible) return false;
+ return true;
+ }
+ });
+
+ slider.on('sliderchange', Util.throttle(ev => {
+ this.curRange = ev.range;
graph.filter();
}, 100));
}
@@ -306,14 +314,14 @@ class Plugin {
const items = [];
Util.each(range, (val, i) => {
const percent = (domain[i] - scale.min) / (scale.max - scale.min);
- let item_text = domain[i];
- if (legendCfg.formatter !== undefined && legendCfg.formmater !== null) {
- item_text = legendCfg.formatter(domain[i]);
+ let itemText = domain[i];
+ if (legendCfg.formatter !== undefined && legendCfg.formatter !== null) {
+ itemText = legendCfg.formatter(domain[i]);
}
items.push({
text: domain[i],
attrValue: val,
- value: item_text, // the number label of the slider
+ value: itemText, // the number label of the slider
scaleValue: percent
});
});
@@ -361,14 +369,14 @@ class Plugin {
const items = [];
Util.each(range, (val, i) => {
const dom = domain[0] + domainStep * i;
- let item_text = dom;
+ let itemText = dom;
if (legendCfg.formatter !== undefined && legendCfg.formmater !== null) {
- item_text = legendCfg.formatter(dom);
+ itemText = legendCfg.formatter(dom);
}
items.push({
text: dom,
attrValue: val,
- value: item_text // the number label of the slider
+ value: itemText // the number label of the slider
});
});
const cfg = {
@@ -407,9 +415,8 @@ class Plugin {
return scale.scale(model[dim]) * 2;
} else if (channel === 'color') {
return color.mapping(model[dim])[0];
- } else if (itemType === 'edge' && channel === 'size') {
- return scale.scale(model[dim]);
}
+ // itemType === 'edge' && channel === 'size'
return scale.scale(model[dim]);
});
}
@@ -419,11 +426,6 @@ class Plugin {
max: domain[domain.length - 1]
};
switch (type) {
- case 'Linear':
- return Scale.linear({
- min: domain[0],
- max: domain[domain.length - 1]
- });
case 'Category':
return Scale.cat({
values: domain
diff --git a/plugins/tool.textDisplay/README.md b/plugins/tool.textDisplay/README.md
index d537250e5f..a8cb7cd8b1 100644
--- a/plugins/tool.textDisplay/README.md
+++ b/plugins/tool.textDisplay/README.md
@@ -1,6 +1,6 @@
## textDisplay
-Hide the labels when the width of the text are 2 times bigger than the parent node.
+Hide the labels when the width of the text is 2 times bigger than the parent node.
## use
diff --git a/plugins/tool.textDisplay/index.js b/plugins/tool.textDisplay/index.js
index 7c122fb381..84a69cec5a 100644
--- a/plugins/tool.textDisplay/index.js
+++ b/plugins/tool.textDisplay/index.js
@@ -29,10 +29,10 @@ class Plugin {
const label = node.getLabel();
const model = node.getModel();
const labelBox = label.getBBox();
- const label_width = labelBox.maxX - labelBox.minX;
- const node_width = model.size * scale;
- if (label_width === 0) return;
- const ratio = label_width / node_width;
+ const labelWidth = labelBox.maxX - labelBox.minX;
+ const nodeWidth = model.size * scale;
+ if (labelWidth === 0) return;
+ const ratio = labelWidth / nodeWidth;
if (ratio > 2) {
label.hide();
} else {
diff --git a/plugins/util.extractSubgraph/index.js b/plugins/util.extractSubgraph/index.js
index 3e3cfb7954..b1a8acf528 100644
--- a/plugins/util.extractSubgraph/index.js
+++ b/plugins/util.extractSubgraph/index.js
@@ -10,58 +10,58 @@ const Util = G6.Util;
const extractSubgraph = {
extract(graph, type, step, focusNodes) {
- const re_edges = [];
+ const reEdges = [];
Util.each(focusNodes, fn => {
if (type === 'in') {
- const in_edges = fn.getInEdges();
- Util.each(in_edges, ie => {
- re_edges.push(ie);
+ const inEdges = fn.getInEdges();
+ Util.each(inEdges, ie => {
+ reEdges.push(ie);
});
} else if (type === 'out') {
- const out_edges = fn.getOutEdges();
- Util.each(out_edges, oe => {
- re_edges.push(oe);
+ const outEdges = fn.getOutEdges();
+ Util.each(outEdges, oe => {
+ reEdges.push(oe);
});
} else {
- const in_edges = fn.getInEdges();
- Util.each(in_edges, ie => {
- re_edges.push(ie);
+ const inEdges = fn.getInEdges();
+ Util.each(inEdges, ie => {
+ reEdges.push(ie);
});
- const out_edges = fn.getOutEdges();
- Util.each(out_edges, oe => {
- re_edges.push(oe);
+ const outEdges = fn.getOutEdges();
+ Util.each(outEdges, oe => {
+ reEdges.push(oe);
});
}
});
- const re_nodes = [];
+ const reNodes = [];
Util.each(focusNodes, fn => {
- re_nodes.push(fn);
- Util.each(re_edges, e => {
+ reNodes.push(fn);
+ Util.each(reEdges, e => {
const source = e.getSource();
const target = e.getTarget();
- if (source.id !== fn.id) re_nodes.push(source);
- if (target.id !== fn.id) re_nodes.push(target);
+ if (source.id !== fn.id) reNodes.push(source);
+ if (target.id !== fn.id) reNodes.push(target);
});
});
return {
- re_nodes,
- re_edges
+ reNodes,
+ reEdges
};
},
- setZIndex(ns, es, min_z) {
+ setZIndex(ns, es, minZ) {
const graph = this.graph;
const nodes = graph.getNodes();
const edges = graph.getEdges();
Util.each(nodes, node => {
Util.each(ns, n => {
- if (node.id === n.id) node.getGraphicGroup().setSilent('zIndex', min_z + 2);
+ if (node.id === n.id) node.getGraphicGroup().setSilent('zIndex', minZ + 2);
});
});
Util.each(edges, edge => {
Util.each(es, e => {
- if (edge.id === e.id) edge.getGraphicGroup().setSilent('zIndex', min_z + 1);
+ if (edge.id === e.id) edge.getGraphicGroup().setSilent('zIndex', minZ + 1);
});
});
graph.getItemGroup().sort();
diff --git a/src/graph.js b/src/graph.js
index ad95ca6374..772a42fb3e 100755
--- a/src/graph.js
+++ b/src/graph.js
@@ -106,7 +106,7 @@ class Graph extends Base {
const cfg = {};
Mixins.forEach(Mixin => {
- Util.mix(cfg, Mixin.CFG, inputCfg);
+ Util.mix(cfg, Util.cloneDeep(Mixin.CFG), inputCfg);
});
super(cfg);
// plugin should init before all
diff --git a/src/version.js b/src/version.js
index 4b75c7b43d..3f92dc4960 100755
--- a/src/version.js
+++ b/src/version.js
@@ -1 +1 @@
-module.exports = '2.1.0-beta';
+module.exports = '2.1.0-beta.3';
diff --git a/test/unit/plugins/layout.forceAtlas2-spec.js b/test/unit/plugins/layout.forceAtlas2-spec.js
index 4d391b9e71..c03a281d23 100644
--- a/test/unit/plugins/layout.forceAtlas2-spec.js
+++ b/test/unit/plugins/layout.forceAtlas2-spec.js
@@ -3,130 +3,145 @@ const Layout = require('../../../build/plugin.layout.forceAtlas2');
const expect = require('chai').expect;
const Util = G6.Util;
-// document.body.appendChild(Util.createDOM(`
-//
-// `));
+document.body.appendChild(Util.createDOM(`
+
+`));
-// describe('custom layout test', () => {
-// const layout = new Layout();
-// const data = {
-// nodes: [{
-// id: 'node1'
-// }, {
-// id: 'node2'
-// }, {
-// id: 'node3'
-// }],
-// edges: [{
-// target: 'node2',
-// source: 'node1'
-// }, {
-// target: 'node2',
-// source: 'node3'
-// }]
-// };
-// const graph = new G6.Graph({
-// container: 'mountNode',
-// width: 500,
-// height: 500,
-// plugins: [ layout ]
-// });
+describe('custom layout test', () => {
+ const originInnerHTML = document.getElementById('mountNode').innerHTML;
+ const layout = new Layout();
+ const data = {
+ nodes: [{
+ id: 'node1'
+ }, {
+ id: 'node2'
+ }, {
+ id: 'node3'
+ }],
+ edges: [{
+ target: 'node2',
+ source: 'node1'
+ }, {
+ target: 'node2',
+ source: 'node3'
+ }]
+ };
+ const graph = new G6.Graph({
+ container: 'mountNode',
+ width: 500,
+ height: 500,
+ plugins: [ layout ]
+ });
-// graph.read(data);
-// it('layout node positions', () => {
-// const node1Model = graph.find('node1').getModel();
-// expect(node1Model.x).not.eql(undefined);
-// expect(node1Model.y).not.eql(undefined);
-// });
-// it('graph destroy', () => {
-// graph.destroy();
-// });
-// });
+ graph.read(data);
+ it('graph render', () => {
+ expect(document.getElementById('mountNode').innerHTML).not.eql(originInnerHTML);
+ });
+ it('layout node positions', () => {
+ graph.on('afterlayout', () => {
+ const node1Model = graph.find('node1').getModel();
+ expect(node1Model.x).not.eql(undefined);
+ expect(node1Model.y).not.eql(undefined);
+ });
+ });
+ it('graph destroy', () => {
+ graph.on('afterlayout', () => {
+ graph.destroy();
+ expect(document.getElementById('mountNode').innerHTML).eql(originInnerHTML);
+ });
+ });
+});
-// describe('node nonoverlapping test', () => {
-// const layout = new Layout({ prevOverlapping: true });
-// const data = {
-// nodes: [{
-// id: 'node1'
-// }, {
-// id: 'node2'
-// }, {
-// id: 'node3'
-// }],
-// edges: [{
-// target: 'node2',
-// source: 'node1'
-// }, {
-// target: 'node2',
-// source: 'node3'
-// }]
-// };
-// const graph = new G6.Graph({
-// container: 'mountNode',
-// width: 500,
-// height: 500,
-// plugins: [ layout ]
-// });
-// graph.read(data);
-// it('overlapping', () => {
-// const node1Model = graph.find('node1').getModel();
-// const node2Model = graph.find('node2').getModel();
-// const node3Model = graph.find('node3').getModel();
-// const node1BBox = node1Model.getBBox();
-// const node2BBox = node2Model.getBBox();
-// const node3BBox = node3Model.getBBox();
-// const node1Radius = (node1BBox.maxX - node1BBox.minX) / 2;
-// const node2Radius = (node2BBox.maxX - node2BBox.minX) / 2;
-// const node3Radius = (node3BBox.maxX - node3BBox.minX) / 2;
-// const dist12 = Math.plot(node1Model.x - node2Model.x, node1Model.y - node2Model.y);
-// const dist23 = Math.plot(node2Model.x - node3Model.x, node2Model.y - node3Model.y);
-// const dist13 = Math.plot(node1Model.x - node3Model.x, node1Model.y - node3Model.y);
-// expect(node1Radius - node2Radius <= dist12).eql(true);
-// expect(node2Radius - node3Radius <= dist23).eql(true);
-// expect(node1Radius - node3Radius <= dist13).eql(true);
-// });
-// it('layout node positions', () => {
-// const node1Model = graph.find('node1').getModel();
-// expect(node1Model.x).not.eql(undefined);
-// expect(node1Model.y).not.eql(undefined);
-// });
-// it('graph destroy', () => {
-// graph.destroy();
-// });
-// });
+describe('node nonoverlapping test', () => {
+ const layout = new Layout({ prevOverlapping: true });
+ const data = {
+ nodes: [{
+ id: 'node1'
+ }, {
+ id: 'node2'
+ }, {
+ id: 'node3'
+ }],
+ edges: [{
+ target: 'node2',
+ source: 'node1'
+ }, {
+ target: 'node2',
+ source: 'node3'
+ }]
+ };
+ const graph = new G6.Graph({
+ container: 'mountNode',
+ width: 500,
+ height: 500,
+ plugins: [ layout ]
+ });
+ graph.read(data);
+ it('overlapping', () => {
+ graph.on('afterlayout', () => {
+ const node1Model = graph.find('node1').getModel();
+ const node2Model = graph.find('node2').getModel();
+ const node3Model = graph.find('node3').getModel();
+ const node1BBox = node1Model.getBBox();
+ const node2BBox = node2Model.getBBox();
+ const node3BBox = node3Model.getBBox();
+ const node1Radius = (node1BBox.maxX - node1BBox.minX) / 2;
+ const node2Radius = (node2BBox.maxX - node2BBox.minX) / 2;
+ const node3Radius = (node3BBox.maxX - node3BBox.minX) / 2;
+ const dist12 = Math.plot(node1Model.x - node2Model.x, node1Model.y - node2Model.y);
+ const dist23 = Math.plot(node2Model.x - node3Model.x, node2Model.y - node3Model.y);
+ const dist13 = Math.plot(node1Model.x - node3Model.x, node1Model.y - node3Model.y);
+ expect(node1Radius - node2Radius <= dist12).eql(true);
+ expect(node2Radius - node3Radius <= dist23).eql(true);
+ expect(node1Radius - node3Radius <= dist13).eql(true);
+ });
+ });
+ it('layout node positions', () => {
+ graph.on('afterlayout', () => {
+ const node1Model = graph.find('node1').getModel();
+ expect(node1Model.x).not.eql(undefined);
+ expect(node1Model.y).not.eql(undefined);
+ });
+ });
+ it('graph destroy', () => {
+ graph.destroy();
+ });
+});
-// describe('barnes hut optimiazation test', () => {
-// const layout = new Layout();
-// const data = {
-// nodes: [{
-// id: 'node1'
-// }, {
-// id: 'node2'
-// }, {
-// id: 'node3'
-// }],
-// edges: [{
-// target: 'node2',
-// source: 'node1'
-// }, {
-// target: 'node2',
-// source: 'node3'
-// }]
-// };
-// const graph = new G6.Graph({
-// container: 'mountNode',
-// width: 500,
-// height: 500,
-// plugins: [ layout ]
-// });
+describe('barnes hut optimiazation test', () => {
+ const layout = new Layout();
+ const data = {
+ nodes: [{
+ id: 'node1'
+ }, {
+ id: 'node2'
+ }, {
+ id: 'node3'
+ }],
+ edges: [{
+ target: 'node2',
+ source: 'node1'
+ }, {
+ target: 'node2',
+ source: 'node3'
+ }]
+ };
+ const graph = new G6.Graph({
+ container: 'mountNode',
+ width: 500,
+ height: 500,
+ plugins: [ layout ]
+ });
-// graph.read(data);
-// it('layout node positions', () => {
-// const node1Model = graph.find('node1').getModel();
-// expect(node1Model.x).not.eql(undefined);
-// expect(node1Model.y).not.eql(undefined);
-// });
-// it('graph destroy', () => {
-// graph.destroy();
-// });
-// });
+ graph.read(data);
+ it('layout node positions', () => {
+ graph.on('afterlayout', () => {
+ const node1Model = graph.find('node1').getModel();
+ expect(node1Model.x).not.eql(undefined);
+ expect(node1Model.y).not.eql(undefined);
+ });
+ });
+ it('graph destroy', () => {
+ graph.destroy();
+ });
+});
diff --git a/test/unit/plugins/tool.mapper-spec.js b/test/unit/plugins/tool.mapper-spec.js
index da542ee26b..1589faa65e 100644
--- a/test/unit/plugins/tool.mapper-spec.js
+++ b/test/unit/plugins/tool.mapper-spec.js
@@ -2,15 +2,18 @@ const G6 = require('../../../src/index');
const Mapper = require('../../../plugins/tool.mapper/');
const expect = require('chai').expect;
const Util = G6.Util;
-const Simulate = require('event-simulate');
document.body.appendChild(Util.createDOM(`
`));
@@ -62,15 +65,61 @@ describe('node size mapper test', () => {
});
it('legend destroy', () => {
graph.destroy();
- expect(document.getElementById('nodeSizeLegend').innerHTML).eql(originInnerHTML);
+ expect(document.getElementById('nodeSizeLegend')).eql(null);
});
});
-describe('node color mapper test', () => {
- const originInnerHTML = document.getElementById('nodeColorLegend').innerHTML;
+describe('node color mapper domain length test', () => {
+ const fn = function() {
+ const nodeSizeMapper = new Mapper('node', 'class', 'color', [ '#ff0000', '#00ff00' ], {
+ legendCfg: {
+ layout: 'vertical'
+ }
+ });
+ const data = {
+ nodes: [{
+ id: 'node1',
+ x: 100,
+ y: 200,
+ class: 'class1'
+ }, {
+ id: 'node2',
+ x: 300,
+ y: 200,
+ class: 'class2'
+ }, {
+ id: 'node3',
+ x: 400,
+ y: 200,
+ class: 'class3'
+ }],
+ edges: [{
+ target: 'node2',
+ source: 'node1'
+ }]
+ };
+ const graph = new G6.Graph({
+ container: 'mountNode',
+ width: 500,
+ height: 500,
+ plugins: [ nodeSizeMapper ]
+ });
+ graph.read(data);
+ };
+
+ it('legend render', () => {
+ expect(fn).to.Throw();
+ });
+});
+
+describe('node color mapper domian equals 1 test', () => {
+ const originInnerHTML = document.getElementById('nodeColorLegend1').innerHTML;
const nodeSizeMapper = new Mapper('node', 'weight', 'color', [ '#ff0000', '#00ff00' ], {
+ scaleCfg: {
+ type: 'pow'
+ },
legendCfg: {
- containerId: 'nodeColorLegend',
+ containerId: 'nodeColorLegend1',
layout: 'vertical'
}
});
@@ -84,7 +133,7 @@ describe('node color mapper test', () => {
id: 'node2',
x: 300,
y: 200,
- weight: 2
+ weight: 1
}],
edges: [{
target: 'node2',
@@ -99,20 +148,123 @@ describe('node color mapper test', () => {
});
graph.read(data);
it('legend render', () => {
- expect(document.getElementById('nodeColorLegend').innerHTML).not.eql(originInnerHTML);
+ expect(document.getElementById('nodeColorLegend1').innerHTML).not.eql(originInnerHTML);
+ });
+ it('node color mapper', () => {
+ const node1Model = graph.find('node1').getModel();
+ const node2Model = graph.find('node2').getModel();
+ expect(node1Model.color).eql('#00ff00');
+ expect(node2Model.color).eql('#00ff00');
+ });
+ it('legend destroy', () => {
+ graph.destroy();
+ expect(document.getElementById('nodeColorLegend1')).eql(null);
+ });
+});
+
+describe('node color mapper domian equals 0 test', () => {
+ const originInnerHTML = document.getElementById('nodeColorLegend2').innerHTML;
+ const nodeSizeMapper = new Mapper('node', 'weight', 'color', [ '#ff0000', '#00ff00' ], {
+ scaleCfg: {
+ type: 'pow'
+ },
+ legendCfg: {
+ containerId: 'nodeColorLegend2',
+ layout: '',
+ formatter: num => {
+ return num * num;
+ }
+ }
+ });
+ const data = {
+ nodes: [{
+ id: 'node1',
+ x: 100,
+ y: 200,
+ weight: 0
+ }, {
+ id: 'node2',
+ x: 300,
+ y: 200,
+ weight: 0
+ }],
+ edges: [{
+ target: 'node2',
+ source: 'node1'
+ }]
+ };
+ const graph = new G6.Graph({
+ container: 'mountNode',
+ width: 500,
+ height: 500,
+ plugins: [ nodeSizeMapper ]
+ });
+ graph.read(data);
+ it('legend render', () => {
+ expect(document.getElementById('nodeColorLegend2').innerHTML).not.eql(originInnerHTML);
+ });
+ it('node color mapper', () => {
+ const node1Model = graph.find('node1').getModel();
+ const node2Model = graph.find('node2').getModel();
+ expect(node1Model.color).eql('#00ff00');
+ expect(node2Model.color).eql('#00ff00');
+ });
+ it('legend destroy', () => {
+ graph.destroy();
+ expect(document.getElementById('nodeColorLegend2')).eql(null);
+ });
+});
+
+describe('node color mapper domian equals -1 test', () => {
+ const originInnerHTML = document.getElementById('nodeColorLegend3').innerHTML;
+ const nodeSizeMapper = new Mapper('node', 'weight', 'color', [ '#ff0000', '#00ff00' ], {
+ scaleCfg: {
+ type: 'pow'
+ },
+ legendCfg: {
+ containerId: 'nodeColorLegend3'
+ }
+ });
+ const data = {
+ nodes: [{
+ id: 'node1',
+ x: 100,
+ y: 200,
+ weight: -1
+ }, {
+ id: 'node2',
+ x: 300,
+ y: 200,
+ weight: -1
+ }],
+ edges: [{
+ target: 'node2',
+ source: 'node1'
+ }]
+ };
+ const graph = new G6.Graph({
+ container: 'mountNode',
+ width: 500,
+ height: 500,
+ plugins: [ nodeSizeMapper ]
+ });
+ graph.read(data);
+ it('legend render', () => {
+ expect(document.getElementById('nodeColorLegend3').innerHTML).not.eql(originInnerHTML);
});
it('node color mapper', () => {
const node1Model = graph.find('node1').getModel();
const node2Model = graph.find('node2').getModel();
expect(node1Model.color).eql('#ff0000');
- expect(node2Model.color).eql('#00ff00');
+ expect(node2Model.color).eql('#ff0000');
});
it('legend destroy', () => {
graph.destroy();
- expect(document.getElementById('nodeColorLegend').innerHTML).eql(originInnerHTML);
+ expect(document.getElementById('nodeColorLegend3')).eql(null);
});
});
+
describe('edge size mapper test', () => {
const edgeSizeMapper = new Mapper('edge', 'weight', 'size', [ 10, 50 ], {
legendCfg: null
@@ -159,6 +311,53 @@ describe('edge size mapper test', () => {
});
});
+describe('edge size mapper vertical test', () => {
+ const edgeSizeMapper = new Mapper('edge', 'weight', 'size', [ 10, 50 ], {
+ legendCfg: {
+ layout: 'vertical'
+ }
+ });
+ const data = {
+ nodes: [{
+ id: 'node1',
+ x: 100,
+ y: 200
+ }, {
+ id: 'node2',
+ x: 300,
+ y: 200
+ }, {
+ id: 'node3',
+ x: 400,
+ y: 200
+ }],
+ edges: [{
+ target: 'node2',
+ source: 'node1',
+ weight: 1
+ }, {
+ target: 'node2',
+ source: 'node3',
+ weight: 2
+ }]
+ };
+ const graph = new G6.Graph({
+ container: 'mountNode',
+ width: 500,
+ height: 500,
+ plugins: [ edgeSizeMapper ]
+ });
+ graph.read(data);
+ it('edge size mapper', () => {
+ const edges = graph.getEdges();
+ const edge1Model = edges[0].getModel();
+ const edge2Model = edges[1].getModel();
+ const size1 = edge1Model.size;
+ const size2 = edge2Model.size;
+ expect(size1).eql(10);
+ expect(size2).eql(50);
+ });
+});
describe('node color category mapper test', () => {
const originInnerHTML = document.getElementById('nodeColorCatLegend').innerHTML;
@@ -202,12 +401,11 @@ describe('node color category mapper test', () => {
});
it('legend destroy', () => {
graph.destroy();
- expect(document.getElementById('nodeColorCatLegend').innerHTML).eql(originInnerHTML);
+ expect(document.getElementById('nodeColorCatLegend')).eql(null);
});
});
describe('node size mapper with formatter test', () => {
- const originInnerHTML = document.getElementById('nodeSizeFormatLegend').innerHTML;
const nodeSizeMapper = new Mapper('node', 'weight', 'size', [ 10, 50 ], {
legendCfg: {
formatter: num => {
@@ -239,9 +437,6 @@ describe('node size mapper with formatter test', () => {
plugins: [ nodeSizeMapper ]
});
graph.read(data);
- it('legend render', () => {
- expect(document.getElementById('nodeSizeFormatLegend').innerHTML).not.eql(originInnerHTML);
- });
it('node size mapper', () => {
const node1Model = graph.find('node1').getModel();
const node2Model = graph.find('node2').getModel();
@@ -250,9 +445,45 @@ describe('node size mapper with formatter test', () => {
expect(size1).eql(10);
expect(size2).eql(50);
});
- it('legend destroy', () => {
- graph.destroy();
- expect(document.getElementById('nodeSizeFormatLegend').innerHTML).eql(originInnerHTML);
+});
+
+
+describe('container undefined test', () => {
+ const fn = function() {
+ const nodeSizeMapper = new Mapper('node', 'weight', 'size', [ 10, 50 ], {
+ legendCfg: {
+ containerId: 'undefinedDOM'
+ }
+ });
+ const data = {
+ nodes: [{
+ id: 'node1',
+ x: 100,
+ y: 200,
+ weight: 2
+ }, {
+ id: 'node2',
+ x: 300,
+ y: 200,
+ weight: 3
+ }],
+ edges: [{
+ target: 'node2',
+ source: 'node1'
+ }]
+ };
+ const graph = new G6.Graph({
+ container: 'mountNode',
+ width: 500,
+ height: 500,
+ plugins: [ nodeSizeMapper ]
+ });
+ graph.read(data);
+
+ };
+
+ it('legend render', () => {
+ expect(fn).to.Throw();
});
});
@@ -268,7 +499,7 @@ describe('slider test', () => {
id: 'node1',
x: 100,
y: 200,
- weight: 2
+ weight: 1
}, {
id: 'node2',
x: 300,
@@ -286,16 +517,11 @@ describe('slider test', () => {
height: 500,
plugins: [ nodeSizeMapper ]
});
- const mouseEventWrapper = graph.getMouseEventWrapper();
graph.read(data);
it('legend sliderchange', () => {
- const node1Model = graph.find('node1').getModel();
- const clientPoint = graph.getClientPoint(node1Model);
- Simulate.simulate(mouseEventWrapper, 'sliderchange', {
- clientX: clientPoint.x - 50,
- clientY: clientPoint.y
- });
- expect(document.getElementsById('sliderChangeTestDiv')).not.eql(undefined);
+ const slider = nodeSizeMapper.legend.get('slider');
+ slider.emit('sliderchange', { range: [ 0, 50 ] });
+ expect(document.getElementById('sliderChangeTestDiv')).not.eql(undefined);
});
});