Merge pull request #445 from antvis/manyChange

many change
This commit is contained in:
Yanyan Wang 2018-09-03 15:54:46 +08:00 committed by GitHub
commit 4f3736665c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 111717 additions and 625 deletions

View File

@ -2,6 +2,24 @@
---
#### 2.1.0
`2018-09-03`
* feat: svg render
* feat: plugin.layout.forceAtlas2
* feat: plugin.tool.fisheye
* feat: plugin.tool.textDisplay
* feat: plugin.tool.grid
* feat: plugin.template.tableSankey
* feat: plugin.edge.polyline
#### 2.0.5
`2018-07-12`
improve: add g6 arrow
#### 2.0.4
`2018-07-12`

File diff suppressed because it is too large Load Diff

5381
demos/assets/data/tr.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,530 @@
[
{
"number": 1,
"president": "George Washington",
"birth_year": 1732,
"death_year": 1799,
"took_office": "1789-04-30",
"left_office": "1797-03-04",
"party": "No Party",
"age_decade": 50,
"sgin": "Pisces",
"birth_place": "Virginia"
},
{
"number": 2,
"president": "John Adams",
"birth_year": 1735,
"death_year": 1826,
"took_office": "1797-03-04",
"left_office": "1801-03-04",
"party": "Federalist",
"age_decade": 60,
"sgin": "Scorpio",
"birth_place": "Massachusetts"
},
{
"number": 3,
"president": "Thomas Jefferson",
"birth_year": 1743,
"death_year": 1826,
"took_office": "1801-03-04",
"left_office": "1809-03-04",
"party": "Democratic-Republican",
"age_decade": 50,
"sgin": "Aries",
"birth_place": "Virginia"
},
{
"number": 4,
"president": "James Madison",
"birth_year": 1751,
"death_year": 1836,
"took_office": "1809-03-04",
"left_office": "1817-03-04",
"party": "Democratic-Republican",
"age_decade": 50,
"sgin": "Pisces",
"birth_place": "Virginia"
},
{
"number": 5,
"president": "James Monroe",
"birth_year": 1758,
"death_year": 1831,
"took_office": "1817-03-04",
"left_office": "1825-03-04",
"party": "Democratic-Republican",
"age_decade": 50,
"sgin": "Taurus",
"birth_place": "Virginia"
},
{
"number": 6,
"president": "John Quincy Adams",
"birth_year": 1767,
"death_year": 1848,
"took_office": "1825-03-04",
"left_office": "1829-03-04",
"party": "Democratic-Republican",
"age_decade": 50,
"sgin": "Cancer",
"birth_place": "Massachusetts"
},
{
"number": 7,
"president": "Andrew Jackson",
"birth_year": 1767,
"death_year": 1845,
"took_office": "1829-03-04",
"left_office": "1837-03-04",
"party": "Democratic",
"age_decade": 60,
"sgin": "Pisces",
"birth_place": "South Carolina"
},
{
"number": 8,
"president": "Martin Van Buren",
"birth_year": 1782,
"death_year": 1862,
"took_office": "1837-03-04",
"left_office": "1841-03-04",
"party": "Democratic",
"age_decade": 50,
"sgin": "Sagittarius",
"birth_place": "New York"
},
{
"number": 9,
"president": "William Henry Harrison",
"birth_year": 1773,
"death_year": 1841,
"took_office": "1841-03-04",
"left_office": "1841-04-04",
"party": "Whig",
"age_decade": 60,
"sgin": "Aquarius",
"birth_place": "Virginia"
},
{
"number": 10,
"president": "John Tyler",
"birth_year": 1790,
"death_year": 1862,
"took_office": "1841-04-04",
"left_office": "1845-03-04",
"party": "Whig",
"age_decade": 50,
"sgin": "Aries",
"birth_place": "Virginia"
},
{
"number": 11,
"president": "James K. Polk",
"birth_year": 1795,
"death_year": 1849,
"took_office": "1845-03-04",
"left_office": "1849-03-04",
"party": "Democratic",
"age_decade": 50,
"sgin": "Scorpio",
"birth_place": "North Carolina"
},
{
"number": 12,
"president": "Zachary Taylor",
"birth_year": 1784,
"death_year": 1850,
"took_office": "1849-03-04",
"left_office": "1850-07-09",
"party": "Whig",
"age_decade": 60,
"sgin": "Sagittarius",
"birth_place": "Virginia"
},
{
"number": 13,
"president": "Millard Fillmore",
"birth_year": 1800,
"death_year": 1874,
"took_office": "1850-07-09",
"left_office": "1853-03-04",
"party": "Whig",
"age_decade": 50,
"sgin": "Capricorns",
"birth_place": "New York"
},
{
"number": 14,
"president": "Franklin Pierce",
"birth_year": 1804,
"death_year": 1869,
"took_office": "1853-03-04",
"left_office": "1857-03-04",
"party": "Democratic",
"age_decade": 40,
"sgin": "Sagittarius",
"birth_place": "New Hampshire"
},
{
"number": 15,
"president": "James Buchanan",
"birth_year": 1791,
"death_year": 1868,
"took_office": "1857-03-04",
"left_office": "1861-03-04",
"party": "Democratic",
"age_decade": 60,
"sgin": "Taurus",
"birth_place": "Pennsylvania"
},
{
"number": 16,
"president": "Abraham Lincoln",
"birth_year": 1809,
"death_year": 1865,
"took_office": "1861-03-04",
"left_office": "1865-04-15",
"party": "Republican",
"age_decade": 50,
"sgin": "Aquarius",
"birth_place": "Kentucky"
},
{
"number": 17,
"president": "Andrew Johnson",
"birth_year": 1808,
"death_year": 1875,
"took_office": "1865-04-15",
"left_office": "1869-03-04",
"party": "Democratic",
"age_decade": 50,
"sgin": "Capricorns",
"birth_place": "North Carolina"
},
{
"number": 18,
"president": "Ulysses S. Grant",
"birth_year": 1822,
"death_year": 1885,
"took_office": "1869-03-04",
"left_office": "1877-03-04",
"party": "Republican",
"age_decade": 40,
"sgin": "Taurus",
"birth_place": "Ohio"
},
{
"number": 19,
"president": "Rutherford B. Hayes",
"birth_year": 1822,
"death_year": 1893,
"took_office": "1877-03-04",
"left_office": "1881-03-04",
"party": "Republican",
"age_decade": 50,
"sgin": "Libra",
"birth_place": "Ohio"
},
{
"number": 20,
"president": "James A. Garfield",
"birth_year": 1831,
"death_year": 1881,
"took_office": "1881-03-04",
"left_office": "1881-09-19",
"party": "Republican",
"age_decade": 50,
"sgin": "Scorpio",
"birth_place": "Ohio"
},
{
"number": 21,
"president": "Chester A. Arthur",
"birth_year": 1829,
"death_year": 1886,
"took_office": "1881-09-19",
"left_office": "1885-03-04",
"party": "Republican",
"age_decade": 50,
"sgin": "Libra",
"birth_place": "Vermont"
},
{
"number": 23,
"president": "Benjamin Harrison",
"birth_year": 1833,
"death_year": 1901,
"took_office": "1889-03-04",
"left_office": "1893-03-04",
"party": "Republican",
"age_decade": 50,
"sgin": "Leo",
"birth_place": "Ohio"
},
{
"number": 24,
"president": "Grover Cleveland",
"birth_year": 1837,
"death_year": 1908,
"took_office": "1893-03-04",
"left_office": "1897-03-04",
"party": "Democratic",
"age_decade": 50,
"sgin": "Pisces",
"birth_place": "New Jersey"
},
{
"number": 25,
"president": "William McKinley",
"birth_year": 1843,
"death_year": 1901,
"took_office": "1897-03-04",
"left_office": "1901-09-14",
"party": "Republican",
"age_decade": 50,
"sgin": "Aquarius",
"birth_place": "Ohio"
},
{
"number": 26,
"president": "Theodore Roosevelt",
"birth_year": 1858,
"death_year": 1919,
"took_office": "1901-09-14",
"left_office": "1909-03-04",
"party": "Republican",
"age_decade": 40,
"sgin": "Scorpio",
"birth_place": "New York"
},
{
"number": 27,
"president": "William Howard Taft",
"birth_year": 1857,
"death_year": 1930,
"took_office": "1909-03-04",
"left_office": "1913-03-04",
"party": "Republican",
"age_decade": 50,
"sgin": "Virgo",
"birth_place": "Ohio"
},
{
"number": 28,
"president": "Woodrow Wilson",
"birth_year": 1856,
"death_year": 1924,
"took_office": "1913-03-04",
"left_office": "1921-03-04",
"party": "Democratic",
"age_decade": 50,
"sgin": "Capricorn",
"birth_place": "Virginia"
},
{
"number": 29,
"president": "Warren G. Harding",
"birth_year": 1865,
"death_year": 1923,
"took_office": "1921-03-04",
"left_office": "1923-08-02",
"party": "Republican",
"age_decade": 50,
"sgin": "Scorpio",
"birth_place": "Ohio"
},
{
"number": 30,
"president": "Calvin Coolidge",
"birth_year": 1872,
"death_year": 1933,
"took_office": "1923-08-02",
"left_office": "1929-03-04",
"party": "Republican",
"age_decade": 50,
"sgin": "Cancer",
"birth_place": "Vermont"
},
{
"number": 31,
"president": "Herbert Hoover",
"birth_year": 1874,
"death_year": 1964,
"took_office": "1929-03-04",
"left_office": "1933-03-04",
"party": "Republican",
"age_decade": 50,
"sgin": "Leo",
"birth_place": "Iowa"
},
{
"number": 32,
"president": "Franklin D. Roosevelt",
"birth_year": 1882,
"death_year": 1945,
"took_office": "1933-03-04",
"left_office": "1945-04-12",
"party": "Democratic",
"age_decade": 50,
"sgin": "Aquarius",
"birth_place": "New York"
},
{
"number": 33,
"president": "Harry S. Truman",
"birth_year": 1884,
"death_year": 1972,
"took_office": "1945-04-12",
"left_office": "1953-01-20",
"party": "Democratic",
"age_decade": 60,
"sgin": "Taurus",
"birth_place": "Missouri"
},
{
"number": 34,
"president": "Dwight D. Eisenhower",
"birth_year": 1890,
"death_year": 1969,
"took_office": "1953-01-20",
"left_office": "1961-01-20",
"party": "Republican",
"age_decade": 60,
"sgin": "Libra",
"birth_place": "Texas"
},
{
"number": 35,
"president": "John F. Kennedy",
"birth_year": 1917,
"death_year": 1963,
"took_office": "1961-01-20",
"left_office": "1963-11-22",
"party": "Democratic",
"age_decade": 40,
"sgin": "Gemini",
"birth_place": "Massachusetts"
},
{
"number": 36,
"president": "Lyndon B. Johnson",
"birth_year": 1908,
"death_year": 1973,
"took_office": "1963-11-22",
"left_office": "1969-01-20",
"party": "Democratic",
"age_decade": 50,
"sgin": "Virgo",
"birth_place": "Texas"
},
{
"number": 37,
"president": "Richard Nixon",
"birth_year": 1913,
"death_year": 1994,
"took_office": "1969-01-20",
"left_office": "1974-08-09",
"party": "Republican",
"age_decade": 50,
"sgin": "Capricorn",
"birth_place": "California"
},
{
"number": 38,
"president": "Gerald Ford",
"birth_year": 1913,
"death_year": 2006,
"took_office": "1974-08-09",
"left_office": "1977-01-20",
"party": "Republican",
"age_decade": 60,
"sgin": "Cancer",
"birth_place": "Nebraska"
},
{
"number": 39,
"president": "Jimmy Carter",
"birth_year": 1924,
"death_year": null,
"took_office": "1977-01-20",
"left_office": "1981-01-20",
"party": "Democratic",
"age_decade": 50,
"sgin": "Gemini",
"birth_place": "Georgia"
},
{
"number": 40,
"president": "Ronald Reagan",
"birth_year": 1911,
"death_year": 2004,
"took_office": "1981-01-20",
"left_office": "1989-01-20",
"party": "Republican",
"age_decade": 70,
"sgin": "Aquarius",
"birth_place": "Illinois"
},
{
"number": 41,
"president": "George H. W. Bush",
"birth_year": 1924,
"death_year": null,
"took_office": "1989-01-20",
"left_office": "1993-01-20",
"party": "Republican",
"age_decade": 60,
"sgin": "Gemini",
"birth_place": "Massachusetts"
},
{
"number": 42,
"president": "Bill Clinton",
"birth_year": 1946,
"death_year": null,
"took_office": "1993-01-20",
"left_office": "2001-01-20",
"party": "Democratic",
"age_decade": 40,
"sgin": "Leo",
"birth_place": "Arkansas"
},
{
"number": 43,
"president": "George W. Bush",
"birth_year": 1946,
"death_year": null,
"took_office": "2001-01-20",
"left_office": "2009-01-20",
"party": "Republican",
"age_decade": 50,
"sgin": "Cancer",
"birth_place": "Connecticut"
},
{
"number": 44,
"president": "Barack Obama",
"birth_year": 1961,
"death_year": null,
"took_office": "2009-01-20",
"left_office": "2017-01-20",
"party": "Democratic",
"age_decade": 40,
"sgin": "Leo",
"birth_place": "Hawaii"
},
{
"number": 45,
"president": "Donald J. Trump",
"birth_year": 1946,
"death_year": null,
"took_office": "2017-01-20",
"left_office": null,
"party": "Republican",
"age_decade": 70,
"sgin": "Gemini",
"birth_place": "New York"
}
]

