mirror of
https://gitee.com/antv/g6.git
synced 2024-12-04 20:59:15 +08:00
commit
4f3736665c
18
CHANGELOG.md
18
CHANGELOG.md
@ -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`
|
||||
|
74256
demos/assets/data/link-data.json
Normal file
74256
demos/assets/data/link-data.json
Normal file
File diff suppressed because it is too large
Load Diff
5381
demos/assets/data/tr.json
Normal file
5381
demos/assets/data/tr.json
Normal file
File diff suppressed because it is too large
Load Diff
530
demos/assets/data/usa-president.json
Normal file
530
demos/assets/data/usa-president.json
Normal 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"
|
||||
}
|
||||
]
|
49
demos/gallery-usa-president-sankey.html
Normal file
49
demos/gallery-usa-president-sankey.html
Normal 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>
|
160
demos/test.html
160
demos/test.html
@ -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>
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>紧凑树</title>
|
||||
<title>系统树</title>
|
||||
<style>
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
91
demos/yunqi-1.html
Normal 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
121
demos/yunqi-2.html
Normal 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
77
demos/yunqi-3.html
Normal 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>
|
10
package.json
10
package.json
@ -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",
|
||||
|
@ -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 => {
|
||||
|
@ -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/'),
|
||||
};
|
||||
|
@ -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);
|
||||
});
|
||||
```
|
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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 => {
|
||||
|
315
plugins/template.tableSankey/index.js
Normal file
315
plugins/template.tableSankey/index.js
Normal 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 - top、right、bottom、left
|
||||
*/
|
||||
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;
|
@ -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);
|
||||
```
|
@ -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;
|
||||
|
@ -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});
|
||||
```
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
```
|
@ -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);
|
||||
```
|
@ -20,6 +20,9 @@ class Plugin {
|
||||
this.graph.on('afterzoom', () => {
|
||||
this.textDisplay();
|
||||
});
|
||||
this.graph.textDisplay = ()=>{
|
||||
this.textDisplay();
|
||||
}
|
||||
}
|
||||
textDisplay() {
|
||||
const graph = this.graph;
|
||||
|
@ -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);
|
||||
```
|
13
plugins/util.backbone/index.js
Normal file
13
plugins/util.backbone/index.js
Normal 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);
|
@ -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: [],
|
@ -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') {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
22
src/graph.js
22
src/graph.js
@ -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();
|
||||
});
|
||||
}
|
||||
/**
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
14
src/tree.js
14
src/tree.js
@ -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) {
|
||||
|
@ -17,7 +17,6 @@ const BaseUtil = {
|
||||
throttle: require('lodash/throttle'),
|
||||
debounce: require('lodash/debounce'),
|
||||
uniq: require('lodash/uniq'),
|
||||
|
||||
/**
|
||||
* traverse tree
|
||||
* @param {object} parent parent
|
||||
|
@ -1 +1 @@
|
||||
module.exports = '2.1.0-beta.19';
|
||||
module.exports = '2.1.0-beta.21';
|
||||
|
30683
test/test-spec.js
Normal file
30683
test/test-spec.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -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', () => {
|
||||
|
@ -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);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user