Commit cc7592d4d64206f966c121ae2641914dff4cb3fd
1 parent
d14cd054
graphs update
Showing
8 changed files
with
1748 additions
and
5 deletions
datalets/graph-datalet/demo/demo-clustering-2.html
0 → 100644
| 1 | +<!DOCTYPE html> | ||
| 2 | +<html lang="en"> | ||
| 3 | +<head> | ||
| 4 | + <meta charset="UTF-8"> | ||
| 5 | + <title>Demo Graph with node clustering</title> | ||
| 6 | + <link rel="import" href="../graph-clustering-datalet.html"> | ||
| 7 | + <script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.js"></script> | ||
| 8 | + <script> | ||
| 9 | + function loadDoc() { | ||
| 10 | + var xhttp = new XMLHttpRequest(); | ||
| 11 | + xhttp.onreadystatechange = function() { | ||
| 12 | + if (xhttp.readyState == 4 && xhttp.status == 200) { | ||
| 13 | + document.getElementById("graph-placeholder").innerHTML = '<graph-clustering-datalet width="1000" height="700" graph=\'' + JSON.parse(xhttp.responseText).graph + | ||
| 14 | + '\'></graph-clustering-datalet>'; | ||
| 15 | + } | ||
| 16 | + }; | ||
| 17 | + xhttp.open("GET", "http://192.168.164.128/public_room/ajax/get-graph?id=1&type=comments", true); | ||
| 18 | + xhttp.send(); | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + loadDoc(); | ||
| 22 | + | ||
| 23 | + </script> | ||
| 24 | +</head> | ||
| 25 | +<body> | ||
| 26 | +<h1>Graph with clustering</h1> | ||
| 27 | +<div id="graph-placeholder"></div> | ||
| 28 | +<!--<graph-clustering-datalet width="1000" | ||
| 29 | + height="700" | ||
| 30 | + graph='{"nodes":[{"name":"Myriel","group":1},{"name":"Napoleon","group":1},{"name":"Mlle.Baptistine","group":1},{"name":"Mme.Magloire","group":1},{"name":"CountessdeLo","group":1},{"name":"Geborand","group":1},{"name":"Champtercier","group":1},{"name":"Cravatte","group":1},{"name":"Count","group":1},{"name":"OldMan","group":1},{"name":"Labarre","group":2},{"name":"Valjean","group":2},{"name":"Marguerite","group":3},{"name":"Mme.deR","group":2},{"name":"Isabeau","group":2},{"name":"Gervais","group":2},{"name":"Tholomyes","group":3},{"name":"Listolier","group":3},{"name":"Fameuil","group":3},{"name":"Blacheville","group":3},{"name":"Favourite","group":3},{"name":"Dahlia","group":3},{"name":"Zephine","group":3},{"name":"Fantine","group":3},{"name":"Mme.Thenardier","group":4},{"name":"Thenardier","group":4},{"name":"Cosette","group":5},{"name":"Javert","group":4},{"name":"Fauchelevent","group":0},{"name":"Bamatabois","group":2},{"name":"Perpetue","group":3},{"name":"Simplice","group":2},{"name":"Scaufflaire","group":2},{"name":"Woman1","group":2},{"name":"Judge","group":2},{"name":"Champmathieu","group":2},{"name":"Brevet","group":2},{"name":"Chenildieu","group":2},{"name":"Cochepaille","group":2},{"name":"Pontmercy","group":4},{"name":"Boulatruelle","group":6},{"name":"Eponine","group":4},{"name":"Anzelma","group":4},{"name":"Woman2","group":5},{"name":"MotherInnocent","group":0},{"name":"Gribier","group":0},{"name":"Jondrette","group":7},{"name":"Mme.Burgon","group":7},{"name":"Gavroche","group":8},{"name":"Gillenormand","group":5},{"name":"Magnon","group":5},{"name":"Mlle.Gillenormand","group":5},{"name":"Mme.Pontmercy","group":5},{"name":"Mlle.Vaubois","group":5},{"name":"Lt.Gillenormand","group":5},{"name":"Marius","group":8},{"name":"BaronessT","group":5},{"name":"Mabeuf","group":8},{"name":"Enjolras","group":8},{"name":"Combeferre","group":8},{"name":"Prouvaire","group":8},{"name":"Feuilly","group":8},{"name":"Courfeyrac","group":8},{"name":"Bahorel","group":8},{"name":"Bossuet","group":8},{"name":"Joly","group":8},{"name":"Grantaire","group":8},{"name":"MotherPlutarch","group":9},{"name":"Gueulemer","group":4},{"name":"Babet","group":4},{"name":"Claquesous","group":4},{"name":"Montparnasse","group":4},{"name":"Toussaint","group":5},{"name":"Child1","group":10},{"name":"Child2","group":10},{"name":"Brujon","group":4},{"name":"Mme.Hucheloup","group":8}],"links":[{"source":1,"target":0,"value":1},{"source":2,"target":0,"value":8},{"source":3,"target":0,"value":10},{"source":3,"target":2,"value":6},{"source":4,"target":0,"value":1},{"source":5,"target":0,"value":1},{"source":6,"target":0,"value":1},{"source":7,"target":0,"value":1},{"source":8,"target":0,"value":2},{"source":9,"target":0,"value":1},{"source":11,"target":10,"value":1},{"source":11,"target":3,"value":3},{"source":11,"target":2,"value":3},{"source":11,"target":0,"value":5},{"source":12,"target":11,"value":1},{"source":13,"target":11,"value":1},{"source":14,"target":11,"value":1},{"source":15,"target":11,"value":1},{"source":17,"target":16,"value":4},{"source":18,"target":16,"value":4},{"source":18,"target":17,"value":4},{"source":19,"target":16,"value":4},{"source":19,"target":17,"value":4},{"source":19,"target":18,"value":4},{"source":20,"target":16,"value":3},{"source":20,"target":17,"value":3},{"source":20,"target":18,"value":3},{"source":20,"target":19,"value":4},{"source":21,"target":16,"value":3},{"source":21,"target":17,"value":3},{"source":21,"target":18,"value":3},{"source":21,"target":19,"value":3},{"source":21,"target":20,"value":5},{"source":22,"target":16,"value":3},{"source":22,"target":17,"value":3},{"source":22,"target":18,"value":3},{"source":22,"target":19,"value":3},{"source":22,"target":20,"value":4},{"source":22,"target":21,"value":4},{"source":23,"target":16,"value":3},{"source":23,"target":17,"value":3},{"source":23,"target":18,"value":3},{"source":23,"target":19,"value":3},{"source":23,"target":20,"value":4},{"source":23,"target":21,"value":4},{"source":23,"target":22,"value":4},{"source":23,"target":12,"value":2},{"source":23,"target":11,"value":9},{"source":24,"target":23,"value":2},{"source":24,"target":11,"value":7},{"source":25,"target":24,"value":13},{"source":25,"target":23,"value":1},{"source":25,"target":11,"value":12},{"source":26,"target":24,"value":4},{"source":26,"target":11,"value":31},{"source":26,"target":16,"value":1},{"source":26,"target":25,"value":1},{"source":27,"target":11,"value":17},{"source":27,"target":23,"value":5},{"source":27,"target":25,"value":5},{"source":27,"target":24,"value":1},{"source":27,"target":26,"value":1},{"source":28,"target":11,"value":8},{"source":28,"target":27,"value":1},{"source":29,"target":23,"value":1},{"source":29,"target":27,"value":1},{"source":29,"target":11,"value":2},{"source":30,"target":23,"value":1},{"source":31,"target":30,"value":2},{"source":31,"target":11,"value":3},{"source":31,"target":23,"value":2},{"source":31,"target":27,"value":1},{"source":32,"target":11,"value":1},{"source":33,"target":11,"value":2},{"source":33,"target":27,"value":1},{"source":34,"target":11,"value":3},{"source":34,"target":29,"value":2},{"source":35,"target":11,"value":3},{"source":35,"target":34,"value":3},{"source":35,"target":29,"value":2},{"source":36,"target":34,"value":2},{"source":36,"target":35,"value":2},{"source":36,"target":11,"value":2},{"source":36,"target":29,"value":1},{"source":37,"target":34,"value":2},{"source":37,"target":35,"value":2},{"source":37,"target":36,"value":2},{"source":37,"target":11,"value":2},{"source":37,"target":29,"value":1},{"source":38,"target":34,"value":2},{"source":38,"target":35,"value":2},{"source":38,"target":36,"value":2},{"source":38,"target":37,"value":2},{"source":38,"target":11,"value":2},{"source":38,"target":29,"value":1},{"source":39,"target":25,"value":1},{"source":40,"target":25,"value":1},{"source":41,"target":24,"value":2},{"source":41,"target":25,"value":3},{"source":42,"target":41,"value":2},{"source":42,"target":25,"value":2},{"source":42,"target":24,"value":1},{"source":43,"target":11,"value":3},{"source":43,"target":26,"value":1},{"source":43,"target":27,"value":1},{"source":44,"target":28,"value":3},{"source":44,"target":11,"value":1},{"source":45,"target":28,"value":2},{"source":47,"target":46,"value":1},{"source":48,"target":47,"value":2},{"source":48,"target":25,"value":1},{"source":48,"target":27,"value":1},{"source":48,"target":11,"value":1},{"source":49,"target":26,"value":3},{"source":49,"target":11,"value":2},{"source":50,"target":49,"value":1},{"source":50,"target":24,"value":1},{"source":51,"target":49,"value":9},{"source":51,"target":26,"value":2},{"source":51,"target":11,"value":2},{"source":52,"target":51,"value":1},{"source":52,"target":39,"value":1},{"source":53,"target":51,"value":1},{"source":54,"target":51,"value":2},{"source":54,"target":49,"value":1},{"source":54,"target":26,"value":1},{"source":55,"target":51,"value":6},{"source":55,"target":49,"value":12},{"source":55,"target":39,"value":1},{"source":55,"target":54,"value":1},{"source":55,"target":26,"value":21},{"source":55,"target":11,"value":19},{"source":55,"target":16,"value":1},{"source":55,"target":25,"value":2},{"source":55,"target":41,"value":5},{"source":55,"target":48,"value":4},{"source":56,"target":49,"value":1},{"source":56,"target":55,"value":1},{"source":57,"target":55,"value":1},{"source":57,"target":41,"value":1},{"source":57,"target":48,"value":1},{"source":58,"target":55,"value":7},{"source":58,"target":48,"value":7},{"source":58,"target":27,"value":6},{"source":58,"target":57,"value":1},{"source":58,"target":11,"value":4},{"source":59,"target":58,"value":15},{"source":59,"target":55,"value":5},{"source":59,"target":48,"value":6},{"source":59,"target":57,"value":2},{"source":60,"target":48,"value":1},{"source":60,"target":58,"value":4},{"source":60,"target":59,"value":2},{"source":61,"target":48,"value":2},{"source":61,"target":58,"value":6},{"source":61,"target":60,"value":2},{"source":61,"target":59,"value":5},{"source":61,"target":57,"value":1},{"source":61,"target":55,"value":1},{"source":62,"target":55,"value":9},{"source":62,"target":58,"value":17},{"source":62,"target":59,"value":13},{"source":62,"target":48,"value":7},{"source":62,"target":57,"value":2},{"source":62,"target":41,"value":1},{"source":62,"target":61,"value":6},{"source":62,"target":60,"value":3},{"source":63,"target":59,"value":5},{"source":63,"target":48,"value":5},{"source":63,"target":62,"value":6},{"source":63,"target":57,"value":2},{"source":63,"target":58,"value":4},{"source":63,"target":61,"value":3},{"source":63,"target":60,"value":2},{"source":63,"target":55,"value":1},{"source":64,"target":55,"value":5},{"source":64,"target":62,"value":12},{"source":64,"target":48,"value":5},{"source":64,"target":63,"value":4},{"source":64,"target":58,"value":10},{"source":64,"target":61,"value":6},{"source":64,"target":60,"value":2},{"source":64,"target":59,"value":9},{"source":64,"target":57,"value":1},{"source":64,"target":11,"value":1},{"source":65,"target":63,"value":5},{"source":65,"target":64,"value":7},{"source":65,"target":48,"value":3},{"source":65,"target":62,"value":5},{"source":65,"target":58,"value":5},{"source":65,"target":61,"value":5},{"source":65,"target":60,"value":2},{"source":65,"target":59,"value":5},{"source":65,"target":57,"value":1},{"source":65,"target":55,"value":2},{"source":66,"target":64,"value":3},{"source":66,"target":58,"value":3},{"source":66,"target":59,"value":1},{"source":66,"target":62,"value":2},{"source":66,"target":65,"value":2},{"source":66,"target":48,"value":1},{"source":66,"target":63,"value":1},{"source":66,"target":61,"value":1},{"source":66,"target":60,"value":1},{"source":67,"target":57,"value":3},{"source":68,"target":25,"value":5},{"source":68,"target":11,"value":1},{"source":68,"target":24,"value":1},{"source":68,"target":27,"value":1},{"source":68,"target":48,"value":1},{"source":68,"target":41,"value":1},{"source":69,"target":25,"value":6},{"source":69,"target":68,"value":6},{"source":69,"target":11,"value":1},{"source":69,"target":24,"value":1},{"source":69,"target":27,"value":2},{"source":69,"target":48,"value":1},{"source":69,"target":41,"value":1},{"source":70,"target":25,"value":4},{"source":70,"target":69,"value":4},{"source":70,"target":68,"value":4},{"source":70,"target":11,"value":1},{"source":70,"target":24,"value":1},{"source":70,"target":27,"value":1},{"source":70,"target":41,"value":1},{"source":70,"target":58,"value":1},{"source":71,"target":27,"value":1},{"source":71,"target":69,"value":2},{"source":71,"target":68,"value":2},{"source":71,"target":70,"value":2},{"source":71,"target":11,"value":1},{"source":71,"target":48,"value":1},{"source":71,"target":41,"value":1},{"source":71,"target":25,"value":1},{"source":72,"target":26,"value":2},{"source":72,"target":27,"value":1},{"source":72,"target":11,"value":1},{"source":73,"target":48,"value":2},{"source":74,"target":48,"value":2},{"source":74,"target":73,"value":3},{"source":75,"target":69,"value":3},{"source":75,"target":68,"value":3},{"source":75,"target":25,"value":3},{"source":75,"target":48,"value":1},{"source":75,"target":41,"value":1},{"source":75,"target":70,"value":1},{"source":75,"target":71,"value":1},{"source":76,"target":64,"value":1},{"source":76,"target":65,"value":1},{"source":76,"target":66,"value":1},{"source":76,"target":63,"value":1},{"source":76,"target":62,"value":1},{"source":76,"target":48,"value":1},{"source":76,"target":58,"value":1}]}' | ||
| 31 | + ></graph-clustering-datalet>--> | ||
| 32 | + | ||
| 33 | +</body> | ||
| 34 | +</html> | ||
| 0 | \ No newline at end of file | 35 | \ No newline at end of file |
datalets/graph-datalet/demo/demo-clustering.html
0 → 100644
| 1 | +<!DOCTYPE html> | ||
| 2 | +<html lang="en"> | ||
| 3 | +<head> | ||
| 4 | + <meta charset="UTF-8"> | ||
| 5 | + <title>Demo Graph with node clustering</title> | ||
| 6 | + <link rel="import" href="../graph-with-clustering-datalet.html"> | ||
| 7 | + <script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.js"></script> | ||
| 8 | +</head> | ||
| 9 | +<script> | ||
| 10 | + function loadDoc() { | ||
| 11 | + var xhttp = new XMLHttpRequest(); | ||
| 12 | + xhttp.onreadystatechange = function() { | ||
| 13 | + if (xhttp.readyState == 4 && xhttp.status == 200) { | ||
| 14 | + document.getElementById("graph-placeholder").innerHTML = '<graph-with-clustering-datalet width="1000" height="700" graph=\'' + JSON.parse(xhttp.responseText).graph + | ||
| 15 | + '\'></graph-with-clustering-datalet>'; | ||
| 16 | + } | ||
| 17 | + }; | ||
| 18 | + xhttp.open("GET", "http://192.168.164.128/public_room/ajax/get-graph?id=1&type=comments", true); | ||
| 19 | + xhttp.send(); | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + loadDoc(); | ||
| 23 | + | ||
| 24 | +</script> | ||
| 25 | +<body> | ||
| 26 | +<h1>Graph with clustering</h1> | ||
| 27 | +<!-- | ||
| 28 | +graph='{"nodes":[{"name":"Myriel","group":1},{"name":"Napoleon","group":1},{"name":"Mlle.Baptistine","group":1},{"name":"Mme.Magloire","group":1},{"name":"CountessdeLo","group":1},{"name":"Geborand","group":1},{"name":"Champtercier","group":1},{"name":"Cravatte","group":1},{"name":"Count","group":1},{"name":"OldMan","group":1},{"name":"Labarre","group":2},{"name":"Valjean","group":2},{"name":"Marguerite","group":3},{"name":"Mme.deR","group":2},{"name":"Isabeau","group":2},{"name":"Gervais","group":2},{"name":"Tholomyes","group":3},{"name":"Listolier","group":3},{"name":"Fameuil","group":3},{"name":"Blacheville","group":3},{"name":"Favourite","group":3},{"name":"Dahlia","group":3},{"name":"Zephine","group":3},{"name":"Fantine","group":3},{"name":"Mme.Thenardier","group":4},{"name":"Thenardier","group":4},{"name":"Cosette","group":5},{"name":"Javert","group":4},{"name":"Fauchelevent","group":0},{"name":"Bamatabois","group":2},{"name":"Perpetue","group":3},{"name":"Simplice","group":2},{"name":"Scaufflaire","group":2},{"name":"Woman1","group":2},{"name":"Judge","group":2},{"name":"Champmathieu","group":2},{"name":"Brevet","group":2},{"name":"Chenildieu","group":2},{"name":"Cochepaille","group":2},{"name":"Pontmercy","group":4},{"name":"Boulatruelle","group":6},{"name":"Eponine","group":4},{"name":"Anzelma","group":4},{"name":"Woman2","group":5},{"name":"MotherInnocent","group":0},{"name":"Gribier","group":0},{"name":"Jondrette","group":7},{"name":"Mme.Burgon","group":7},{"name":"Gavroche","group":8},{"name":"Gillenormand","group":5},{"name":"Magnon","group":5},{"name":"Mlle.Gillenormand","group":5},{"name":"Mme.Pontmercy","group":5},{"name":"Mlle.Vaubois","group":5},{"name":"Lt.Gillenormand","group":5},{"name":"Marius","group":8},{"name":"BaronessT","group":5},{"name":"Mabeuf","group":8},{"name":"Enjolras","group":8},{"name":"Combeferre","group":8},{"name":"Prouvaire","group":8},{"name":"Feuilly","group":8},{"name":"Courfeyrac","group":8},{"name":"Bahorel","group":8},{"name":"Bossuet","group":8},{"name":"Joly","group":8},{"name":"Grantaire","group":8},{"name":"MotherPlutarch","group":9},{"name":"Gueulemer","group":4},{"name":"Babet","group":4},{"name":"Claquesous","group":4},{"name":"Montparnasse","group":4},{"name":"Toussaint","group":5},{"name":"Child1","group":10},{"name":"Child2","group":10},{"name":"Brujon","group":4},{"name":"Mme.Hucheloup","group":8}],"links":[{"source":1,"target":0,"value":1},{"source":2,"target":0,"value":8},{"source":3,"target":0,"value":10},{"source":3,"target":2,"value":6},{"source":4,"target":0,"value":1},{"source":5,"target":0,"value":1},{"source":6,"target":0,"value":1},{"source":7,"target":0,"value":1},{"source":8,"target":0,"value":2},{"source":9,"target":0,"value":1},{"source":11,"target":10,"value":1},{"source":11,"target":3,"value":3},{"source":11,"target":2,"value":3},{"source":11,"target":0,"value":5},{"source":12,"target":11,"value":1},{"source":13,"target":11,"value":1},{"source":14,"target":11,"value":1},{"source":15,"target":11,"value":1},{"source":17,"target":16,"value":4},{"source":18,"target":16,"value":4},{"source":18,"target":17,"value":4},{"source":19,"target":16,"value":4},{"source":19,"target":17,"value":4},{"source":19,"target":18,"value":4},{"source":20,"target":16,"value":3},{"source":20,"target":17,"value":3},{"source":20,"target":18,"value":3},{"source":20,"target":19,"value":4},{"source":21,"target":16,"value":3},{"source":21,"target":17,"value":3},{"source":21,"target":18,"value":3},{"source":21,"target":19,"value":3},{"source":21,"target":20,"value":5},{"source":22,"target":16,"value":3},{"source":22,"target":17,"value":3},{"source":22,"target":18,"value":3},{"source":22,"target":19,"value":3},{"source":22,"target":20,"value":4},{"source":22,"target":21,"value":4},{"source":23,"target":16,"value":3},{"source":23,"target":17,"value":3},{"source":23,"target":18,"value":3},{"source":23,"target":19,"value":3},{"source":23,"target":20,"value":4},{"source":23,"target":21,"value":4},{"source":23,"target":22,"value":4},{"source":23,"target":12,"value":2},{"source":23,"target":11,"value":9},{"source":24,"target":23,"value":2},{"source":24,"target":11,"value":7},{"source":25,"target":24,"value":13},{"source":25,"target":23,"value":1},{"source":25,"target":11,"value":12},{"source":26,"target":24,"value":4},{"source":26,"target":11,"value":31},{"source":26,"target":16,"value":1},{"source":26,"target":25,"value":1},{"source":27,"target":11,"value":17},{"source":27,"target":23,"value":5},{"source":27,"target":25,"value":5},{"source":27,"target":24,"value":1},{"source":27,"target":26,"value":1},{"source":28,"target":11,"value":8},{"source":28,"target":27,"value":1},{"source":29,"target":23,"value":1},{"source":29,"target":27,"value":1},{"source":29,"target":11,"value":2},{"source":30,"target":23,"value":1},{"source":31,"target":30,"value":2},{"source":31,"target":11,"value":3},{"source":31,"target":23,"value":2},{"source":31,"target":27,"value":1},{"source":32,"target":11,"value":1},{"source":33,"target":11,"value":2},{"source":33,"target":27,"value":1},{"source":34,"target":11,"value":3},{"source":34,"target":29,"value":2},{"source":35,"target":11,"value":3},{"source":35,"target":34,"value":3},{"source":35,"target":29,"value":2},{"source":36,"target":34,"value":2},{"source":36,"target":35,"value":2},{"source":36,"target":11,"value":2},{"source":36,"target":29,"value":1},{"source":37,"target":34,"value":2},{"source":37,"target":35,"value":2},{"source":37,"target":36,"value":2},{"source":37,"target":11,"value":2},{"source":37,"target":29,"value":1},{"source":38,"target":34,"value":2},{"source":38,"target":35,"value":2},{"source":38,"target":36,"value":2},{"source":38,"target":37,"value":2},{"source":38,"target":11,"value":2},{"source":38,"target":29,"value":1},{"source":39,"target":25,"value":1},{"source":40,"target":25,"value":1},{"source":41,"target":24,"value":2},{"source":41,"target":25,"value":3},{"source":42,"target":41,"value":2},{"source":42,"target":25,"value":2},{"source":42,"target":24,"value":1},{"source":43,"target":11,"value":3},{"source":43,"target":26,"value":1},{"source":43,"target":27,"value":1},{"source":44,"target":28,"value":3},{"source":44,"target":11,"value":1},{"source":45,"target":28,"value":2},{"source":47,"target":46,"value":1},{"source":48,"target":47,"value":2},{"source":48,"target":25,"value":1},{"source":48,"target":27,"value":1},{"source":48,"target":11,"value":1},{"source":49,"target":26,"value":3},{"source":49,"target":11,"value":2},{"source":50,"target":49,"value":1},{"source":50,"target":24,"value":1},{"source":51,"target":49,"value":9},{"source":51,"target":26,"value":2},{"source":51,"target":11,"value":2},{"source":52,"target":51,"value":1},{"source":52,"target":39,"value":1},{"source":53,"target":51,"value":1},{"source":54,"target":51,"value":2},{"source":54,"target":49,"value":1},{"source":54,"target":26,"value":1},{"source":55,"target":51,"value":6},{"source":55,"target":49,"value":12},{"source":55,"target":39,"value":1},{"source":55,"target":54,"value":1},{"source":55,"target":26,"value":21},{"source":55,"target":11,"value":19},{"source":55,"target":16,"value":1},{"source":55,"target":25,"value":2},{"source":55,"target":41,"value":5},{"source":55,"target":48,"value":4},{"source":56,"target":49,"value":1},{"source":56,"target":55,"value":1},{"source":57,"target":55,"value":1},{"source":57,"target":41,"value":1},{"source":57,"target":48,"value":1},{"source":58,"target":55,"value":7},{"source":58,"target":48,"value":7},{"source":58,"target":27,"value":6},{"source":58,"target":57,"value":1},{"source":58,"target":11,"value":4},{"source":59,"target":58,"value":15},{"source":59,"target":55,"value":5},{"source":59,"target":48,"value":6},{"source":59,"target":57,"value":2},{"source":60,"target":48,"value":1},{"source":60,"target":58,"value":4},{"source":60,"target":59,"value":2},{"source":61,"target":48,"value":2},{"source":61,"target":58,"value":6},{"source":61,"target":60,"value":2},{"source":61,"target":59,"value":5},{"source":61,"target":57,"value":1},{"source":61,"target":55,"value":1},{"source":62,"target":55,"value":9},{"source":62,"target":58,"value":17},{"source":62,"target":59,"value":13},{"source":62,"target":48,"value":7},{"source":62,"target":57,"value":2},{"source":62,"target":41,"value":1},{"source":62,"target":61,"value":6},{"source":62,"target":60,"value":3},{"source":63,"target":59,"value":5},{"source":63,"target":48,"value":5},{"source":63,"target":62,"value":6},{"source":63,"target":57,"value":2},{"source":63,"target":58,"value":4},{"source":63,"target":61,"value":3},{"source":63,"target":60,"value":2},{"source":63,"target":55,"value":1},{"source":64,"target":55,"value":5},{"source":64,"target":62,"value":12},{"source":64,"target":48,"value":5},{"source":64,"target":63,"value":4},{"source":64,"target":58,"value":10},{"source":64,"target":61,"value":6},{"source":64,"target":60,"value":2},{"source":64,"target":59,"value":9},{"source":64,"target":57,"value":1},{"source":64,"target":11,"value":1},{"source":65,"target":63,"value":5},{"source":65,"target":64,"value":7},{"source":65,"target":48,"value":3},{"source":65,"target":62,"value":5},{"source":65,"target":58,"value":5},{"source":65,"target":61,"value":5},{"source":65,"target":60,"value":2},{"source":65,"target":59,"value":5},{"source":65,"target":57,"value":1},{"source":65,"target":55,"value":2},{"source":66,"target":64,"value":3},{"source":66,"target":58,"value":3},{"source":66,"target":59,"value":1},{"source":66,"target":62,"value":2},{"source":66,"target":65,"value":2},{"source":66,"target":48,"value":1},{"source":66,"target":63,"value":1},{"source":66,"target":61,"value":1},{"source":66,"target":60,"value":1},{"source":67,"target":57,"value":3},{"source":68,"target":25,"value":5},{"source":68,"target":11,"value":1},{"source":68,"target":24,"value":1},{"source":68,"target":27,"value":1},{"source":68,"target":48,"value":1},{"source":68,"target":41,"value":1},{"source":69,"target":25,"value":6},{"source":69,"target":68,"value":6},{"source":69,"target":11,"value":1},{"source":69,"target":24,"value":1},{"source":69,"target":27,"value":2},{"source":69,"target":48,"value":1},{"source":69,"target":41,"value":1},{"source":70,"target":25,"value":4},{"source":70,"target":69,"value":4},{"source":70,"target":68,"value":4},{"source":70,"target":11,"value":1},{"source":70,"target":24,"value":1},{"source":70,"target":27,"value":1},{"source":70,"target":41,"value":1},{"source":70,"target":58,"value":1},{"source":71,"target":27,"value":1},{"source":71,"target":69,"value":2},{"source":71,"target":68,"value":2},{"source":71,"target":70,"value":2},{"source":71,"target":11,"value":1},{"source":71,"target":48,"value":1},{"source":71,"target":41,"value":1},{"source":71,"target":25,"value":1},{"source":72,"target":26,"value":2},{"source":72,"target":27,"value":1},{"source":72,"target":11,"value":1},{"source":73,"target":48,"value":2},{"source":74,"target":48,"value":2},{"source":74,"target":73,"value":3},{"source":75,"target":69,"value":3},{"source":75,"target":68,"value":3},{"source":75,"target":25,"value":3},{"source":75,"target":48,"value":1},{"source":75,"target":41,"value":1},{"source":75,"target":70,"value":1},{"source":75,"target":71,"value":1},{"source":76,"target":64,"value":1},{"source":76,"target":65,"value":1},{"source":76,"target":66,"value":1},{"source":76,"target":63,"value":1},{"source":76,"target":62,"value":1},{"source":76,"target":48,"value":1},{"source":76,"target":58,"value":1}]}' | ||
| 29 | +--> | ||
| 30 | +<div id="graph-placeholder"></div> | ||
| 31 | + | ||
| 32 | +</body> | ||
| 33 | +</html> | ||
| 0 | \ No newline at end of file | 34 | \ No newline at end of file |
datalets/graph-datalet/graph-clustering-datalet.html
0 → 100644
| 1 | +<!-- | ||
| 2 | +@license | ||
| 3 | + The MIT License (MIT) | ||
| 4 | + | ||
| 5 | + Copyright (c) 2015 Dipartimento di Informatica - Università di Salerno - Italy | ||
| 6 | + | ||
| 7 | + Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 8 | + of this software and associated documentation files (the "Software"), to deal | ||
| 9 | + in the Software without restriction, including without limitation the rights | ||
| 10 | + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 11 | + copies of the Software, and to permit persons to whom the Software is | ||
| 12 | + furnished to do so, subject to the following conditions: | ||
| 13 | + | ||
| 14 | + The above copyright notice and this permission notice shall be included in | ||
| 15 | + all copies or substantial portions of the Software. | ||
| 16 | + | ||
| 17 | + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 18 | + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 19 | + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 20 | + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 21 | + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 22 | + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| 23 | + THE SOFTWARE. | ||
| 24 | +--> | ||
| 25 | + | ||
| 26 | +<!-- | ||
| 27 | +* Developed by : | ||
| 28 | +* ROUTE-TO-PA Project - grant No 645860. - www.routetopa.eu | ||
| 29 | +* | ||
| 30 | +--> | ||
| 31 | + | ||
| 32 | +<link rel="import" href="../base-datalet/base-datalet.html"> | ||
| 33 | +<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout.html"> | ||
| 34 | +<link rel="import" href="../../bower_components/paper-dialog/paper-dialog.html"> | ||
| 35 | +<link rel="import" href="../../bower_components/paper-fab/paper-fab.html"> | ||
| 36 | + | ||
| 37 | +<!-- | ||
| 38 | +`preview-datalet` is a datalet that allow user to preview the content of a web page. It creates a thumbnail of the site using the data-url attribute passed as input. | ||
| 39 | + | ||
| 40 | +Example: | ||
| 41 | + | ||
| 42 | + <preview-datalet data-url="http://spod.routetopa.eu" | ||
| 43 | + </preview-datalet> | ||
| 44 | + | ||
| 45 | + | ||
| 46 | +@element preview-datalet | ||
| 47 | +@status beta | ||
| 48 | +@homepage | ||
| 49 | +@group datalets | ||
| 50 | +--> | ||
| 51 | + | ||
| 52 | +<dom-module id="graph-clustering-datalet"> | ||
| 53 | + <template> | ||
| 54 | + | ||
| 55 | + <link rel="stylesheet" href="static/css/graphClusteringStyle.css"> | ||
| 56 | + | ||
| 57 | + <style is="custom-style"> | ||
| 58 | + | ||
| 59 | + #dialog{ | ||
| 60 | + position: absolute; | ||
| 61 | + padding: 20px; | ||
| 62 | + top: 20px; | ||
| 63 | + right:5%; | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + #close{ | ||
| 67 | + position: absolute; | ||
| 68 | + top: -20px; | ||
| 69 | + right: 3px; | ||
| 70 | + --iron-icon-height: 20px; | ||
| 71 | + --iron-icon-width: 20px; | ||
| 72 | + width: 24px; | ||
| 73 | + height: 24px; | ||
| 74 | + --paper-fab-background:#9e9e9e; | ||
| 75 | + z-index: 1001; | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + </style> | ||
| 79 | + | ||
| 80 | + <div style="align-content: center;overflow: visible" id="graph_content"> | ||
| 81 | + <svg id="sbiricuda"></svg> | ||
| 82 | + </div> | ||
| 83 | + | ||
| 84 | + <paper-dialog id="dialog"> | ||
| 85 | + <paper-fab id="close" mini icon="close" on-click="_onCloseClick"></paper-fab> | ||
| 86 | + <h2 id="dialog_title"></h2> | ||
| 87 | + <paper-dialog-scrollable id="dialog_content">cos</paper-dialog-scrollable> | ||
| 88 | + </paper-dialog> | ||
| 89 | + | ||
| 90 | + </template> | ||
| 91 | + | ||
| 92 | + <script src="static/js/d3.v3.js"></script> | ||
| 93 | + | ||
| 94 | + <script> | ||
| 95 | + _this = null; | ||
| 96 | + | ||
| 97 | + var dr = 4, // default point radius | ||
| 98 | + off = 15, // cluster hull offset | ||
| 99 | + expand = {}, // expanded clusters | ||
| 100 | + data, net, force, hullg, hull, linkg, link, nodeg, node; | ||
| 101 | + | ||
| 102 | + | ||
| 103 | + var fill = d3.scale.category20(); | ||
| 104 | + var curve = d3.svg.line() | ||
| 105 | + .interpolate("cardinal-closed") | ||
| 106 | + .tension(.85); | ||
| 107 | + | ||
| 108 | + Polymer({ | ||
| 109 | + is : 'graph-clustering-datalet', | ||
| 110 | + | ||
| 111 | + properties: { | ||
| 112 | + /** | ||
| 113 | + * It's the url for the preview | ||
| 114 | + * | ||
| 115 | + * @attribute url | ||
| 116 | + * @type Strig | ||
| 117 | + * @default '' | ||
| 118 | + */ | ||
| 119 | + width: { | ||
| 120 | + type: Number, | ||
| 121 | + value: undefined | ||
| 122 | + }, | ||
| 123 | + | ||
| 124 | + height: { | ||
| 125 | + type: Number, | ||
| 126 | + type: undefined | ||
| 127 | + }, | ||
| 128 | + | ||
| 129 | + svg: { | ||
| 130 | + type: Object, | ||
| 131 | + value: undefined | ||
| 132 | + }, | ||
| 133 | + | ||
| 134 | + feelings: { | ||
| 135 | + type: Array, | ||
| 136 | + values: ["Agree", "Neutral", "Not agree"] | ||
| 137 | + }, | ||
| 138 | + | ||
| 139 | + gnodes : { | ||
| 140 | + type : Array, | ||
| 141 | + value : [] | ||
| 142 | + }, | ||
| 143 | + | ||
| 144 | + glinks : { | ||
| 145 | + type :Array, | ||
| 146 | + value : [] | ||
| 147 | + }, | ||
| 148 | + | ||
| 149 | + graph : { | ||
| 150 | + type : Object, | ||
| 151 | + value : {} | ||
| 152 | + }, | ||
| 153 | + | ||
| 154 | + prev_selected_node : { | ||
| 155 | + type : Object, | ||
| 156 | + value : null | ||
| 157 | + } | ||
| 158 | + }, | ||
| 159 | + | ||
| 160 | + /* fill : function(group){ | ||
| 161 | + d3.scale.category20(); | ||
| 162 | + },*/ | ||
| 163 | + | ||
| 164 | + noop : function() { return false; }, | ||
| 165 | + | ||
| 166 | + nodeid : function(n) { | ||
| 167 | + return n.size ? "_g_"+n.group : n.name; | ||
| 168 | + }, | ||
| 169 | + | ||
| 170 | + linkid: function(l) { | ||
| 171 | + var u = _this.nodeid(l.source), | ||
| 172 | + v = _this.nodeid(l.target); | ||
| 173 | + return u<v ? u+"|"+v : v+"|"+u; | ||
| 174 | + }, | ||
| 175 | + | ||
| 176 | + getGroup: function(n) { | ||
| 177 | + return n.group; | ||
| 178 | + }, | ||
| 179 | + | ||
| 180 | + // constructs the network to visualize | ||
| 181 | + network : function(prev, index, expand) { | ||
| 182 | + expand = expand || {}; | ||
| 183 | + var gm = {}, // group map | ||
| 184 | + nm = {}, // node map | ||
| 185 | + lm = {}, // link map | ||
| 186 | + gn = {}, // previous group nodes | ||
| 187 | + gc = {}, // previous group centroids | ||
| 188 | + nodes = [], // output nodes | ||
| 189 | + links = []; // output links | ||
| 190 | + | ||
| 191 | + // process previous nodes for reuse or centroid calculation | ||
| 192 | + if (prev) { | ||
| 193 | + prev.nodes.forEach(function(n) { | ||
| 194 | + var i = index(n), o; | ||
| 195 | + if (n.size > 0) { | ||
| 196 | + gn[i] = n; | ||
| 197 | + n.size = 0; | ||
| 198 | + } else { | ||
| 199 | + o = gc[i] || (gc[i] = {x:0,y:0,count:0}); | ||
| 200 | + o.x += n.x; | ||
| 201 | + o.y += n.y; | ||
| 202 | + o.count += 1; | ||
| 203 | + } | ||
| 204 | + }); | ||
| 205 | + } | ||
| 206 | + | ||
| 207 | + // determine nodes | ||
| 208 | + for (var k=0; k < this.graph.nodes.length; ++k) { | ||
| 209 | + var n = this.graph.nodes[k], | ||
| 210 | + i = index(n), | ||
| 211 | + l = gm[i] || (gm[i]=gn[i]) || (gm[i]={group:i, size:0, nodes:[]}); | ||
| 212 | + | ||
| 213 | + if (expand[i]) { | ||
| 214 | + // the node should be directly visible | ||
| 215 | + nm[n.name] = nodes.length; | ||
| 216 | + nodes.push(n); | ||
| 217 | + if (gn[i]) { | ||
| 218 | + // place new nodes at cluster location (plus jitter) | ||
| 219 | + n.x = gn[i].x + Math.random(); | ||
| 220 | + n.y = gn[i].y + Math.random(); | ||
| 221 | + } | ||
| 222 | + } else { | ||
| 223 | + // the node is part of a collapsed cluster | ||
| 224 | + if (l.size == 0) { | ||
| 225 | + // if new cluster, add to set and position at centroid of leaf nodes | ||
| 226 | + nm[i] = nodes.length; | ||
| 227 | + nodes.push(l); | ||
| 228 | + if (gc[i]) { | ||
| 229 | + l.x = gc[i].x / gc[i].count; | ||
| 230 | + l.y = gc[i].y / gc[i].count; | ||
| 231 | + } | ||
| 232 | + } | ||
| 233 | + l.nodes.push(n); | ||
| 234 | + } | ||
| 235 | + // always count group size as we also use it to tweak the force graph strengths/distances | ||
| 236 | + l.size += 1; | ||
| 237 | + n.group_data = l; | ||
| 238 | + } | ||
| 239 | + | ||
| 240 | + for (i in gm) { gm[i].link_count = 0; } | ||
| 241 | + | ||
| 242 | + // determine links | ||
| 243 | + for (k=0; k<this.graph.links.length; ++k) { | ||
| 244 | + var e = this.graph.links[k], | ||
| 245 | + u = index(e.source), | ||
| 246 | + v = index(e.target); | ||
| 247 | + if (u != v) { | ||
| 248 | + gm[u].link_count++; | ||
| 249 | + gm[v].link_count++; | ||
| 250 | + } | ||
| 251 | + u = expand[u] ? nm[e.source.name] : nm[u]; | ||
| 252 | + v = expand[v] ? nm[e.target.name] : nm[v]; | ||
| 253 | + var i = (u<v ? u+"|"+v : v+"|"+u), | ||
| 254 | + l = lm[i] || (lm[i] = {source:u, target:v, size:0}); | ||
| 255 | + l.size += 1; | ||
| 256 | + } | ||
| 257 | + for (i in lm) { links.push(lm[i]); } | ||
| 258 | + | ||
| 259 | + return {nodes: nodes, links: links}; | ||
| 260 | + }, | ||
| 261 | + | ||
| 262 | + // constructs the network to visualize | ||
| 263 | + | ||
| 264 | + convexHulls : function(nodes, index, offset) { | ||
| 265 | + var hulls = {}; | ||
| 266 | + | ||
| 267 | + // create point sets | ||
| 268 | + for (var k=0; k<nodes.length; ++k) { | ||
| 269 | + var n = nodes[k]; | ||
| 270 | + if (n.size) continue; | ||
| 271 | + var i = index(n), | ||
| 272 | + l = hulls[i] || (hulls[i] = []); | ||
| 273 | + l.push([n.x-offset, n.y-offset]); | ||
| 274 | + l.push([n.x-offset, n.y+offset]); | ||
| 275 | + l.push([n.x+offset, n.y-offset]); | ||
| 276 | + l.push([n.x+offset, n.y+offset]); | ||
| 277 | + } | ||
| 278 | + | ||
| 279 | + // create convex hulls | ||
| 280 | + var hullset = []; | ||
| 281 | + for (i in hulls) { | ||
| 282 | + hullset.push({group: i, path: d3.geom.hull(hulls[i])}); | ||
| 283 | + } | ||
| 284 | + return hullset; | ||
| 285 | + }, | ||
| 286 | + | ||
| 287 | + drawCluster : function(d) { | ||
| 288 | + return curve(d.path); // 0.8 | ||
| 289 | + }, | ||
| 290 | + | ||
| 291 | + init : function() { | ||
| 292 | + if (force) force.stop(); | ||
| 293 | + | ||
| 294 | + net = this.network(net, this.getGroup, expand); | ||
| 295 | + | ||
| 296 | + force = d3.layout.force() | ||
| 297 | + .nodes(net.nodes) | ||
| 298 | + .links(net.links) | ||
| 299 | + .size([this.width, this.height]) | ||
| 300 | + .linkDistance(function(l, i) { | ||
| 301 | + var n1 = l.source, n2 = l.target; | ||
| 302 | + // larger distance for bigger groups: | ||
| 303 | + // both between single nodes and _other_ groups (where size of own node group still counts), | ||
| 304 | + // and between two group nodes. | ||
| 305 | + // | ||
| 306 | + // reduce distance for groups with very few outer links, | ||
| 307 | + // again both in expanded and grouped form, i.e. between individual nodes of a group and | ||
| 308 | + // nodes of another group or other group node or between two group nodes. | ||
| 309 | + // | ||
| 310 | + // The latter was done to keep the single-link groups ('blue', rose, ...) close. | ||
| 311 | + return 30 + | ||
| 312 | + Math.min(20 * Math.min((n1.size || (n1.group != n2.group ? n1.group_data.size : 0)), | ||
| 313 | + (n2.size || (n1.group != n2.group ? n2.group_data.size : 0))), | ||
| 314 | + -30 + | ||
| 315 | + 30 * Math.min((n1.link_count || (n1.group != n2.group ? n1.group_data.link_count : 0)), | ||
| 316 | + (n2.link_count || (n1.group != n2.group ? n2.group_data.link_count : 0))), | ||
| 317 | + 100); | ||
| 318 | + //return 150; | ||
| 319 | + }) | ||
| 320 | + .linkStrength(function(l, i) { | ||
| 321 | + return 1; | ||
| 322 | + }) | ||
| 323 | + .gravity(0.05) // gravity+charge tweaked to ensure good 'grouped' view (e.g. green group not smack between blue&orange, ... | ||
| 324 | + .charge(-600) // ... charge is important to turn single-linked groups to the outside | ||
| 325 | + .friction(0.5) // friction adjusted to get dampened display: less bouncy bouncy ball [Swedish Chef, anyone?] | ||
| 326 | + .start(); | ||
| 327 | + | ||
| 328 | + hullg.selectAll("path.hull").remove(); | ||
| 329 | + hull = hullg.selectAll("path.hull") | ||
| 330 | + .data(this.convexHulls(net.nodes, this.getGroup, off)) | ||
| 331 | + .enter().append("path") | ||
| 332 | + .attr("class", "hull") | ||
| 333 | + .attr("d", this.drawCluster) | ||
| 334 | + .style("fill", function(d) { return fill(d.group); }) | ||
| 335 | + .on("click", function(d) { | ||
| 336 | + console.log("hull click", d, arguments, this, expand[d.group]); | ||
| 337 | + expand[d.group] = false; _this.init(); | ||
| 338 | + }); | ||
| 339 | + | ||
| 340 | + link = linkg.selectAll("line.link").data(net.links, this.linkid); | ||
| 341 | + link.exit().remove(); | ||
| 342 | + link.enter().append("line") | ||
| 343 | + .attr("class", "link") | ||
| 344 | + .attr("x1", function(d) { return d.source.x; }) | ||
| 345 | + .attr("y1", function(d) { return d.source.y; }) | ||
| 346 | + .attr("x2", function(d) { return d.target.x; }) | ||
| 347 | + .attr("y2", function(d) { return d.target.y; }) | ||
| 348 | + .attr("style", function(t){ return "stroke:" + t.color }) | ||
| 349 | + .style("stroke-width", function(d) { return d.size || 1; }); | ||
| 350 | + | ||
| 351 | + | ||
| 352 | + node = nodeg.selectAll("circle.node").data(net.nodes, this.nodeid); | ||
| 353 | + node.exit().remove(); | ||
| 354 | + node.enter().append("circle") | ||
| 355 | + // if (d.size) -- d.size > 0 when d is a group node. | ||
| 356 | + .attr("class", function(d) { return "node" + (d.size?"":" leaf"); }) | ||
| 357 | + .attr("r", function(d) { return d.size ? d.size + dr : dr+1; }) | ||
| 358 | + //.attr("r", function (t) { return t.r;}) | ||
| 359 | + .attr("cx", function(d) { return d.x; }) | ||
| 360 | + .attr("cy", function(d) { return d.y; }) | ||
| 361 | + .attr("id", function(d){ return d.id; }) | ||
| 362 | + //.attr("style", function (t) { return t.color ? "fill:" + t.color : !1 + "; stroke:white" }) | ||
| 363 | + .style("fill", function(d) { return fill(d.group); }) | ||
| 364 | + .on("mouseover", this.mouseover) | ||
| 365 | + .on("mouseout", this.mouseout) | ||
| 366 | + .on("click", this.active) | ||
| 367 | + .on("click", function(d) { | ||
| 368 | + //console.log("node click", d, arguments, this, expand[d.group]); | ||
| 369 | + expand[d.group] = !expand[d.group]; | ||
| 370 | + _this.init(); | ||
| 371 | + }); | ||
| 372 | + | ||
| 373 | + node.call(force.drag); | ||
| 374 | + | ||
| 375 | + force.on("tick", function() { | ||
| 376 | + if (!hull.empty()) { | ||
| 377 | + hull.data(_this.convexHulls(net.nodes, _this.getGroup, off)) | ||
| 378 | + .attr("d", _this.drawCluster); | ||
| 379 | + } | ||
| 380 | + | ||
| 381 | + link.attr("x1", function(d) { return d.source.x; }) | ||
| 382 | + .attr("y1", function(d) { return d.source.y; }) | ||
| 383 | + .attr("x2", function(d) { return d.target.x; }) | ||
| 384 | + .attr("y2", function(d) { return d.target.y; }); | ||
| 385 | + | ||
| 386 | + node.attr("cx", function(d) { return d.x; }) | ||
| 387 | + .attr("cy", function(d) { return d.y; }); | ||
| 388 | + }); | ||
| 389 | + }, | ||
| 390 | + | ||
| 391 | + buildGraph: function (){ | ||
| 392 | + | ||
| 393 | + this.svg = this.svg.append("g") | ||
| 394 | + .call(d3.behavior.zoom().scaleExtent([.25, 20]).on("zoom", this.zoom)) | ||
| 395 | + .append("g"); | ||
| 396 | + | ||
| 397 | + //set initial zoom | ||
| 398 | + scale = (1.0); | ||
| 399 | + //translate = [(width-scale*width)/2, ((height-scale*height)/4)]; | ||
| 400 | + translate = [0, 0]; | ||
| 401 | + this.svg.transition() | ||
| 402 | + .duration(750) | ||
| 403 | + .attr("transform", "translate(" + translate + ")scale(" + scale + ")") | ||
| 404 | + .each("end", function () { | ||
| 405 | + d3.behavior.zoom() | ||
| 406 | + .scale(scale) | ||
| 407 | + .translate(translate); | ||
| 408 | + }); | ||
| 409 | + //end set initial zoom | ||
| 410 | + | ||
| 411 | + this.svg.append("rect") | ||
| 412 | + .attr("fill", "white") | ||
| 413 | + .attr("width", this.width) | ||
| 414 | + .attr("height", this.height); | ||
| 415 | + | ||
| 416 | + //pezzotto | ||
| 417 | + this.svg.append("filter") | ||
| 418 | + .attr("id","filter1") | ||
| 419 | + .attr("x","0%") | ||
| 420 | + .attr("y","0%") | ||
| 421 | + .attr("width","100%") | ||
| 422 | + .attr("height","100%") | ||
| 423 | + .append("feImage") | ||
| 424 | + .attr("xlink:href","http://icons.iconarchive.com/icons/hopstarter/soft-scraps/256/User-Executive-Green-icon.png"); | ||
| 425 | + | ||
| 426 | + for (var i = 0; i < this.graph.links.length; ++i) { | ||
| 427 | + o = this.graph.links[i]; | ||
| 428 | + o.source = this.graph.nodes[o.source]; | ||
| 429 | + o.target = this.graph.nodes[o.target]; | ||
| 430 | + } | ||
| 431 | + | ||
| 432 | + hullg = this.svg.append("g"); | ||
| 433 | + linkg = this.svg.append("g"); | ||
| 434 | + nodeg = this.svg.append("g"); | ||
| 435 | + | ||
| 436 | + this.init(); | ||
| 437 | + | ||
| 438 | + this.svg.attr("opacity", 1e-6) | ||
| 439 | + .transition() | ||
| 440 | + .duration(1000) | ||
| 441 | + .attr("opacity", 1); | ||
| 442 | + }, | ||
| 443 | + | ||
| 444 | + zoom: function() { | ||
| 445 | + _this.svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); | ||
| 446 | + }, | ||
| 447 | + | ||
| 448 | + text: function (t){ | ||
| 449 | + var e = t.append("svg:foreignObject").attr("width", 120).attr("height", 30); | ||
| 450 | + e.attr("style", function (t) { | ||
| 451 | + return "color:" + (t.color ? t.color : "#000") | ||
| 452 | + }).append("xhtml:div").html(function (t) { | ||
| 453 | + //return t.fixed ? t.name : null | ||
| 454 | + return t.name; | ||
| 455 | + }) | ||
| 456 | + }, | ||
| 457 | + | ||
| 458 | + tick : function () { | ||
| 459 | + // d3.select("svg").attr("style", "transform:translate(8%)"); | ||
| 460 | + d3.selectAll("g foreignObject").attr("x", function (t) { | ||
| 461 | + return t.x + (t.r ? 0.8 * t.r : 15) | ||
| 462 | + }).attr("y", function (t) { | ||
| 463 | + return t.y - 20 | ||
| 464 | + }); | ||
| 465 | + | ||
| 466 | + d3.selectAll("#logo text").attr("x", function (t) { | ||
| 467 | + return t.x + .7 * (t.r ? t.r : 15) | ||
| 468 | + }).attr("y", function (t) { | ||
| 469 | + return t.y | ||
| 470 | + }); | ||
| 471 | + | ||
| 472 | + | ||
| 473 | + _this.gnodes.attr("cx", function (t) { | ||
| 474 | + return t.x = Math.max(25, Math.min(_this.width - 50, t.x)) | ||
| 475 | + }).attr("cy", function (t) { | ||
| 476 | + return t.y = Math.max(8, Math.min(600, t.y)) | ||
| 477 | + }); | ||
| 478 | + | ||
| 479 | + _this.glinks.attr("x1", function (t) { | ||
| 480 | + return t.source.x | ||
| 481 | + }).attr("y1", function (t) { | ||
| 482 | + return t.source.y | ||
| 483 | + }).attr("x2", function (t) { | ||
| 484 | + return t.target.x | ||
| 485 | + }).attr("y2", function (t) { | ||
| 486 | + return t.target.y | ||
| 487 | + }) | ||
| 488 | + }, | ||
| 489 | + | ||
| 490 | + mouseover : function (t) { | ||
| 491 | + d3.select(this).selectAll("circle").transition().duration(600).ease("elastic").attr("r", function (t) { | ||
| 492 | + //return 1 == t.fixed ? 1.4 * t.r : 15 | ||
| 493 | + return 1 == t.fixed ? 1.4 * t.r : t.r + 10; | ||
| 494 | + }); | ||
| 495 | + | ||
| 496 | + _this.$.dialog.close(); | ||
| 497 | + _this.$.dialog_title.innerHTML = t.name; | ||
| 498 | + _this.$.dialog_content.innerHTML = t.content; | ||
| 499 | + | ||
| 500 | + _this.$.dialog.open(); | ||
| 501 | + }, | ||
| 502 | + | ||
| 503 | + mouseout : function () { | ||
| 504 | + d3.select(this).selectAll("text").style("visibility", "hidden"), d3.select(this).selectAll("circle").transition().duration(400).attr("r", function (t) { | ||
| 505 | + return t.r ? t.r : 15 | ||
| 506 | + }); | ||
| 507 | + _this.$.dialog.close(); | ||
| 508 | + }, | ||
| 509 | + | ||
| 510 | + active : function (t) { | ||
| 511 | + _this.fire('graph-datalet_node-clicked', {node : t}); | ||
| 512 | + | ||
| 513 | + if(_this.prev_selected_node != null){ | ||
| 514 | + _this.prev_selected_node.style.fill = _this.prev_selected_node.style.stroke; | ||
| 515 | + _this.prev_selected_node.style.stroke = "#FFFFFF"; | ||
| 516 | + } | ||
| 517 | + | ||
| 518 | + _this.prev_selected_node = document.getElementById("" + t.id); | ||
| 519 | + _this.prev_selected_node.style.fill = "#FFFFFF" | ||
| 520 | + _this.prev_selected_node.style.stroke = t.color; | ||
| 521 | + | ||
| 522 | + /* _this.$.dialog.close(); | ||
| 523 | + _this.$.dialog_title.innerHTML = t.name; | ||
| 524 | + _this.$.dialog_content.innerHTML = t.content; | ||
| 525 | + | ||
| 526 | + _this.$.dialog.open();*/ | ||
| 527 | + }, | ||
| 528 | + | ||
| 529 | + _onCloseClick : function(){ | ||
| 530 | + //_this.$.dialog.close(); | ||
| 531 | + }, | ||
| 532 | + | ||
| 533 | + /** | ||
| 534 | + * It is called after the element’s template has been stamped and all elements inside the element’s local | ||
| 535 | + * DOM have been configured (with values bound from parents, deserialized attributes, or else default values) | ||
| 536 | + * and had their ready method called. | ||
| 537 | + * | ||
| 538 | + * Extract the dataset domain from the entire URL and set the text content of the datalet footer. | ||
| 539 | + * | ||
| 540 | + * @method ready | ||
| 541 | + * | ||
| 542 | + */ | ||
| 543 | + ready: function(){ | ||
| 544 | + | ||
| 545 | + _this = this; | ||
| 546 | + | ||
| 547 | + this.svg = d3.select("svg#sbiricuda").attr("class", "svg").attr({ | ||
| 548 | + width: "100%", | ||
| 549 | + height: "100%" | ||
| 550 | + }).attr("viewBox", "0 0 " + this.width + " " + this.height) | ||
| 551 | + .attr("pointer-events", "all") | ||
| 552 | + .attr("style", "transform:translate(0px)") | ||
| 553 | + .style("position", "absolute"); | ||
| 554 | + | ||
| 555 | + var groups = []; | ||
| 556 | + for(var i= 0,j=0; i < this.graph.nodes.length;i++,j+=3){ | ||
| 557 | + groups.push([{key : "" + j, values : []}, {key : "" + (j + 1), values : []}, {key : "" + (j + 2), values : []}]); | ||
| 558 | + if(this.graph.nodes[i].father != null){ | ||
| 559 | + switch (parseInt(this.graph.nodes[i].sentiment)){ | ||
| 560 | + case 1: | ||
| 561 | + groups[this.graph.nodes[i].father.id][0].values.push(this.graph.nodes[i]); | ||
| 562 | + break; | ||
| 563 | + case 2: | ||
| 564 | + groups[this.graph.nodes[i].father.id][1].values.push(this.graph.nodes[i]); | ||
| 565 | + break; | ||
| 566 | + case 3: | ||
| 567 | + groups[this.graph.nodes[i].father.id][2].values.push(this.graph.nodes[i]); | ||
| 568 | + break; | ||
| 569 | + } | ||
| 570 | + } | ||
| 571 | + } | ||
| 572 | + | ||
| 573 | + var index = 0; | ||
| 574 | + for(var i=0; i < groups.length; i++){ | ||
| 575 | + for(var j=0; j < groups[i].length;j++){ | ||
| 576 | + for(var k=0; k < groups[i][j].values.length;k++) | ||
| 577 | + this.graph.nodes[groups[i][j].values[k].id].group = i; | ||
| 578 | + } | ||
| 579 | + } | ||
| 580 | + | ||
| 581 | + this.buildGraph(); | ||
| 582 | + } | ||
| 583 | + }); | ||
| 584 | + </script> | ||
| 585 | +</dom-module> | ||
| 0 | \ No newline at end of file | 586 | \ No newline at end of file |
datalets/graph-datalet/graph-datalet.html
| @@ -74,6 +74,9 @@ Example: | @@ -74,6 +74,9 @@ Example: | ||
| 74 | --paper-fab-background:#9e9e9e; | 74 | --paper-fab-background:#9e9e9e; |
| 75 | z-index: 1001; | 75 | z-index: 1001; |
| 76 | } | 76 | } |
| 77 | + #dialog_content{ | ||
| 78 | + padding : 10px; | ||
| 79 | + } | ||
| 77 | 80 | ||
| 78 | </style> | 81 | </style> |
| 79 | 82 | ||
| @@ -84,7 +87,7 @@ Example: | @@ -84,7 +87,7 @@ Example: | ||
| 84 | <paper-dialog id="dialog"> | 87 | <paper-dialog id="dialog"> |
| 85 | <paper-fab id="close" mini icon="close" on-click="_onCloseClick"></paper-fab> | 88 | <paper-fab id="close" mini icon="close" on-click="_onCloseClick"></paper-fab> |
| 86 | <h2 id="dialog_title"></h2> | 89 | <h2 id="dialog_title"></h2> |
| 87 | - <paper-dialog-scrollable id="dialog_content">cos</paper-dialog-scrollable> | 90 | + <div id="dialog_content">cos</div> |
| 88 | </paper-dialog> | 91 | </paper-dialog> |
| 89 | 92 | ||
| 90 | </template> | 93 | </template> |
| @@ -203,6 +206,8 @@ Example: | @@ -203,6 +206,8 @@ Example: | ||
| 203 | 206 | ||
| 204 | this.svg.selectAll(".link").attr("style", function(t){ | 207 | this.svg.selectAll(".link").attr("style", function(t){ |
| 205 | return "stroke:" + t.color | 208 | return "stroke:" + t.color |
| 209 | + }).attr("style", function(t){ | ||
| 210 | + return "stroke-width:" + (t.size ? t.size : 1.0) + "px"; | ||
| 206 | }); | 211 | }); |
| 207 | 212 | ||
| 208 | gnodes = this.svg.selectAll(".node").data(graph.nodes).enter().append("g").attr("class", function (t) { | 213 | gnodes = this.svg.selectAll(".node").data(graph.nodes).enter().append("g").attr("class", function (t) { |
| @@ -225,7 +230,10 @@ Example: | @@ -225,7 +230,10 @@ Example: | ||
| 225 | return t.color ? "fill:" + t.color : !1 + "; stroke:white" | 230 | return t.color ? "fill:" + t.color : !1 + "; stroke:white" |
| 226 | }); | 231 | }); |
| 227 | 232 | ||
| 228 | - d3.selectAll('circle').attr("filter", function(t){return t.image ? 'url(#filter1)' : ""}); | 233 | + d3.selectAll('circle').attr("filter", function(t){return t.image ? 'url(#filter1)' : ""}) |
| 234 | + .selectAll('feImage') | ||
| 235 | + .attr("xlink:href", function(t){ | ||
| 236 | + return t.image ? t.image : "http://icons.iconarchive.com/icons/hopstarter/soft-scraps/256/User-Executive-Green-icon.png"}); | ||
| 229 | 237 | ||
| 230 | //d3.selectAll(".drag").call(force.drag), svg.selectAll("g.fixed").call(text); | 238 | //d3.selectAll(".drag").call(force.drag), svg.selectAll("g.fixed").call(text); |
| 231 | d3.selectAll(".drag").call(force.drag), this.svg.selectAll("g.node").call(this.text); | 239 | d3.selectAll(".drag").call(force.drag), this.svg.selectAll("g.node").call(this.text); |
| @@ -355,6 +363,7 @@ Example: | @@ -355,6 +363,7 @@ Example: | ||
| 355 | g.nodes[0].y = this.height / 2; | 363 | g.nodes[0].y = this.height / 2; |
| 356 | this.buildGraph(g);*/ | 364 | this.buildGraph(g);*/ |
| 357 | 365 | ||
| 366 | + var json = JSON.stringify(this.data); | ||
| 358 | var g = this.data; | 367 | var g = this.data; |
| 359 | g.nodes[0].x = this.width / 2; | 368 | g.nodes[0].x = this.width / 2; |
| 360 | g.nodes[0].y = this.height / 8; | 369 | g.nodes[0].y = this.height / 8; |
datalets/graph-datalet/graph-with-clustering-datalet.html
0 → 100644
| 1 | +<!-- | ||
| 2 | +@license | ||
| 3 | + The MIT License (MIT) | ||
| 4 | + | ||
| 5 | + Copyright (c) 2015 Dipartimento di Informatica - Università di Salerno - Italy | ||
| 6 | + | ||
| 7 | + Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 8 | + of this software and associated documentation files (the "Software"), to deal | ||
| 9 | + in the Software without restriction, including without limitation the rights | ||
| 10 | + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 11 | + copies of the Software, and to permit persons to whom the Software is | ||
| 12 | + furnished to do so, subject to the following conditions: | ||
| 13 | + | ||
| 14 | + The above copyright notice and this permission notice shall be included in | ||
| 15 | + all copies or substantial portions of the Software. | ||
| 16 | + | ||
| 17 | + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 18 | + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 19 | + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 20 | + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 21 | + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 22 | + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| 23 | + THE SOFTWARE. | ||
| 24 | +--> | ||
| 25 | + | ||
| 26 | +<!-- | ||
| 27 | +* Developed by : | ||
| 28 | +* ROUTE-TO-PA Project - grant No 645860. - www.routetopa.eu | ||
| 29 | +* | ||
| 30 | +--> | ||
| 31 | + | ||
| 32 | +<link rel="import" href="../base-datalet/base-datalet.html"> | ||
| 33 | +<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout.html"> | ||
| 34 | +<link rel="import" href="../../bower_components/paper-dialog/paper-dialog.html"> | ||
| 35 | +<link rel="import" href="../../bower_components/paper-fab/paper-fab.html"> | ||
| 36 | + | ||
| 37 | +<!-- | ||
| 38 | +`preview-datalet` is a datalet that allow user to preview the content of a web page. It creates a thumbnail of the site using the data-url attribute passed as input. | ||
| 39 | + | ||
| 40 | +Example: | ||
| 41 | + | ||
| 42 | + <preview-datalet data-url="http://spod.routetopa.eu" | ||
| 43 | + </preview-datalet> | ||
| 44 | + | ||
| 45 | + | ||
| 46 | +@element preview-datalet | ||
| 47 | +@status beta | ||
| 48 | +@homepage | ||
| 49 | +@group datalets | ||
| 50 | +--> | ||
| 51 | + | ||
| 52 | +<dom-module id="graph-with-clustering-datalet"> | ||
| 53 | + <template> | ||
| 54 | + | ||
| 55 | + <link rel="stylesheet" href="static/css/graphStyle.css"> | ||
| 56 | + | ||
| 57 | + <style is="custom-style"> | ||
| 58 | + | ||
| 59 | + #dialog{ | ||
| 60 | + position: absolute; | ||
| 61 | + padding: 20px; | ||
| 62 | + top: 20px; | ||
| 63 | + right:5%; | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + #close{ | ||
| 67 | + position: absolute; | ||
| 68 | + top: -20px; | ||
| 69 | + right: 3px; | ||
| 70 | + --iron-icon-height: 20px; | ||
| 71 | + --iron-icon-width: 20px; | ||
| 72 | + width: 24px; | ||
| 73 | + height: 24px; | ||
| 74 | + --paper-fab-background:#9e9e9e; | ||
| 75 | + z-index: 1001; | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + </style> | ||
| 79 | + | ||
| 80 | + <div style="align-content: center;overflow: visible" id="graph_content"> | ||
| 81 | + <svg id="sbiricuda"></svg> | ||
| 82 | + </div> | ||
| 83 | + | ||
| 84 | + <paper-dialog id="dialog"> | ||
| 85 | + <paper-fab id="close" mini icon="close" on-click="_onCloseClick"></paper-fab> | ||
| 86 | + <h2 id="dialog_title"></h2> | ||
| 87 | + <paper-dialog-scrollable id="dialog_content">cos</paper-dialog-scrollable> | ||
| 88 | + </paper-dialog> | ||
| 89 | + | ||
| 90 | + </template> | ||
| 91 | + | ||
| 92 | + <script src="static/js/d3.v3.js"></script> | ||
| 93 | + | ||
| 94 | + <script> | ||
| 95 | + _this = null; | ||
| 96 | + | ||
| 97 | + Polymer({ | ||
| 98 | + is : 'graph-with-clustering-datalet', | ||
| 99 | + | ||
| 100 | + properties: { | ||
| 101 | + /** | ||
| 102 | + * It's the url for the preview | ||
| 103 | + * | ||
| 104 | + * @attribute url | ||
| 105 | + * @type Strig | ||
| 106 | + * @default '' | ||
| 107 | + */ | ||
| 108 | + graph : { | ||
| 109 | + type : Object, | ||
| 110 | + value : undefined | ||
| 111 | + }, | ||
| 112 | + | ||
| 113 | + svgNodes : { | ||
| 114 | + type : Array, | ||
| 115 | + value : [] | ||
| 116 | + }, | ||
| 117 | + | ||
| 118 | + svgLinks : { | ||
| 119 | + type : Array, | ||
| 120 | + value : [] | ||
| 121 | + }, | ||
| 122 | + | ||
| 123 | + width: { | ||
| 124 | + type: Number, | ||
| 125 | + value: undefined | ||
| 126 | + }, | ||
| 127 | + | ||
| 128 | + height : { | ||
| 129 | + type : Number, | ||
| 130 | + value: undefined | ||
| 131 | + }, | ||
| 132 | + | ||
| 133 | + svg: { | ||
| 134 | + type: Object, | ||
| 135 | + value: undefined | ||
| 136 | + }, | ||
| 137 | + feelings:{ | ||
| 138 | + type: Array, | ||
| 139 | + values: ["Agree", "Neutral", "Not agree"] | ||
| 140 | + }, | ||
| 141 | + prev_selected_node : { | ||
| 142 | + type : Object, | ||
| 143 | + value : null | ||
| 144 | + }, | ||
| 145 | + | ||
| 146 | + force : { | ||
| 147 | + type : Object, | ||
| 148 | + value : null | ||
| 149 | + }, | ||
| 150 | + | ||
| 151 | + edgesMap : { | ||
| 152 | + type : Array, | ||
| 153 | + value : [] | ||
| 154 | + }, | ||
| 155 | + | ||
| 156 | + groups: { | ||
| 157 | + type: Array, | ||
| 158 | + value: [] | ||
| 159 | + }, | ||
| 160 | + | ||
| 161 | + hull : { | ||
| 162 | + type : Array, | ||
| 163 | + value : [] | ||
| 164 | + }, | ||
| 165 | + /*test*/ | ||
| 166 | + hullg : { | ||
| 167 | + type : Array, | ||
| 168 | + value : [] | ||
| 169 | + }, | ||
| 170 | + | ||
| 171 | + offset :{ | ||
| 172 | + type : Number, | ||
| 173 | + value : 15 | ||
| 174 | + } | ||
| 175 | + | ||
| 176 | + /*end test*/ | ||
| 177 | + }, | ||
| 178 | + | ||
| 179 | + convexHulls : function() { | ||
| 180 | + var hullset = []; | ||
| 181 | + for(var i in _this.groups){ | ||
| 182 | + for(var j=0; j < _this.groups[i].length;j++){ | ||
| 183 | + var vertices = []; | ||
| 184 | + for(var v=0;v < _this.groups[i][j].values.length; v++){ | ||
| 185 | + vertices.push([_this.groups[i][j].values[v].x - _this.offset, _this.groups[i][j].values[v].y - _this.offset]); | ||
| 186 | + vertices.push([_this.groups[i][j].values[v].x - _this.offset, _this.groups[i][j].values[v].y + _this.offset]); | ||
| 187 | + vertices.push([_this.groups[i][j].values[v].x + _this.offset, _this.groups[i][j].values[v].y - _this.offset]); | ||
| 188 | + vertices.push([_this.groups[i][j].values[v].x + _this.offset, _this.groups[i][j].values[v].y + _this.offset]); | ||
| 189 | + } | ||
| 190 | + | ||
| 191 | + hullset.push({id : parseInt(i) + 3, sentiment: j , path: d3.geom.hull(vertices), extend : _this.groups[i][j].extend}); | ||
| 192 | + } | ||
| 193 | + } | ||
| 194 | + | ||
| 195 | + return hullset; | ||
| 196 | + }, | ||
| 197 | + | ||
| 198 | + fill : function(d){ | ||
| 199 | + /*var fill = d3.scale.category20(); | ||
| 200 | + return fill(d);*/ | ||
| 201 | + switch((d % 3)){ | ||
| 202 | + case 0 : | ||
| 203 | + return "#1F77B4"; | ||
| 204 | + case 1 : | ||
| 205 | + return "#2CA02C"; | ||
| 206 | + case 2: | ||
| 207 | + return "#FF1E1E"; | ||
| 208 | + } | ||
| 209 | + }, | ||
| 210 | + | ||
| 211 | + drawCluster : function(d) { | ||
| 212 | + var curve = d3.svg.line() | ||
| 213 | + .interpolate("cardinal-closed") | ||
| 214 | + .tension(.85); | ||
| 215 | + | ||
| 216 | + return curve(d.path); // 0.8 | ||
| 217 | + }, | ||
| 218 | + | ||
| 219 | + getNetwork : function(){ | ||
| 220 | + | ||
| 221 | + var nodes = [], links = []; | ||
| 222 | + this.groups = []; | ||
| 223 | + | ||
| 224 | + for(var i= 0,j=0; i < this.graph.nodes.length;i++,j+=3){ | ||
| 225 | + | ||
| 226 | + var f = this.graph.nodes[i].father; | ||
| 227 | + if(f != null) { | ||
| 228 | + while (f.sentiment == this.graph.nodes[i].sentiment) f = f.father; | ||
| 229 | + } | ||
| 230 | + | ||
| 231 | + if(f != null){ | ||
| 232 | + if(this.groups[f.id] == undefined){ | ||
| 233 | + this.groups[f.id] = ([ | ||
| 234 | + {key: "" + j, values: [], extend: true}, | ||
| 235 | + {key: "" + (j + 1), values: [],extend: true}, | ||
| 236 | + {key: "" + (j + 2), values: [], extend: true} | ||
| 237 | + ]); | ||
| 238 | + } | ||
| 239 | + | ||
| 240 | + this.graph.nodes[i].group = f.id; | ||
| 241 | + | ||
| 242 | + switch (parseInt(this.graph.nodes[i].sentiment)){ | ||
| 243 | + case 1: | ||
| 244 | + if(this.groups[f.id][0].extend) { | ||
| 245 | + this.groups[f.id][0].values.push(this.graph.nodes[i]); | ||
| 246 | + } | ||
| 247 | + break; | ||
| 248 | + case 2: | ||
| 249 | + if(this.groups[f.id][1].extend) | ||
| 250 | + this.groups[f.id][1].values.push(this.graph.nodes[i]); | ||
| 251 | + break; | ||
| 252 | + case 3: | ||
| 253 | + if(this.groups[f.id][2].extend) | ||
| 254 | + this.groups[f.id][2].values.push(this.graph.nodes[i]); | ||
| 255 | + break; | ||
| 256 | + } | ||
| 257 | + }else{ | ||
| 258 | + this.graph.nodes[i].group = 0; | ||
| 259 | + } | ||
| 260 | + } | ||
| 261 | + | ||
| 262 | + var nodesMap = []; | ||
| 263 | + | ||
| 264 | + for(var g in this.groups){ | ||
| 265 | + for(var s in this.groups[g]) { | ||
| 266 | + if(this.groups[g][s].values.length > 0) { | ||
| 267 | + var node = ({ | ||
| 268 | + group: g, | ||
| 269 | + sentiment: parseInt(s) + 1, | ||
| 270 | + nodes: this.groups[g][s].values, | ||
| 271 | + r: this.groups[g][s].values.length * 6, | ||
| 272 | + extend: false | ||
| 273 | + }); | ||
| 274 | + | ||
| 275 | + node.id = nodes.length; | ||
| 276 | + nodes.push(node); | ||
| 277 | + | ||
| 278 | + for(var n=0; n < this.groups[g][s].values.length;n++) | ||
| 279 | + nodesMap[this.groups[g][s].values[n].id] = node; | ||
| 280 | + | ||
| 281 | + } | ||
| 282 | + } | ||
| 283 | + } | ||
| 284 | + | ||
| 285 | + for(var e = 0; e < this.graph.links.length; e++){ | ||
| 286 | + if(this.graph.nodes[this.graph.links[e].source.id].group != this.graph.nodes[this.graph.links[e].target.id].group) { | ||
| 287 | + links.push({ | ||
| 288 | + //id: nodesMap[this.graph.nodes[this.graph.links[e].source.id].group].id + "-" + nodesMap[this.graph.nodes[this.graph.links[e].target.id].group].id, | ||
| 289 | + source: nodesMap[this.graph.links[e].source.id], | ||
| 290 | + target: nodesMap[this.graph.links[e].target.id], | ||
| 291 | + value: 100 | ||
| 292 | + }); | ||
| 293 | + } | ||
| 294 | + | ||
| 295 | + } | ||
| 296 | + | ||
| 297 | + //return {nodes : nodes, links : links}; | ||
| 298 | + return {nodes : this.graph.nodes, links : this.graph.links}; | ||
| 299 | + | ||
| 300 | + }, | ||
| 301 | + | ||
| 302 | + init : function(){ | ||
| 303 | + | ||
| 304 | + var net = this.getNetwork(); | ||
| 305 | + | ||
| 306 | + if(this.force != null) this.force.stop(); | ||
| 307 | + force = d3.layout.force() | ||
| 308 | + .nodes(net.nodes) | ||
| 309 | + .links(net.links) | ||
| 310 | + .size([this.width, this.height]) | ||
| 311 | + .charge(-1e3) | ||
| 312 | + .friction(.7) | ||
| 313 | + .linkDistance(function (t){ return t.value ? t.value : 80}) | ||
| 314 | + .on("tick", this.tick).start(); | ||
| 315 | + | ||
| 316 | + this.hullg.selectAll("path.hull").remove(); | ||
| 317 | + this.hull = this.hullg.selectAll("path.hull") | ||
| 318 | + .data(this.convexHulls) | ||
| 319 | + .enter().append("path") | ||
| 320 | + .attr("class", "hull") | ||
| 321 | + .attr("d", this.drawCluster) | ||
| 322 | + .style("fill", "#60df20") | ||
| 323 | + .style("opacity", .2) | ||
| 324 | + .on("click", function(d) { | ||
| 325 | + alert(d.id); | ||
| 326 | + }); | ||
| 327 | + | ||
| 328 | + | ||
| 329 | + this.svg.selectAll(".link").data(net.links).remove(); | ||
| 330 | + this.svgLinks = this.svg.selectAll(".link").data(net.links).enter() | ||
| 331 | + .append("line") | ||
| 332 | + .attr("class", "link") | ||
| 333 | + .attr("style", function(t){ return "stroke:#333"; /*+ t.color*/ }) | ||
| 334 | + .style("stroke-width", function(d) { return d.size || 0.3; }); | ||
| 335 | + | ||
| 336 | + this.svg.selectAll(".node").data(net.nodes).remove(); | ||
| 337 | + this.svgNodes = this.svg.selectAll(".node").data(net.nodes).enter() | ||
| 338 | + .append("g") | ||
| 339 | + .on("mouseover", this.mouseover) | ||
| 340 | + .on("mouseout", this.mouseout) | ||
| 341 | + .attr("class", function (t) { return t.fixed ? "node fixed" : "node"}) | ||
| 342 | + .attr("name", function (t) { return t.name ? t.name.split(" ").join("_").toLowerCase() : ""}) | ||
| 343 | + .append("circle") | ||
| 344 | + .on("click", this.active) | ||
| 345 | + .attr("id", function(t){ return t.id }) | ||
| 346 | + .attr("class", function (t) { return t.fixed ? "" : "drag"}) | ||
| 347 | + .attr("r", function (t){ return t.r ? t.r : 15 }) | ||
| 348 | + .attr("style", function (t) { | ||
| 349 | + switch(parseInt(t.sentiment)){ | ||
| 350 | + case 1 : | ||
| 351 | + t.color = "#1F77B4"; | ||
| 352 | + break; | ||
| 353 | + case 2 : | ||
| 354 | + t.color = "#2CA02C"; | ||
| 355 | + break; | ||
| 356 | + case 3: | ||
| 357 | + t.color = "#D62728"; | ||
| 358 | + break; | ||
| 359 | + default: | ||
| 360 | + t.color = "#333"; | ||
| 361 | + } | ||
| 362 | + //return t.color ? "fill:" + t.color : !1 + "; stroke:white" | ||
| 363 | + return "fill:" + t.color + "; stroke:white" | ||
| 364 | + }) | ||
| 365 | + .attr("filter", function(t){return t.image ? 'url(#filter1)' : ""}); | ||
| 366 | + | ||
| 367 | + this.svg.style("opacity", 1e-6) | ||
| 368 | + .transition() | ||
| 369 | + .duration(1000) | ||
| 370 | + .style("opacity", 1); | ||
| 371 | + | ||
| 372 | + d3.selectAll(".drag").call(force.drag), this.svg.selectAll("g.node").call(this.text); | ||
| 373 | + }, | ||
| 374 | + | ||
| 375 | + buildGraph: function (){ | ||
| 376 | + | ||
| 377 | + this.svg = this.svg.append("g") | ||
| 378 | + .call(d3.behavior.zoom().scaleExtent([.25, 20]).on("zoom", this.zoom)) | ||
| 379 | + .append("g"); | ||
| 380 | + | ||
| 381 | + //set initial zoom | ||
| 382 | + scale = (1.0); | ||
| 383 | + translate = [0, 0]; | ||
| 384 | + this.svg.transition() | ||
| 385 | + .duration(750) | ||
| 386 | + .attr("transform", "translate(" + translate + ")scale(" + scale + ")") | ||
| 387 | + .each("end", function () { | ||
| 388 | + d3.behavior.zoom() | ||
| 389 | + .scale(scale) | ||
| 390 | + .translate(translate); | ||
| 391 | + }); | ||
| 392 | + //end set initial zoom | ||
| 393 | + | ||
| 394 | + this.svg.append("rect") | ||
| 395 | + .attr("fill", "white") | ||
| 396 | + .attr("width", this.width) | ||
| 397 | + .attr("height", this.height); | ||
| 398 | + | ||
| 399 | + //pezzotto | ||
| 400 | + this.svg.append("filter") | ||
| 401 | + .attr("id","filter1") | ||
| 402 | + .attr("x","0%") | ||
| 403 | + .attr("y","0%") | ||
| 404 | + .attr("width","100%") | ||
| 405 | + .attr("height","100%") | ||
| 406 | + .append("feImage") | ||
| 407 | + .attr("xlink:href","http://icons.iconarchive.com/icons/hopstarter/soft-scraps/256/User-Executive-Green-icon.png"); | ||
| 408 | + | ||
| 409 | + for (var i = 0; i < this.graph.links.length; ++i) { | ||
| 410 | + o = this.graph.links[i]; | ||
| 411 | + o.source = this.graph.nodes[o.source]; | ||
| 412 | + o.target = this.graph.nodes[o.target]; | ||
| 413 | + } | ||
| 414 | + | ||
| 415 | + this.hullg = this.svg.append("g"); | ||
| 416 | + | ||
| 417 | + this.init(); | ||
| 418 | + }, | ||
| 419 | + | ||
| 420 | + zoom: function() { | ||
| 421 | + _this.svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); | ||
| 422 | + }, | ||
| 423 | + | ||
| 424 | + text: function (t){ | ||
| 425 | + var e = t.append("svg:foreignObject").attr("width", 120).attr("height", 30); | ||
| 426 | + e.attr("style", function (t) { | ||
| 427 | + return "color:" + (t.color ? t.color : "#000") | ||
| 428 | + }).append("xhtml:div").html(function (t) { | ||
| 429 | + //return t.fixed ? t.name : null | ||
| 430 | + return t.name; | ||
| 431 | + }) | ||
| 432 | + }, | ||
| 433 | + | ||
| 434 | + tick : function () { | ||
| 435 | + | ||
| 436 | + if (!_this.hull.empty()) { | ||
| 437 | + _this.hull.data(_this.convexHulls) | ||
| 438 | + .style("fill", function(d) { | ||
| 439 | + return _this.fill(d.sentiment); | ||
| 440 | + }) | ||
| 441 | + .attr("d", _this.drawCluster); | ||
| 442 | + } | ||
| 443 | + | ||
| 444 | + d3.selectAll("g foreignObject").attr("x", function (t) { | ||
| 445 | + return t.x + (t.r ? 0.8 * t.r : 15) | ||
| 446 | + }).attr("y", function (t) { | ||
| 447 | + return t.y - 20 | ||
| 448 | + }); | ||
| 449 | + | ||
| 450 | + d3.selectAll("#logo text").attr("x", function (t) { | ||
| 451 | + return t.x + .7 * (t.r ? t.r : 15) | ||
| 452 | + }).attr("y", function (t) { | ||
| 453 | + return t.y | ||
| 454 | + }); | ||
| 455 | + | ||
| 456 | + _this.svgNodes.attr("cx", function (t) { | ||
| 457 | + return t.x = Math.max(25, Math.min(_this.width - 50, t.x)) | ||
| 458 | + }).attr("cy", function (t) { | ||
| 459 | + return t.y = Math.max(8, Math.min(600, t.y)) | ||
| 460 | + }); | ||
| 461 | + | ||
| 462 | + _this.svgLinks.attr("x1", function (t) { | ||
| 463 | + return t.source.x | ||
| 464 | + }).attr("y1", function (t) { | ||
| 465 | + return t.source.y | ||
| 466 | + }).attr("x2", function (t) { | ||
| 467 | + return t.target.x | ||
| 468 | + }).attr("y2", function (t) { | ||
| 469 | + return t.target.y | ||
| 470 | + }); | ||
| 471 | + | ||
| 472 | + }, | ||
| 473 | + | ||
| 474 | + mouseover : function (t) { | ||
| 475 | + d3.select(this).selectAll("circle").transition().duration(600).ease("elastic").attr("r", function (t) { | ||
| 476 | + return 1 == t.fixed ? 1.4 * t.r : t.r + 10; | ||
| 477 | + }); | ||
| 478 | + | ||
| 479 | + _this.$.dialog.close(); | ||
| 480 | + _this.$.dialog_title.innerHTML = t.name; | ||
| 481 | + _this.$.dialog_content.innerHTML = t.content; | ||
| 482 | + | ||
| 483 | + _this.$.dialog.open(); | ||
| 484 | + }, | ||
| 485 | + | ||
| 486 | + mouseout : function () { | ||
| 487 | + d3.select(this).selectAll("text").style("visibility", "hidden"), d3.select(this).selectAll("circle").transition().duration(400).attr("r", function (t) { | ||
| 488 | + return t.r ? t.r : 15 | ||
| 489 | + }); | ||
| 490 | + _this.$.dialog.close(); | ||
| 491 | + }, | ||
| 492 | + | ||
| 493 | + active : function (t) { | ||
| 494 | + | ||
| 495 | + _this.init(); | ||
| 496 | + _this.fire('graph-datalet_node-clicked', {node : t}); | ||
| 497 | + | ||
| 498 | + if(_this.prev_selected_node != null){ | ||
| 499 | + _this.prev_selected_node.style.fill = _this.prev_selected_node.style.stroke; | ||
| 500 | + _this.prev_selected_node.style.stroke = "#FFFFFF"; | ||
| 501 | + } | ||
| 502 | + | ||
| 503 | + _this.prev_selected_node = document.getElementById("" + t.id); | ||
| 504 | + _this.prev_selected_node.style.fill = "#FFFFFF" | ||
| 505 | + _this.prev_selected_node.style.stroke = t.color; | ||
| 506 | + | ||
| 507 | + /* _this.$.dialog.close(); | ||
| 508 | + _this.$.dialog_title.innerHTML = t.name; | ||
| 509 | + _this.$.dialog_content.innerHTML = t.content; | ||
| 510 | + | ||
| 511 | + _this.$.dialog.open();*/ | ||
| 512 | + }, | ||
| 513 | + | ||
| 514 | + _onCloseClick : function(){ | ||
| 515 | + //_this.$.dialog.close(); | ||
| 516 | + }, | ||
| 517 | + | ||
| 518 | + /** | ||
| 519 | + * It is called after the element’s template has been stamped and all elements inside the element’s local | ||
| 520 | + * DOM have been configured (with values bound from parents, deserialized attributes, or else default values) | ||
| 521 | + * and had their ready method called. | ||
| 522 | + * | ||
| 523 | + * Extract the dataset domain from the entire URL and set the text content of the datalet footer. | ||
| 524 | + * | ||
| 525 | + * @method ready | ||
| 526 | + * | ||
| 527 | + */ | ||
| 528 | + ready: function(){ | ||
| 529 | + | ||
| 530 | + _this = this; | ||
| 531 | + | ||
| 532 | + this.svg = d3.select("svg#sbiricuda").attr("class", "svg").attr({ | ||
| 533 | + width: "100%", | ||
| 534 | + height: "100%" | ||
| 535 | + }).attr("viewBox", "0 0 " + this.width + " " + this.height) | ||
| 536 | + .attr("pointer-events", "all") | ||
| 537 | + .attr("style", "transform:translate(0px)") | ||
| 538 | + .style("position", "absolute"); | ||
| 539 | + | ||
| 540 | + this.buildGraph(); | ||
| 541 | + } | ||
| 542 | + }); | ||
| 543 | + </script> | ||
| 544 | +</dom-module> | ||
| 0 | \ No newline at end of file | 545 | \ No newline at end of file |
datalets/graph-datalet/graph-with-clustering-datalet_.html
0 → 100644
| 1 | +<!-- | ||
| 2 | +@license | ||
| 3 | + The MIT License (MIT) | ||
| 4 | + | ||
| 5 | + Copyright (c) 2015 Dipartimento di Informatica - Università di Salerno - Italy | ||
| 6 | + | ||
| 7 | + Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 8 | + of this software and associated documentation files (the "Software"), to deal | ||
| 9 | + in the Software without restriction, including without limitation the rights | ||
| 10 | + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 11 | + copies of the Software, and to permit persons to whom the Software is | ||
| 12 | + furnished to do so, subject to the following conditions: | ||
| 13 | + | ||
| 14 | + The above copyright notice and this permission notice shall be included in | ||
| 15 | + all copies or substantial portions of the Software. | ||
| 16 | + | ||
| 17 | + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 18 | + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 19 | + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 20 | + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 21 | + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 22 | + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| 23 | + THE SOFTWARE. | ||
| 24 | +--> | ||
| 25 | + | ||
| 26 | +<!-- | ||
| 27 | +* Developed by : | ||
| 28 | +* ROUTE-TO-PA Project - grant No 645860. - www.routetopa.eu | ||
| 29 | +* | ||
| 30 | +--> | ||
| 31 | + | ||
| 32 | +<link rel="import" href="../base-datalet/base-datalet.html"> | ||
| 33 | +<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout.html"> | ||
| 34 | +<link rel="import" href="../../bower_components/paper-dialog/paper-dialog.html"> | ||
| 35 | +<link rel="import" href="../../bower_components/paper-fab/paper-fab.html"> | ||
| 36 | + | ||
| 37 | +<!-- | ||
| 38 | +`preview-datalet` is a datalet that allow user to preview the content of a web page. It creates a thumbnail of the site using the data-url attribute passed as input. | ||
| 39 | + | ||
| 40 | +Example: | ||
| 41 | + | ||
| 42 | + <preview-datalet data-url="http://spod.routetopa.eu" | ||
| 43 | + </preview-datalet> | ||
| 44 | + | ||
| 45 | + | ||
| 46 | +@element preview-datalet | ||
| 47 | +@status beta | ||
| 48 | +@homepage | ||
| 49 | +@group datalets | ||
| 50 | +--> | ||
| 51 | + | ||
| 52 | +<dom-module id="graph-with-clustering-datalet"> | ||
| 53 | + <template> | ||
| 54 | + | ||
| 55 | + <link rel="stylesheet" href="static/css/graphStyle.css"> | ||
| 56 | + | ||
| 57 | + <style is="custom-style"> | ||
| 58 | + | ||
| 59 | + #dialog{ | ||
| 60 | + position: absolute; | ||
| 61 | + padding: 20px; | ||
| 62 | + top: 20px; | ||
| 63 | + right:5%; | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + #close{ | ||
| 67 | + position: absolute; | ||
| 68 | + top: -20px; | ||
| 69 | + right: 3px; | ||
| 70 | + --iron-icon-height: 20px; | ||
| 71 | + --iron-icon-width: 20px; | ||
| 72 | + width: 24px; | ||
| 73 | + height: 24px; | ||
| 74 | + --paper-fab-background:#9e9e9e; | ||
| 75 | + z-index: 1001; | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + </style> | ||
| 79 | + | ||
| 80 | + <div style="align-content: center;overflow: visible" id="graph_content"> | ||
| 81 | + <svg id="sbiricuda"></svg> | ||
| 82 | + </div> | ||
| 83 | + | ||
| 84 | + <paper-dialog id="dialog"> | ||
| 85 | + <paper-fab id="close" mini icon="close" on-click="_onCloseClick"></paper-fab> | ||
| 86 | + <h2 id="dialog_title"></h2> | ||
| 87 | + <paper-dialog-scrollable id="dialog_content">cos</paper-dialog-scrollable> | ||
| 88 | + </paper-dialog> | ||
| 89 | + | ||
| 90 | + </template> | ||
| 91 | + | ||
| 92 | + <script src="static/js/d3.v3.js"></script> | ||
| 93 | + | ||
| 94 | + <script> | ||
| 95 | + _this = null; | ||
| 96 | + | ||
| 97 | + Polymer({ | ||
| 98 | + is : 'graph-with-clustering-datalet', | ||
| 99 | + | ||
| 100 | + properties: { | ||
| 101 | + /** | ||
| 102 | + * It's the url for the preview | ||
| 103 | + * | ||
| 104 | + * @attribute url | ||
| 105 | + * @type Strig | ||
| 106 | + * @default '' | ||
| 107 | + */ | ||
| 108 | + graph : { | ||
| 109 | + type : Object, | ||
| 110 | + value : undefined | ||
| 111 | + }, | ||
| 112 | + | ||
| 113 | + svgNodes : { | ||
| 114 | + type : Array, | ||
| 115 | + value : [] | ||
| 116 | + }, | ||
| 117 | + | ||
| 118 | + svgLinks : { | ||
| 119 | + type : Array, | ||
| 120 | + value : [] | ||
| 121 | + }, | ||
| 122 | + | ||
| 123 | + width: { | ||
| 124 | + type: Number, | ||
| 125 | + value: undefined | ||
| 126 | + }, | ||
| 127 | + | ||
| 128 | + height : { | ||
| 129 | + type : Number, | ||
| 130 | + value: undefined | ||
| 131 | + }, | ||
| 132 | + | ||
| 133 | + svg: { | ||
| 134 | + type: Object, | ||
| 135 | + value: undefined | ||
| 136 | + }, | ||
| 137 | + feelings:{ | ||
| 138 | + type: Array, | ||
| 139 | + values: ["Agree", "Neutral", "Not agree"] | ||
| 140 | + }, | ||
| 141 | + prev_selected_node : { | ||
| 142 | + type : Object, | ||
| 143 | + value : null | ||
| 144 | + }, | ||
| 145 | + | ||
| 146 | + force : { | ||
| 147 | + type : Object, | ||
| 148 | + value : null | ||
| 149 | + }, | ||
| 150 | + | ||
| 151 | + edgesMap : { | ||
| 152 | + type : Array, | ||
| 153 | + value : [] | ||
| 154 | + }, | ||
| 155 | + | ||
| 156 | + groups: { | ||
| 157 | + type: Array, | ||
| 158 | + value: [] | ||
| 159 | + }, | ||
| 160 | + | ||
| 161 | + hulls : { | ||
| 162 | + type: Array, | ||
| 163 | + value: [] | ||
| 164 | + }, | ||
| 165 | + hull : { | ||
| 166 | + type : Array, | ||
| 167 | + value : [] | ||
| 168 | + | ||
| 169 | + } | ||
| 170 | + }, | ||
| 171 | + | ||
| 172 | + groupPath : function(d) { | ||
| 173 | + return "M" + | ||
| 174 | + d3.geom.hull(d.values.map(function(i) { return [i.x, i.y];})) | ||
| 175 | + .join("L") | ||
| 176 | + + "Z"; | ||
| 177 | + }, | ||
| 178 | + | ||
| 179 | + groupFill : function(d, i) { | ||
| 180 | + var fill = d3.scale.category10(); | ||
| 181 | + return fill(i & 3); | ||
| 182 | + }, | ||
| 183 | + | ||
| 184 | + createHulls : function(nodes){ | ||
| 185 | + this.svg.selectAll("path") | ||
| 186 | + .data(nodes) | ||
| 187 | + .attr("d", this.groupPath) | ||
| 188 | + .enter().insert("path", "g") | ||
| 189 | + //.style("fill", _this.groupFill) | ||
| 190 | + .style("fill", "#60df20") | ||
| 191 | + //.style("stroke", _this.groupFill) | ||
| 192 | + .style("stroke", "#60df20") | ||
| 193 | + .style("stroke-width", 30) | ||
| 194 | + .style("stroke-linejoin", "round") | ||
| 195 | + .style("opacity", .2) | ||
| 196 | + .attr("d", this.groupPath); | ||
| 197 | + }, | ||
| 198 | + | ||
| 199 | + getNetwork : function(){ | ||
| 200 | + | ||
| 201 | + var nodes = [], links = [], prevLevel = 1, prevGroupIndex = 1; | ||
| 202 | + | ||
| 203 | + //for(var i=0; i < 27; i++) groups.push({key : "" + i , values : []}); | ||
| 204 | + | ||
| 205 | + //nodes.push(this.graph.nodes[0]) | ||
| 206 | + | ||
| 207 | + for(var i= 0,j=0; i < this.graph.nodes.length;i++,j+=3){ | ||
| 208 | + var node = this.graph.nodes[i]; | ||
| 209 | + var l = node.level; | ||
| 210 | + var sentiment = node.sentiment; | ||
| 211 | + var id = node.id; | ||
| 212 | + var father = node.father; | ||
| 213 | + | ||
| 214 | + this.groups.push([{key : "" + j, values : []}, {key : "" + (j + 1), values : []}, {key : "" + (j + 2), values : []}]); | ||
| 215 | + if(this.graph.nodes[i].father != null){ | ||
| 216 | + switch (parseInt(this.graph.nodes[i].sentiment)){ | ||
| 217 | + case 1: | ||
| 218 | + this.groups[this.graph.nodes[i].father.id][0].values.push(this.graph.nodes[i]); | ||
| 219 | + break; | ||
| 220 | + case 2: | ||
| 221 | + this.groups[this.graph.nodes[i].father.id][1].values.push(this.graph.nodes[i]); | ||
| 222 | + break; | ||
| 223 | + case 3: | ||
| 224 | + this.groups[this.graph.nodes[i].father.id][2].values.push(this.graph.nodes[i]); | ||
| 225 | + break; | ||
| 226 | + } | ||
| 227 | + } | ||
| 228 | + | ||
| 229 | + /*var node = this.graph.nodes[i]; | ||
| 230 | + var l = node.level; | ||
| 231 | + var sentiment = node.sentiment; | ||
| 232 | + var id = node.id; | ||
| 233 | + | ||
| 234 | + var gi = (((this.graph.nodes[i].level - 1) * 3) + parseInt(this.graph.nodes[i].sentiment)); | ||
| 235 | + groups[gi].values.push(node);*/ | ||
| 236 | + | ||
| 237 | + } | ||
| 238 | + | ||
| 239 | + this.hulls = []; | ||
| 240 | + var index = 0; | ||
| 241 | + for(var i=0; i < _this.groups.length; i++){ | ||
| 242 | + for(var j=0; j < _this.groups[i].length;j++){ | ||
| 243 | + if(_this.groups[i][j].values.length != 0) { | ||
| 244 | + if(_this.groups[i][j].values.length > 0){ | ||
| 245 | + _this.groups[i][j].key = "" + index; | ||
| 246 | + index++; | ||
| 247 | + this.hulls.push(_this.groups[i][j]); | ||
| 248 | + } | ||
| 249 | + } | ||
| 250 | + } | ||
| 251 | + } | ||
| 252 | + }, | ||
| 253 | + | ||
| 254 | + /*TEST*/ | ||
| 255 | + convexHulls : function(nodes, index, offset) { | ||
| 256 | + var hulls = {}; | ||
| 257 | + | ||
| 258 | + // create point sets | ||
| 259 | + for (var k=0; k<nodes.length; ++k) { | ||
| 260 | + var n = nodes[k]; | ||
| 261 | + if (n.size) continue; | ||
| 262 | + var i = index(n), | ||
| 263 | + l = hulls[i] || (hulls[i] = []); | ||
| 264 | + l.push([n.x-offset, n.y-offset]); | ||
| 265 | + l.push([n.x-offset, n.y+offset]); | ||
| 266 | + l.push([n.x+offset, n.y-offset]); | ||
| 267 | + l.push([n.x+offset, n.y+offset]); | ||
| 268 | + } | ||
| 269 | + | ||
| 270 | + // create convex hulls | ||
| 271 | + var hullset = []; | ||
| 272 | + for (i in hulls) { | ||
| 273 | + hullset.push({group: i, path: d3.geom.hull(hulls[i])}); | ||
| 274 | + } | ||
| 275 | + return hullset; | ||
| 276 | + }, | ||
| 277 | + | ||
| 278 | + drawCluster : function(d) { | ||
| 279 | + return this.curve(d.path); // 0.8 | ||
| 280 | + }, | ||
| 281 | + | ||
| 282 | + curve : function(d){ | ||
| 283 | + var curve = d3.svg.line() | ||
| 284 | + .interpolate("cardinal-closed") | ||
| 285 | + .tension(.85); | ||
| 286 | + return curve(d); | ||
| 287 | + }, | ||
| 288 | + /*END TEST*/ | ||
| 289 | + | ||
| 290 | + init : function(){ | ||
| 291 | + | ||
| 292 | + this.getNetwork(); | ||
| 293 | + | ||
| 294 | + if(this.force != null) this.force.stop(); | ||
| 295 | + force = d3.layout.force() | ||
| 296 | + .nodes(this.graph.nodes) | ||
| 297 | + .links(this.graph.links) | ||
| 298 | + .size([this.width, this.height]) | ||
| 299 | + .charge(-1e3) | ||
| 300 | + .friction(.7) | ||
| 301 | + .linkDistance(function (t){ return t.value ? t.value : 80}) | ||
| 302 | + .on("tick", this.tick).start(); | ||
| 303 | + | ||
| 304 | + _this.svg.selectAll("path").remove(); | ||
| 305 | + _this.hull = _this.svg.append("path") | ||
| 306 | + .style("fill", "#60df20") | ||
| 307 | + .style("stroke", "#60df20") | ||
| 308 | + .style("stroke-width", 30) | ||
| 309 | + .attr("class", "hull") | ||
| 310 | + .style("stroke-linejoin", "round") | ||
| 311 | + .style("opacity", .2); | ||
| 312 | + | ||
| 313 | + | ||
| 314 | + this.svg.selectAll(".link").data(this.graph.links).remove(); | ||
| 315 | + this.svgLinks = this.svg.selectAll(".link").data(this.graph.links).enter() | ||
| 316 | + .append("line") | ||
| 317 | + .attr("class", "link") | ||
| 318 | + /* .attr("x1", function(d) { return d.source.x; }) | ||
| 319 | + .attr("y1", function(d) { return d.source.y; }) | ||
| 320 | + .attr("x2", function(d) { return d.target.x; }) | ||
| 321 | + .attr("y2", function(d) { return d.target.y; })*/ | ||
| 322 | + .attr("style", function(t){ return "stroke:" + t.color }) | ||
| 323 | + .style("stroke-width", function(d) { return d.size || 1; }); | ||
| 324 | + | ||
| 325 | + this.svg.selectAll(".node").data(this.graph.nodes).remove(); | ||
| 326 | + this.svgNodes = this.svg.selectAll(".node").data(this.graph.nodes).enter() | ||
| 327 | + .append("g") | ||
| 328 | + .on("mouseover", this.mouseover) | ||
| 329 | + .on("mouseout", this.mouseout) | ||
| 330 | + .attr("class", function (t) { return t.fixed ? "node fixed" : "node"}) | ||
| 331 | + .attr("name", function (t) { return t.name ? t.name.split(" ").join("_").toLowerCase() : ""}) | ||
| 332 | + .append("circle") | ||
| 333 | + .on("click", this.active) | ||
| 334 | + .attr("id", function(t){ return t.id }) | ||
| 335 | + .attr("class", function (t) { return t.fixed ? "" : "drag"}) | ||
| 336 | + .attr("r", function (t){ return t.r ? t.r : 15 }) | ||
| 337 | + .attr("style", function (t) { return t.color ? "fill:" + t.color : !1 + "; stroke:white"}) | ||
| 338 | + .attr("filter", function(t){return t.image ? 'url(#filter1)' : ""}); | ||
| 339 | + | ||
| 340 | + //d3.selectAll(".drag").call(force.drag), this.svg.selectAll("g.node").call(this.text); | ||
| 341 | + | ||
| 342 | + this.svg.style("opacity", 1e-6) | ||
| 343 | + .transition() | ||
| 344 | + .duration(1000) | ||
| 345 | + .style("opacity", 1); | ||
| 346 | + | ||
| 347 | + d3.selectAll(".drag").call(force.drag), this.svg.selectAll("g.node").call(this.text); | ||
| 348 | + }, | ||
| 349 | + | ||
| 350 | + buildGraph: function (){ | ||
| 351 | + | ||
| 352 | + this.svg = this.svg.append("g") | ||
| 353 | + .call(d3.behavior.zoom().scaleExtent([.25, 20]).on("zoom", this.zoom)) | ||
| 354 | + .append("g"); | ||
| 355 | + | ||
| 356 | + //set initial zoom | ||
| 357 | + scale = (1.0); | ||
| 358 | + //translate = [(width-scale*width)/2, ((height-scale*height)/4)]; | ||
| 359 | + translate = [0, 0]; | ||
| 360 | + this.svg.transition() | ||
| 361 | + .duration(750) | ||
| 362 | + .attr("transform", "translate(" + translate + ")scale(" + scale + ")") | ||
| 363 | + .each("end", function () { | ||
| 364 | + d3.behavior.zoom() | ||
| 365 | + .scale(scale) | ||
| 366 | + .translate(translate); | ||
| 367 | + }); | ||
| 368 | + //end set initial zoom | ||
| 369 | + | ||
| 370 | + this.svg.append("rect") | ||
| 371 | + .attr("fill", "white") | ||
| 372 | + .attr("width", this.width) | ||
| 373 | + .attr("height", this.height); | ||
| 374 | + | ||
| 375 | + //pezzotto | ||
| 376 | + this.svg.append("filter") | ||
| 377 | + .attr("id","filter1") | ||
| 378 | + .attr("x","0%") | ||
| 379 | + .attr("y","0%") | ||
| 380 | + .attr("width","100%") | ||
| 381 | + .attr("height","100%") | ||
| 382 | + .append("feImage") | ||
| 383 | + .attr("xlink:href","http://icons.iconarchive.com/icons/hopstarter/soft-scraps/256/User-Executive-Green-icon.png"); | ||
| 384 | + | ||
| 385 | + this.init(); | ||
| 386 | + }, | ||
| 387 | + | ||
| 388 | + zoom: function() { | ||
| 389 | + _this.svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); | ||
| 390 | + }, | ||
| 391 | + | ||
| 392 | + text: function (t){ | ||
| 393 | + var e = t.append("svg:foreignObject").attr("width", 120).attr("height", 30); | ||
| 394 | + e.attr("style", function (t) { | ||
| 395 | + return "color:" + (t.color ? t.color : "#000") | ||
| 396 | + }).append("xhtml:div").html(function (t) { | ||
| 397 | + //return t.fixed ? t.name : null | ||
| 398 | + return t.name; | ||
| 399 | + }) | ||
| 400 | + }, | ||
| 401 | + | ||
| 402 | + tick : function () { | ||
| 403 | + // d3.select("svg").attr("style", "transform:translate(8%)"); | ||
| 404 | + d3.selectAll("g foreignObject").attr("x", function (t) { | ||
| 405 | + return t.x + (t.r ? 0.8 * t.r : 15) | ||
| 406 | + }).attr("y", function (t) { | ||
| 407 | + return t.y - 20 | ||
| 408 | + }); | ||
| 409 | + | ||
| 410 | + d3.selectAll("#logo text").attr("x", function (t) { | ||
| 411 | + return t.x + .7 * (t.r ? t.r : 15) | ||
| 412 | + }).attr("y", function (t) { | ||
| 413 | + return t.y | ||
| 414 | + }); | ||
| 415 | + | ||
| 416 | + _this.svgNodes.attr("cx", function (t) { | ||
| 417 | + return t.x = Math.max(25, Math.min(_this.width - 50, t.x)) | ||
| 418 | + }).attr("cy", function (t) { | ||
| 419 | + return t.y = Math.max(8, Math.min(600, t.y)) | ||
| 420 | + }); | ||
| 421 | + | ||
| 422 | + _this.svgLinks.attr("x1", function (t) { | ||
| 423 | + return t.source.x | ||
| 424 | + }).attr("y1", function (t) { | ||
| 425 | + return t.source.y | ||
| 426 | + }).attr("x2", function (t) { | ||
| 427 | + return t.target.x | ||
| 428 | + }).attr("y2", function (t) { | ||
| 429 | + return t.target.y | ||
| 430 | + }); | ||
| 431 | + | ||
| 432 | + //create hulls | ||
| 433 | + //var n = [{key : "0", values : [ _this.graph.nodes[14], _this.graph.nodes[15], _this.graph.nodes[16],_this.graph.nodes[17], _this.graph.nodes[18]]}]; | ||
| 434 | + | ||
| 435 | + //_this.createHulls([_this.hulls[2]]); | ||
| 436 | + //_this.createHulls(_this.hulls); | ||
| 437 | + | ||
| 438 | + var vertices = []; | ||
| 439 | + for(var i=0; i < _this.groups[0][0].values.length;i++){ | ||
| 440 | + vertices.push([_this.groups[0][0].values[i].x, _this.groups[0][0].values[i].y]); | ||
| 441 | + } | ||
| 442 | + _this.hull.datum(d3.geom.hull(vertices)).attr("d", function(d) { return "M" + d.join("L") + "Z"; }); | ||
| 443 | + }, | ||
| 444 | + | ||
| 445 | + mouseover : function (t) { | ||
| 446 | + d3.select(this).selectAll("circle").transition().duration(600).ease("elastic").attr("r", function (t) { | ||
| 447 | + //return 1 == t.fixed ? 1.4 * t.r : 15 | ||
| 448 | + return 1 == t.fixed ? 1.4 * t.r : t.r + 10; | ||
| 449 | + }); | ||
| 450 | + | ||
| 451 | + _this.$.dialog.close(); | ||
| 452 | + _this.$.dialog_title.innerHTML = t.name; | ||
| 453 | + _this.$.dialog_content.innerHTML = t.content; | ||
| 454 | + | ||
| 455 | + _this.$.dialog.open(); | ||
| 456 | + }, | ||
| 457 | + | ||
| 458 | + mouseout : function () { | ||
| 459 | + d3.select(this).selectAll("text").style("visibility", "hidden"), d3.select(this).selectAll("circle").transition().duration(400).attr("r", function (t) { | ||
| 460 | + return t.r ? t.r : 15 | ||
| 461 | + }); | ||
| 462 | + _this.$.dialog.close(); | ||
| 463 | + }, | ||
| 464 | + | ||
| 465 | + active : function (t) { | ||
| 466 | + | ||
| 467 | + _this.init(); | ||
| 468 | + _this.fire('graph-datalet_node-clicked', {node : t}); | ||
| 469 | + | ||
| 470 | + if(_this.prev_selected_node != null){ | ||
| 471 | + _this.prev_selected_node.style.fill = _this.prev_selected_node.style.stroke; | ||
| 472 | + _this.prev_selected_node.style.stroke = "#FFFFFF"; | ||
| 473 | + } | ||
| 474 | + | ||
| 475 | + _this.prev_selected_node = document.getElementById("" + t.id); | ||
| 476 | + _this.prev_selected_node.style.fill = "#FFFFFF" | ||
| 477 | + _this.prev_selected_node.style.stroke = t.color; | ||
| 478 | + | ||
| 479 | + /* _this.$.dialog.close(); | ||
| 480 | + _this.$.dialog_title.innerHTML = t.name; | ||
| 481 | + _this.$.dialog_content.innerHTML = t.content; | ||
| 482 | + | ||
| 483 | + _this.$.dialog.open();*/ | ||
| 484 | + }, | ||
| 485 | + | ||
| 486 | + _onCloseClick : function(){ | ||
| 487 | + //_this.$.dialog.close(); | ||
| 488 | + }, | ||
| 489 | + | ||
| 490 | + /** | ||
| 491 | + * It is called after the element’s template has been stamped and all elements inside the element’s local | ||
| 492 | + * DOM have been configured (with values bound from parents, deserialized attributes, or else default values) | ||
| 493 | + * and had their ready method called. | ||
| 494 | + * | ||
| 495 | + * Extract the dataset domain from the entire URL and set the text content of the datalet footer. | ||
| 496 | + * | ||
| 497 | + * @method ready | ||
| 498 | + * | ||
| 499 | + */ | ||
| 500 | + ready: function(){ | ||
| 501 | + | ||
| 502 | + _this = this; | ||
| 503 | + | ||
| 504 | + this.svg = d3.select("svg#sbiricuda").attr("class", "svg").attr({ | ||
| 505 | + width: "100%", | ||
| 506 | + height: "100%" | ||
| 507 | + }).attr("viewBox", "0 0 " + this.width + " " + this.height) | ||
| 508 | + .attr("pointer-events", "all") | ||
| 509 | + .attr("style", "transform:translate(0px)") | ||
| 510 | + .style("position", "absolute"); | ||
| 511 | + | ||
| 512 | + this.buildGraph(); | ||
| 513 | + } | ||
| 514 | + }); | ||
| 515 | + </script> | ||
| 516 | +</dom-module> | ||
| 0 | \ No newline at end of file | 517 | \ No newline at end of file |
datalets/graph-datalet/static/css/graphClusteringStyle.css
0 → 100644
| 1 | +#sbiricuda { | ||
| 2 | + border: 1px solid #ccc; | ||
| 3 | +} | ||
| 4 | + | ||
| 5 | +.node { | ||
| 6 | + fill: lightsteelblue; | ||
| 7 | + stroke: #FFFFFF; | ||
| 8 | + stroke-width: 3px; | ||
| 9 | +} | ||
| 10 | +.leaf { | ||
| 11 | + stroke: #fff; | ||
| 12 | + stroke-width: 1.5px; | ||
| 13 | +} | ||
| 14 | +.hull { | ||
| 15 | + fill: lightsteelblue; | ||
| 16 | + fill-opacity: 0.3; | ||
| 17 | +} | ||
| 18 | +.link { | ||
| 19 | + stroke: #333; | ||
| 20 | + stroke-opacity: 0.5; | ||
| 21 | + pointer-events: none; | ||
| 22 | +} | ||
| 0 | \ No newline at end of file | 23 | \ No newline at end of file |
datalets/graph-datalet/static/css/graphStyle.css
| 1 | circle{ | 1 | circle{ |
| 2 | - stroke-width: 2.5px; | 2 | + stroke-width: 1.5px; |
| 3 | } | 3 | } |
| 4 | 4 | ||
| 5 | .text { | 5 | .text { |
| @@ -11,8 +11,8 @@ circle{ | @@ -11,8 +11,8 @@ circle{ | ||
| 11 | cursor: pointer; | 11 | cursor: pointer; |
| 12 | fill: #fff; | 12 | fill: #fff; |
| 13 | stroke: #FFFFFF; | 13 | stroke: #FFFFFF; |
| 14 | - stroke-width: 4.5px | ||
| 15 | - z-index: 100; | 14 | + stroke-width: 2.5px |
| 15 | + z-index: 10; | ||
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | .node.fixed { | 18 | .node.fixed { |