View File

@ -0,0 +1,49 @@
<!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">
<title>画廊-美国总统信息桑基图</title>
</head>
<body>
<div id="mountNode"></div>
<script src="./assets/jquery-3.2.1.min.js"></script>
<script src="../build/g6.js"></script>
<script src="../build/plugin.template.tableSankey.js"></script>
<script>
$.getJSON('./assets/data/usa-president.json', table => {
const sankeyPlugin = new G6.Plugins['template.tableSankey']({
table,
fields: ['president', 'birth_place', 'age_decade', 'party', 'sgin'],
onBeforeRender(graph) {
graph.node({
color() {
const colors = ['#FD8C3D', '#D83F43', '#F7BED6', '#E487C7', '#46A848', '#D83F43', '#3B85BA', '#48335B', '#B7CDE9'];
return colors[parseInt(colors.length * Math.random())];
},
style: {
stroke: '#616161'
}
});
graph.edge({
style: {
stroke: 'rgb(0, 0, 0)',
strokeOpacity: 0.2
}
});
}
})
const graph = new G6.Graph({
container: 'mountNode',
height: 600,
fitView: 'cc',
animate: true,
plugins: [ sankeyPlugin ]
});
});
</script>
</body>
</html>

View File

@ -14,95 +14,77 @@
<body>
<div id="mountNode"></div>
<script>
const dagre = new G6.Plugins['layout.dagre']({
rankdir: 'LR',
ranksep: 72
});
G6.registerNode('custom', {
anchor(item) {
const outEdges = item.getOutEdges();
const inEdges = item.getInEdges();
if(outEdges.length > 1) {
return [
[0, 0.5],
[0.5, 1],
[0.5, 0]
];
}
if (inEdges.length > 1) {
return [
[1, 0.5],
[0.5, 1],
[0.5, 0]
];
}
return [
[0, 0.5],
[1, 0.5],
[0.5, 1],
[0.5, 0]
];
}
});
const data = {
nodes: [{
id: 'node1',
},{
id: 'node2',
},{
id: 'node3',
},{
id: 'node4',
},{
id: 'node5',
},{
id: 'node6',
}],
edges: [{
source: 'node1',
target: 'node2'
},{
source: 'node2',
target: 'node3'
},{
source: 'node2',
target: 'node4'
},{
source: 'node4',
target: 'node5'
},{
source: 'node3',
target: 'node5'
},{
source: 'node5',
target: 'node6'
}]
};
const graph = new G6.Graph({
container: 'mountNode',
width: 500,
height: 500,
fitView: 'cc',
plugins: [dagre]
});
graph.node({
size: 10,
style: {
lineWidth: 6,
strokeOpacity: 0
}
});
graph.node({
shape: 'custom',
label(model) {
return model.id;
},
labelOffsetY: 12
});
graph.edge({
shape: 'polyline'
});
graph.read(data);
$.getJSON('./assets/data/usa-president.json', table => {
// 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']({
table,
fields: ['president', 'birth_place', 'age_decade', 'party', 'sgin'],
onBeforeRender(graph) {
graph.node({
color(model) {
const colors = ['#FD8C3D', '#D83F43', '#F7BED6', '#E487C7', '#46A848', '#D83F43', '#3B85BA', '#48335B', '#B7CDE9'];
return colors[model.rowIndex%10];
},
style: {
stroke: '#616161'
}
});
graph.edge({
style: {
stroke: 'rgb(0, 0, 0)',
strokeOpacity: 0.2
}
});
},
...fullViewCfg
})
const graph = new G6.Graph({
container: 'mountNode',
height: 600,
fitView: 'cc',
animate: true,
plugins: [sankeyPlugin]
});
setTimeout(()=>{
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);
});
</script>
</body>
</html>

