Commit cc7592d4d64206f966c121ae2641914dff4cb3fd

Authored by Luigi Serra
1 parent d14cd054

graphs update

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 {