View File

@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<title>紧凑</title>
<title>系统</title>
<style>
::-webkit-scrollbar {
display: none;

View File

@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<title>紧凑</title>
<title>缩进</title>
<style>
::-webkit-scrollbar {
display: none;
@ -45,7 +45,7 @@
var layout = new G6.Layouts.IndentedTree({
direction: 'LR', // 方向LR/RL/H
indent: 30, // 缩进量
getVGap: function getVGap() /* d */ {
getVGap() /* d */ {
// 竖向间距
return 4;
}

View File

@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<title>紧凑</title>
<title>脑图</title>
<style>
::-webkit-scrollbar {
display: none;

91
demos/yunqi-1.html Normal file
View File

@ -0,0 +1,91 @@
<!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>
<body>
<div id="mountNode"></div>
<script>
$.getJSON('./assets/data/usa-president.json', table => {
// 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']({
table,
fields: ['president', 'birth_place', 'age_decade', 'party', 'sgin'],
onBeforeRender(graph) {
graph.node({
color(model) {
const colors = ['#FD8C3D', '#D83F43', '#F7BED6', '#E487C7', '#46A848', '#D83F43', '#3B85BA', '#48335B', '#B7CDE9'];
return colors[model.rowIndex%10];
},
style: {
stroke: '#616161'
}
});
graph.edge({
style: {
stroke: 'rgb(0, 0, 0)',
strokeOpacity: 0.2
}
});
},
...fullViewCfg
})
const graph = new G6.Graph({
container: 'mountNode',
height: window.innerHeight, // 画布高
fitView: 'cc',
animate: true,
plugins: [sankeyPlugin]
});
setTimeout(()=>{
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);
});
</script>
</body>
</html>

121
demos/yunqi-2.html Normal file
View File

@ -0,0 +1,121 @@
<!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>
<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().strength(0.05))
.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)
}, 10000);
}
},
});
graph.node({
size: 6,
color(model) {
const colors = ['#FD8C3D', '#D83F43', '#F7BED6', '#E487C7', '#46A848', '#D83F43', '#3B85BA', '#48335B', '#B7CDE9'];
return model.fColor ? model.fColor: colors[parseInt(Math.random()*colors.length)];
},
});
graph.read(data);
});
}, 5000);
</script>
</body>
</html>

77
demos/yunqi-3.html Normal file
View File

@ -0,0 +1,77 @@
<!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>
<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: 120px;"/>
</div>
<script>
$.getJSON('./assets/data/link-data.json', data => {
const { Util } = G6;
const graph = new G6.Graph({
container: 'mountNode',
height: window.innerHeight, // 画布高
plugins: [
new G6.Plugins['tool.fisheye'],
new G6.Plugins['tool.highlightSubgraph'],
],
fitView:'autoZoom',
});
graph.node({
style: {
stroke: '#333'
}
})
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>

View File

@ -1,6 +1,6 @@
{
"name": "@antv/g6",
"version": "2.1.0-beta.19",
"version": "2.1.0-beta.21",
"description": "graph visualization frame work",
"main": "build/g6.js",
"homepage": "https://github.com/antvis/g6",
@ -73,6 +73,7 @@
"radixsort": "~1.0.0",
"serve-static": "~1.13.2",
"shelljs": "~0.7.8",
"svgson": "^2.1.1",
"torchjs": "~2.0.3",
"uglify-js": "~3.1.10",
"webpack": "~4.10.2",
@ -100,7 +101,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/item/",
"test-live": "torch --compile --interactive --watch --recursive ./test/test-spec.js",
"watch": "webpack --config webpack-dev.config.js",
"win-dev": "node ./bin/win-dev.js"
},
@ -108,11 +109,12 @@
"run": []
},
"dependencies": {
"@antv/g": "~3.1.0-beta.11",
"@antv/g2": "~3.2.7-beta.4",
"@antv/g": "~3.1.0",
"@antv/g2": "~3.2.7",
"@antv/hierarchy": "~0.3.13",
"@antv/scale": "^0.0.1",
"d3": "^5.4.0",
"d3-sankey": "^0.7.1",
"d3-svg-legend": "^2.25.6",
"dagre": "~0.8.2",
"dom-to-image": "^2.6.0",

View File

@ -83,14 +83,24 @@ G6.registerBehaviour('panNode', graph => {
let node;
let dx;
let dy;
graph.on('node:dragstart', ev => {
const {
item
} = ev;
graph.on('node:mouseenter', () => {
graph.css({
cursor: 'move'
});
});
graph.on('node:mouseleave', () => {
graph.css({
cursor: 'default'
});
});
graph.on('node:dragstart', ({ item, x, y }) => {
graph.css({
cursor: 'move'
});
const model = item.getModel();
node = item;
dx = model.x - ev.x;
dy = model.y - ev.y;
dx = model.x - x;
dy = model.y - y;
graph.forcePreventAnimate(true);
});
graph.on('node:drag', ev => {

View File

@ -8,6 +8,7 @@ module.exports = {
'layout.forceAtlas2': require('./layout.forceAtlas2/'),
'layout.grid': require('./layout.grid/'),
'template.maxSpanningForest': require('./template.maxSpanningForest/'),
'template.tableSankey': require('./template.tableSankey/'),
'tool.d3.mapper': require('./tool.d3.mapper/'),
'tool.fisheye': require('./tool.fisheye/'),
'tool.freezeSize': require('./tool.freezeSize/'),
@ -17,7 +18,8 @@ module.exports = {
'tool.minimap': require('./tool.minimap/'),
'tool.textDisplay': require('./tool.textDisplay/'),
'tool.tooltip': require('./tool.tooltip/'),
'util.backbone': require('./util.backbone/'),
'util.dataCleaner': require('./util.dataCleaner/'),
'util.extractSubgraph': require('./util.extractSubgraph/'),
'util.randomData': require('./util.randomData/')
'util.randomData': require('./util.randomData/'),
};

View File

@ -1,45 +0,0 @@
## forceAtlas2
ForceAtlas2(https://medialab.sciencespo.fr/publications/Jacomy_Heymann_Venturini-Force_Atlas2.pdf) is a graph layout algorithm, whose parameters determine the result.
- kr: repulsive parameter, larger the kr, more loose the layout.
- kg: gravity parameter, larger the kg, more central the layout.
- mode: 'normal'/'linlog'
'normal': normal layout
'linlog': the cluster will be more compact
- preOverlapping: true/false.
true: prevents node overlapping, result in non-node-overlapping layout
false: allows node overlapping.
- 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
- 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
- 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
simple use.
```js
$.getJSON('../../test/fixtures/viralMarketing.json', data => {
const Plugin = G6.Plugins['layout.forceAtlas2'];
const layoutParams = {
maxIteration: 1500,
prevOverlapping: true,
kr: 15,
mode: 'normal',
barnesHut: false, // may be counter-productive on small networks
ks: 0.1,
dissuadeHubs: false
};
graph = new G6.Graph({
id: 'mountNode', // dom id
plugins: [new Plugin(layoutParams)],
height: 1000,
});
graph.read(data);
});
```

View File

@ -245,7 +245,7 @@ class Layout {
model.x = this.nodes[i].x;
model.y = this.nodes[i].y;
}
graph.changeLayout();
graph.updateNodePosition();
const fitView = graph.get('fitView');
fitView && graph.setFitView(fitView);
worker.terminate();
@ -262,7 +262,7 @@ class Layout {
model.x = this.nodes[i].x;
model.y = this.nodes[i].y;
}
graph.changeLayout();
graph.updateNodePosition();
const fitView = graph.get('fitView');
fitView && graph.setFitView(fitView);
onLayoutComplete();

View File

@ -8,7 +8,7 @@
* edge.weight - edge weight
*/
const G6 = require('@antv/g6');
const maxSpanningForest = require('./maxSpanningForest');
const maxSpanningForest = require('../util.backbone/maxSpanningForest');
const Layout = require('../layout.forceAtlas2/layout');
const Util = G6.Util;
const Menu = require('./menu');
@ -50,7 +50,8 @@ class Plugin {
menu: null,
edgeStyle: {
stroke: '#4F7DAB',
strokeOpacity: 0.65
strokeOpacity: 0.65,
endArrow: true
},
activedEdgeStyle: {
stroke: '#4C7295',
@ -80,7 +81,6 @@ class Plugin {
}
init() {
const graph = this.graph;
if (this.fisheye) {
const fisheye = new G6.Plugins['tool.fisheye']({
radius: 100
@ -139,7 +139,7 @@ class Plugin {
index
};
});
const forest = maxSpanningForest(nodes, edges);
const forest = maxSpanningForest({ nodes, edges });
forest.edges.forEach(edge => {
const {
index
@ -149,7 +149,6 @@ class Plugin {
graph.addFilter(item => {
return !item.isEdge || item.getModel().isTreeEdge;
});
this.setStyle();
this.interactive && this.setListener();
const menuCfg = this.menuCfg;
@ -176,9 +175,8 @@ class Plugin {
if (model.actived) {
return this.activedEdgeStyle;
}
return this.edgeStyle;
},
endArrow: true
return Util.isFunction(this.edgeStyle) ? this.edgeStyle(model) : this.edgeStyle;
}
});
graph.node({
label: this.node_label,

View File

@ -58,7 +58,6 @@ class Menu {
showSource(node) {
this._showEdge('in', 1, [ node ]);
}
showTargets(node) {
this._showEdge('out', 1, [ node ]);
}
@ -70,11 +69,8 @@ class Menu {
const {
reNodes,
reEdges
} = Util.extract(graph, type, step, focusNodes);
graph.highlightSubgraph({
reNodes,
reEdges
});
} = Util.extract(type, focusNodes);
graph.highlightSubgraph(reNodes.concat(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
reEdges.forEach(edgeObj => {

View File

@ -0,0 +1,315 @@
/**
* @fileOverview table sankey
* show the table in sankey view
* @author huangtonger@aliyun.com
*/
const G6 = require('@antv/g6');
const {
sankey,
sankeyLeft,
sankeyRight,
sankeyCenter,
sankeyJustify
} = require('d3-sankey');
const Util = G6.Util;
const ALIGN_METHOD = {
sankeyLeft,
sankeyRight,
sankeyCenter,
sankeyJustify
};
G6.registerNode('sankey-node', {
getPath(item) {
const model = item.getModel();
const { x, y, x0, y0, x1, y1 } = model;
return [
[ 'M', x0 - x, y0 - y ],
[ 'L', x1 - x, y0 - y ],
[ 'L', x1 - x, y1 - y ],
[ 'L', x0 - x, y1 - y ],
[ 'Z' ]
];
}
});
G6.registerEdge('sankey-edge', {
getPath(item) {
const model = item.getModel();
const source = item.getSource();
const target = item.getTarget();
const sourceBox = source.getBBox();
const targetBox = target.getBBox();
const sourceModel = source.getModel();
const targetModel = target.getModel();
let { y0, y1 } = model;
y0 = sourceBox.minY + y0 - sourceModel.y0;
y1 = targetBox.minY + y1 - targetModel.y0;
if (sourceBox.centerX < targetBox.centerX) {
const hgap = targetBox.minX - sourceBox.maxX;
return [
[ 'M', sourceBox.maxX, y0 ],
[ 'C', sourceBox.maxX + hgap / 4, y0, targetBox.minX - hgap / 2, y1, targetBox.minX, y1 ]
];
}
const hgap = sourceBox.minX - targetBox.maxX;
return [
[ 'M', targetBox.maxX, y1 ],
[ 'C', targetBox.maxX + hgap / 4, y1, sourceBox.minX - hgap / 2, y0, sourceBox.minX, y0 ]
];
}
});
G6.registerGuide('col-names', {
draw(item) {
const group = item.getGraphicGroup();
const graph = item.getGraph();
const nodes = graph.getNodes();
const colMap = {};
let minY = Infinity;
nodes.forEach(node => {
const model = node.getModel();
const { field, y, x } = model;
if (minY > y) {
minY = y;
}
if (!colMap[field]) {
colMap[field] = {
field,
x
};
}
});
Util.each(colMap, ({ field, x }) => {
group.addShape('text', {
attrs: {
text: field,
x,
y: minY - 12,
fill: '#333',
textAlign: 'center'
}
});
});
return group;
}
});
class Plugin {
constructor(options) {
Util.mix(this, {
/**
* @type {array} table - table data
*/
table: null,
/**
* @type {array} fields - table data fields
*/
fields: null,
/**
* @type {function} onBeforeRender - trigger before render
*/
onBeforeRender: null,
/**
* @type {boolean} showColName - show col name or not
*/
showColName: true,
/**
* @type {string} align - could be `sankeyLeft` `sankeyRight` `sankeyCenter` `sankeyJustify`
*/
align: 'sankeyJustify',
/**
* @type {array} padding - toprightbottomleft
*/
padding: [ 40, 24, 24, 24 ],
/**
* @type {function} combine - comine the node id
* @param {object} cfg - combine cfg
* @property {string} cfg.field - input object
* @property {string} cfg.value - input object
* @property {string} cfg.colIndex - input object
* @property {object} cfg.rowIndex - input object
* @return {string} combine id
*/
combine({ field, value }) {
return field + value;
}
}, options);
}
_getFields() {
let { table, fields } = this;
if (!fields) {
fields = [];
Util.each(table[0], (v, k) => {
fields.push(k);
});
return fields;
}
return fields;
}
_object2values(obj) {
const rst = [];
Util.each(obj, v => {
rst.push(v);
});
return rst;
}
_getNodes(table, fields) {
const map = {};
table.forEach((row, rowIndex) => {
fields.forEach((field, colIndex) => {
const value = row[field];
const id = this.combine({ field, value, colIndex, rowIndex });
if (!map[id]) {
map[id] = {
id,
field,
rowIndex,
colIndex,
fieldValue: value
};
}
});
});
return this._object2values(map);
}
_getEdges(table, fields) {
const map = {};
table.forEach((row, rowIndex) => {
fields.forEach((field, colIndex) => {
const nextColIndex = colIndex + 1;
const nextField = fields[nextColIndex];
if (!nextField) {
return;
}
const value = row[field];
const nextValue = row[nextField];
const source = this.combine({ field, value, colIndex, rowIndex });
const target = this.combine({ field: nextField, value: nextValue, colIndex: nextColIndex, rowIndex });
const id = source + '-' + target;
if (!map[id]) {
map[id] = {
id,
source,
target,
value: 1
};
} else {
map[id].value++;
}
});
});
return this._object2values(map);
}
init() {
const graph = this.graph;
if (!this.table) {
throw new Error('please input valid table data!');
}
graph.on('beforerender', () => {
this.onBeforeRender && this.onBeforeRender(graph);
});
graph.on('afterrender', () => {
graph.getItems().forEach(item => {
if (item.isEdge) {
graph.toBack(item);
}
});
this.onAfterRender && this.onAfterRender(graph);
});
graph.on('afterinit', () => {
this._initSankeyProcessor();
const data = this._getData();
this._graphMapping();
graph.read(data);
});
}
_graphMapping() {
const graph = this.graph;
const width = graph.getWidth();
graph.node({
label(model) {
if (model.x > width / 2) {
return {
text: model.fieldValue,
textAlign: 'right'
};
}
return {
text: model.fieldValue,
textAlign: 'left'
};
},
labelOffsetX(model) {
const labelGap = 8;
if (model.x > width / 2) {
return -(model.x1 - model.x0) / 2 - labelGap;
}
return (model.x1 - model.x0) / 2 + labelGap;
}
});
}
_getGuides() {
const guides = [];
if (this.showColName) {
guides.push({
shape: 'col-names'
});
}
return guides;
}
_getData() {
const table = this.table;
const fields = this._getFields();
const sankeyProcessor = this.sankeyProcessor;
const data = {
nodes: this._getNodes(table, fields),
edges: this._getEdges(table, fields),
guides: this._getGuides()
};
sankeyProcessor(data);
data.nodes.forEach(node => {
node.x = (node.x0 + node.x1) / 2;
node.y = (node.y0 + node.y1) / 2;
node.shape = 'sankey-node';
node.label = node.fieldValue;
});
data.edges.forEach(edge => {
edge.source = edge.source.id;
edge.target = edge.target.id;
edge.shape = 'sankey-edge';
edge.size = edge.width;
});
return data;
}
_initSankeyProcessor() {
const graph = this.graph;
const padding = this.padding;
const graphWidth = graph.getWidth();
const graphHeight = graph.getHeight();
const sankeyProcessor = sankey()
.nodeId(d => {
return d.id;
})
.links(d => d.edges)
.extent([[ padding[3], padding[0] ], [ graphWidth - padding[1], graphHeight - padding[2] ]]);
sankeyProcessor.nodeAlign(ALIGN_METHOD[this.align]);
this.sankeyProcessor = sankeyProcessor;
}
change(cfg) {
Util.mix(this, cfg);
const graph = this.graph;
const data = this._getData();
graph.read(data);
}
}
G6.Plugins['template.tableSankey'] = Plugin;
module.exports = Plugin;

View File

@ -1,36 +0,0 @@
## Fisheye
Fisheye is a magnifying lens for graph exploration. We inplement 'Graphical Fisheye Views' with polar coordinate system: ftp://ftp.cs.brown.edu/pub/techreports/93/cs93-40.pdf
params:
- radius: the radius of the fisheye lens. Default: 200.
- d: the magnification factor of the fisheye lens. Default: 1.
## use
simple use.
```js
const plugin = new G6.Plugins['tool.fisheye']();
const data = {
nodes: [{
id: 'node1',
x: 100,
y: 200
}, {
id: 'node2',
x: 300,
y: 200
}],
edges: [{
target: 'node2',
source: 'node1'
}]
};
const graph = new G6.Graph({
container: 'mountNode',
width: 500,
height: 500,
plugins: [plugin]
});
graph.read(data);
```

View File

@ -28,7 +28,7 @@ class Plugin {
* grid line style
* @type {string}
*/
type: 'point',
type: 'dot',
/**
* visible
@ -62,7 +62,7 @@ class Plugin {
const matrix = graph.getMatrix();
const type = this.type;
const lineWidth = type === 'line' ? 1 / matrix[0] : 2 / matrix[0];
if (type === 'point') {
if (type === 'dot') {
attrs.lineDash = null;
}
attrs.lineWidth = lineWidth;
@ -109,7 +109,7 @@ class Plugin {
const type = this.type;
return this['_get' + Util.upperFirst(type) + 'Path']();
}
// get point style grid path
// get dot style grid path
_getPointPath() {
const graph = this.graph;
const width = graph.getWidth();
@ -157,9 +157,12 @@ class Plugin {
return cell;
}
update(cfg) {
Util.mix(this, cfg);
const path = this._getPath();
const gridEl = this.gridEl;
if (!gridEl) {
return;
}
cfg && Util.mix(this, cfg);
const path = this._getPath();
const graph = this.graph;
const zoom = graph.getZoom();
const type = this.type;

View File

@ -1,64 +0,0 @@
## highlightSubgraph
Highlight a subgraph and weaken the rest of the graph.
interface:
- highlightSubgraph(hlItems)
hightlight a subgraph
params:
- hlItems: the items which will be highlighted
- unhighlightGraph()
restore the graph to the un-lighlighted style.
## use
simple use.
```js
const Highlighter = G6.Plugins['tool.highlightSubgraph'];
const highlighter = new Highlighter();
const data = {
nodes: [{
id: 'node1',
x: 100,
y: 200
}, {
id: 'node2',
x: 300,
y: 200
}, {
id: 'node3',
x: 100,
y: 100
}, {
id: 'node4',
x: 300,
y: 100
}],
edges: [{
target: 'node2',
source: 'node1'
}, {
target: 'node3',
source: 'node2'
}, {
target: 'node4',
source: 'node3'
}, {
target: 'node1',
source: 'node4'
}, ]
};
const graph = new G6.Graph({
id: 'mountNode', // dom id
plugins: [highlighter],
height: 1000,
});
graph.read(data);
const nodes = graph.getNodes();
const edges = graph.getEdges();
const reNodes = [nodes[0], nodes[1]];
const reEdges = [edges[0]];
graph.highlightSubgraph({reNodes, reEdges});
```

View File

@ -30,84 +30,26 @@ class Plugin {
Util.mix(this, options);
}
init() {
this.graph.on('afterinit', () => {
const graph = this.graph;
graph.on('afterinit', () => {
this.graph.highlightSubgraph = this.highlightSubgraph;
this.graph.unhighlightGraph = this.unhighlightGraph;
});
}
highlightSubgraph(hlItems) {
highlightSubgraph(items) {
this.unhighlightGraph();
// sort the group items
const ns = hlItems.reNodes;
const es = hlItems.reEdges;
const items = this.getItems();
Util.each(items, i => {
if (i.type === 'edge') {
Util.each(es, e => {
if (i.id !== e.id) {
this.toFront(i);
}
});
}
this.add('guide', {
shape: 'mask',
id: 'mask'
});
Util.each(items, i => {
if (i.type === 'node') {
Util.each(ns, n => {
if (i.id !== n.id) {
this.toFront(i);
}
});
}
items.forEach(item=>{
this.toFront(item);
});
let mask;
Util.each(items, i => {
if (i.type === 'guide') {
mask = i;
this.toFront(i);
return;
}
});
if (mask === undefined) {
mask = this.add('guide', {
shape: 'mask'
});
this.toFront(mask);
}
mask.show();
Util.each(items, i => {
if (i.type === 'edge') {
Util.each(es, e => {
if (i.id === e.id) {
this.toFront(i);
}
});
}
});
Util.each(items, i => {
if (i.type === 'node') {
Util.each(ns, n => {
if (i.id === n.id) {
this.toFront(i);
}
});
}
});
this.draw();
}
unhighlightGraph() {
// hide the mask
const items = this.getItems();
let mask;
Util.each(items, i => {
if (i.type === 'guide') {
mask = i;
return;
}
});
if (mask !== undefined) {
mask.hide();
}
this.draw();
const mask = this.find('mask');
mask && this.remove(mask);
}
}

View File

@ -1,75 +0,0 @@
## mapper
Associate the input range with the @antv/scale, @antv/attr and @antv/g2/src/component/legend.
Constructor parameters:
- itemType: 'node'/'edge. The type of the item being mapped.
- dim: the dimension of the edge. e.g. 'class'.
- range: the range the of mapping result. e.g. [ 0, 1 ], ['#BAE7FF', '#1890FF', '#0050B3'].
- channel: the visual channel. e.g.'size', 'color'.
- othercfg:
- scaleCfg: the configuration of the scale.
- legendCfg: the configuration of the legend.
null: no lengend.
scale: scaling the size of the legend.
formatter: a function for formatting the number label of the slider.
legendTitle: the title of the legend.
legendLayout: the layout way of the legend.'horizontal'/'vertical'
legendWdith and lengedHeight: the size of the legend. Defualt: 150*15 for horizontal layout, 15*150 for vertical layout.
## use
simple use.
```js
const Mapper = G6.Plugins['tool.mapper'];
const nodeColorMapper = new Mapper('node', 'class', 'color', ['#BAE7FF', '#0050B3'], {
legendCfg: {
scale: 0.5
}
});
const edgeSizeMapper = new Mapper('edge', 'weight', 'size', [2, 20], {
legendCfg: null
});
const data = {
nodes: [{
id: 'node1',
x: 100,
y: 200,
class: 'class_1'
}, {
id: 'node2',
x: 300,
y: 200,
class: 'class_1'
}, {
id: 'node3',
x: 100,
y: 100,
class: 'class_2'
}, {
id: 'node4',
x: 300,
y: 100,
class: 'class_2'
}],
edges: [{
target: 'node2',
source: 'node1',
weight: 5
}, {
target: 'node3',
source: 'node2',
weight: 20
}, {
target: 'node4',
source: 'node3',
weight: 50
}]
};
const graph = new G6.Graph({
id: 'mountNode', // dom id
plugins: [nodeColorMapper, edgeSizeMapper],
height: 1000,
});
graph.read(data);
```

View File

@ -1,55 +0,0 @@
## textDisplay
Hide the labels when the width of the text is 2 times bigger than the parent node.
## use
simple use.
```js
const data = {
nodes: [{
id: 'node1',
x: 100,
y: 200,
width: 100
}, {
id: 'node2',
x: 300,
y: 200
}, {
id: 'node3',
x: 100,
y: 100
}, {
id: 'node4',
x: 300,
y: 100
}],
edges: [{
target: 'node2',
source: 'node1'
}, {
target: 'node3',
source: 'node2'
}, {
target: 'node4',
source: 'node3'
}, {
target: 'node1',
source: 'node4'
}, ]
};
const textDisplay = new G6.Plugins['tool.textDisplay']();
const edgeSizeMapper = new Mapper('edge', 'userview', 'size', [2, 20], {
legendCfg: null
});
graph = new G6.Graph({
id: 'mountNode', // dom id
plugins: [textDisplay],
height: 1000,
});
graph.read(data);
```

View File

@ -20,6 +20,9 @@ class Plugin {
this.graph.on('afterzoom', () => {
this.textDisplay();
});
this.graph.textDisplay = ()=>{
this.textDisplay();
}
}
textDisplay() {
const graph = this.graph;

View File

@ -1,85 +0,0 @@
## Tooltip
Tooltip helps users to get the detailed information. This plugin helps developers locate tooltip position quickly.
## use
simple use.
```js
const plugin = new G6.Plugins['tool.tooltip']();
const data = {
nodes: [{
id: 'node1',
x: 100,
y: 200
}, {
id: 'node2',
x: 300,
y: 200
}],
edges: [{
target: 'node2',
source: 'node1'
}]
};
const graph = new G6.Graph({
container: 'mountNode',
width: 500,
height: 500
});
graph.node({
tooltip(model) {
return [
['id', model.id],
['x', model.x],
['y', model.y]
];
}
});
graph.edge({
tooltip(model) {
return [
['来源', model.source],
['去向', model.target]
];
}
});
graph.read(data);
```
custom use
```js
const plugin = new G6.Plugins['tool.tooltip']({
getTooltip({item}) {
const model = item.getModel();
return `
<ul>
<li>唯一标识:${model.id}</li>
</ul>
`;
}
});
const data = {
nodes: [{
id: 'node1',
x: 100,
y: 200
}, {
id: 'node2',
x: 300,
y: 200
}],
edges: [{
target: 'node2',
source: 'node1'
}]
};
const graph = new G6.Graph({
container: 'mountNode',
width: 500,
height: 500
});
graph.read(data);
```

View File

@ -0,0 +1,13 @@
/**
* @fileOverview pull graph backbone
* @author huangtonger@aliyun.com
*/
const G6 = require('@antv/g6');
const maxSpanningForest = require('./maxSpanningForest');
const Util = G6.Util;
const backbone = {
maxSpanningForest,
};
Util.mix(Util, backbone);

View File

@ -6,7 +6,7 @@ const G6 = require('@antv/g6');
const { Util } = G6;
const maxSpanningTree = require('./maxSpanningTree');
function maxSpanningForest(nodes, edges) {
function maxSpanningForest({nodes, edges}) {
const connectedSubsets = [];
const forest = {
nodes: [],

View File

@ -7,7 +7,7 @@ const G6 = require('@antv/g6');
const Util = G6.Util;
const extractSubgraph = {
extract(graph, type, step, focusNodes) {
extract(type, focusNodes) {
const reEdges = [];
Util.each(focusNodes, fn => {
if (type === 'in') {

View File

@ -22,10 +22,10 @@ class Controller extends Base {
auto: true,
/**
* layout processer
* layout processor
* @type {object}
*/
processer: null
processor: null
};
}
constructor(cfg) {
@ -57,13 +57,13 @@ class Controller extends Base {
}
});
}
changeLayout(processer) {
this.processer = processer;
changeLayout(processor) {
this.processor = processor;
this.layout();
}
layout() {
const graph = this.graph;
const processer = this.processer;
const processor = this.getLayoutProcessor();
graph.emit('beforelayout');
const nodes = graph.getNodes()
.filter(node => {
@ -86,12 +86,12 @@ class Controller extends Base {
.map(group => {
return group.getModel();
});
graph._executeLayout(processer, nodes, edges, groups);
graph._executeLayout(processor, nodes, edges, groups);
graph.updateNodePosition();
graph.emit('afterlayout');
}
getLayoutProcesser() {
return this.processer;
getLayoutProcessor() {
return this.processor ? this.processor : this.processer;
}
}

View File

@ -128,15 +128,15 @@ class Graph extends Base {
initEvent() {
}
_executeLayout(processer, nodes, edges, groups) {
if (Util.isFunction(processer)) {
processer(nodes, edges, this);
} else if (Util.isObject(processer)) {
processer.nodes = nodes;
processer.edges = edges;
processer.groups = groups;
processer.graph = this;
processer.execute();
_executeLayout(processor, nodes, edges, groups) {
if (Util.isFunction(processor)) {
processor(nodes, edges, this);
} else if (Util.isObject(processor)) {
processor.nodes = nodes;
processor.edges = edges;
processor.groups = groups;
processor.graph = this;
processor.execute();
}
}
_pluginInit() {
@ -333,13 +333,13 @@ class Graph extends Base {
itemGroup.sortBy(child => {
const id = child.id;
const model = dataMap[id];
return model.index;
return model && model.index;
});
}
_clearInner() {
const items = this.getItems();
items.forEach(item => {
item && !item.destroyed && item.destroy();
item && item.destroy();
});
}
/**

View File

@ -70,7 +70,6 @@ class Item {
}
_init() {
this._setIndex();
this._setShapeObj();
this._initGroup();
this.draw();
}
@ -162,7 +161,6 @@ class Item {
item: this
});
this.updateCollapsedParent();
this._setShapeObj();
}
_shouldDraw() {
return true;
@ -186,8 +184,9 @@ class Item {
const animate = this.animate;
const group = this.group;
group.clear(!animate);
const shapeObj = this.shapeObj;
this._mapping();
this._setShapeObj();
const shapeObj = this.shapeObj;
const keyShape = shapeObj.draw(this);
if (keyShape) {
keyShape.isKeyShape = true;

View File

@ -22,8 +22,8 @@ Mixin.CFG = {
forcePreventAnimate: false,
_enterAnimate(item) {
if (!item.getKeyShape()) return;
const group = item.getGraphicGroup();
if (!item.getKeyShape()) return;
const box = item.getBBox();
const centerX = (box.minX + box.maxX) / 2;
const centerY = (box.minY + box.maxY) / 2;
@ -31,8 +31,11 @@ Mixin.CFG = {
},
_leaveAnimate(item) {
if (!item.getKeyShape()) return;
const group = item.getGraphicGroup();
if (!item.getKeyShape()) {
group.remove();
return;
}
const box = item.getBBox();
const centerX = (box.minX + box.maxX) / 2;
const centerY = (box.minY + box.maxY) / 2;

View File

@ -30,7 +30,7 @@ Mixin.AUGMENT = {
return layout;
} else if (Util.isFunction(layout) || Util.isObject(layout)) {
return {
processer: layout
processor: layout
};
}
return null;
@ -77,12 +77,12 @@ Mixin.AUGMENT = {
this.draw();
return this;
},
changeLayout(processer) {
this._getController('layout').changeLayout(processer);
changeLayout(processor) {
this._getController('layout').changeLayout(processor);
return this;
},
getLayout() {
return this._getController('layout').getLayoutProcesser();
return this._getController('layout').getLayoutProcessor();
}
};

View File

@ -79,6 +79,9 @@ Shape.registerEdge('common', {
const { labelOffsetX, labelOffsetY } = model;
if (label) {
const center = keyShape.getPoint(0.5);
if (!center) {
return;
}
center.x = labelOffsetX ? center.x + labelOffsetX : center.x;
center.y = labelOffsetY ? center.y + labelOffsetY : center.y;
const attrs = Util.mix(true, {}, Global.labelStyle, center);

View File

@ -30,14 +30,14 @@ class Tree extends Graph {
});
});
}
_executeLayout(processer) {
_executeLayout(processor) {
const source = this.get('_sourceData');
if (Util.isFunction(processer)) {
processer(source.roots, this);
} else if (Util.isObject(processer)) {
processer.roots = source.roots;
processer.graph = this;
processer.execute();
if (Util.isFunction(processor)) {
processor(source.roots, this);
} else if (Util.isObject(processor)) {
processor.roots = source.roots;
processor.graph = this;
processor.execute();
}
}
getHierarchy(item) {

View File

@ -17,7 +17,6 @@ const BaseUtil = {
throttle: require('lodash/throttle'),
debounce: require('lodash/debounce'),
uniq: require('lodash/uniq'),
/**
* traverse tree
* @param {object} parent parent

View File

@ -1 +1 @@
module.exports = '2.1.0-beta.19';
module.exports = '2.1.0-beta.21';

30683
test/test-spec.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -41,48 +41,24 @@ describe('highlight subgraph test', () => {
const edges = graph.getEdges();
const reNodes = [ nodes[0], nodes[1] ];
const reEdges = [ edges[0] ];
graph.highlightSubgraph({
reNodes,
reEdges
});
graph.highlightSubgraph(reNodes.concat(reEdges));
const items = graph.getItems();
let mask;
G6.Util.each(items, i => {
if (i.type === 'guide') {
mask = i;
return;
}
});
const mask = graph.find('mask');
expect(mask.isVisible()).eql(true);
});
it('unhighlight', () => {
graph.unhighlightGraph();
const items = graph.getItems();
let mask;
G6.Util.each(items, i => {
if (i.type === 'guide') {
mask = i;
return;
}
});
expect(mask.isVisible()).eql(false);
const mask = graph.find('mask');
expect(mask).eql(undefined);
});
it('highlight again', () => {
const nodes = graph.getNodes();
const reNodes = [ nodes[0] ];
const reEdges = [ ];
graph.highlightSubgraph({
reNodes,
reEdges
});
graph.highlightSubgraph(reNodes.concat(reEdges));
const items = graph.getItems();
let mask;
G6.Util.each(items, i => {
if (i.type === 'guide') {
mask = i;
return;
}
});
const mask = graph.find('mask');
expect(mask.isVisible()).eql(true);
});
it('graph destroy', () => {

View File

@ -39,7 +39,7 @@ describe('extract subgraph test', () => {
const {
reNodes,
reEdges
} = Util.extract(graph, 'bi', 1, [ node ]);
} = Util.extract('bi', [ node ]);
expect(reNodes.length).eql(3);
expect(reEdges.length).eql(2);
});
@ -48,7 +48,7 @@ describe('extract subgraph test', () => {
const {
reNodes,
reEdges
} = Util.extract(graph, 'in', 1, [ node ]);
} = Util.extract('in', [ node ]);
expect(reNodes.length).eql(2);
expect(reEdges.length).eql(1);
});
@ -57,7 +57,7 @@ describe('extract subgraph test', () => {
const {
reNodes,
reEdges
} = Util.extract(graph, 'out', 1, [ node ]);
} = Util.extract('out', [ node ]);
expect(reNodes.length).eql(2);
expect(reEdges.length).eql(1);
});