Added autocomplete functionality
|
@ -5,18 +5,24 @@
|
|||
<script src="util/graph_actions.js"></script>
|
||||
<link rel="stylesheet" href="jquery-ui/css/smoothness/jquery-ui-1.10.4.custom.css" />
|
||||
<script src="util/setup_census.js"></script>
|
||||
<script src="util/ui_commands.js"></script>
|
||||
<script src="jquery-ui/js/jquery-1.10.2.js"></script>
|
||||
<script src="jquery-ui/js/jquery-ui-1.10.4.custom.min.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="graph" style='height:100%; width:100%'></div>
|
||||
<h1>Princeton Web Transparency</h1>
|
||||
<div id="weight_slider" style='width:30%'></div>
|
||||
<div class="ui-widget" style ='width:30%'>
|
||||
<label for="tags">Tags: </label>
|
||||
<input id="tags">
|
||||
</div>
|
||||
<div id="graph" style='height:80%; width:100%'></div>
|
||||
<div id="cookie_panel">
|
||||
<div id="owners"></div>
|
||||
<div id="cookies"></div>
|
||||
</div>
|
||||
<div id="weight_slider"></div>
|
||||
<script> init(); </script>
|
||||
|
||||
|
||||
<script>init();</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
После Ширина: | Высота: | Размер: 1.7 KiB |
Двоичные данные
census/www/jquery-ui/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png
Normal file
После Ширина: | Высота: | Размер: 212 B |
Двоичные данные
census/www/jquery-ui/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png
Normal file
После Ширина: | Высота: | Размер: 208 B |
Двоичные данные
census/www/jquery-ui/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png
Normal file
После Ширина: | Высота: | Размер: 335 B |
Двоичные данные
census/www/jquery-ui/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png
Normal file
После Ширина: | Высота: | Размер: 207 B |
Двоичные данные
census/www/jquery-ui/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png
Normal file
После Ширина: | Высота: | Размер: 262 B |
Двоичные данные
census/www/jquery-ui/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png
Normal file
После Ширина: | Высота: | Размер: 262 B |
Двоичные данные
census/www/jquery-ui/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png
Normal file
После Ширина: | Высота: | Размер: 332 B |
Двоичные данные
census/www/jquery-ui/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png
Normal file
После Ширина: | Высота: | Размер: 280 B |
После Ширина: | Высота: | Размер: 6.8 KiB |
После Ширина: | Высота: | Размер: 4.4 KiB |
После Ширина: | Высота: | Размер: 6.8 KiB |
После Ширина: | Высота: | Размер: 6.8 KiB |
После Ширина: | Высота: | Размер: 4.4 KiB |
|
@ -143,3 +143,26 @@ function filter_out_low_weights(threshold_weight) {
|
|||
});
|
||||
s.refresh();
|
||||
}
|
||||
|
||||
function highlight_cookie_owners(cookie) {
|
||||
console.log(cookie);
|
||||
// highlight only the nodes and edges with a single value
|
||||
s.graph.nodes().forEach(function(n) {
|
||||
if (cookie in n.cookies) {
|
||||
n.color = highlighted;
|
||||
}
|
||||
else {
|
||||
n.color = faded;
|
||||
}
|
||||
});
|
||||
// next, highlight the edges with a single value
|
||||
s.graph.edges().forEach(function(e) {
|
||||
if (cookie in e.cookies) {
|
||||
e.color = highlighted;
|
||||
}
|
||||
else {
|
||||
e.color = faded;
|
||||
}
|
||||
});
|
||||
s.refresh();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
var curr_clicked = null; // currently clicked node
|
||||
var curr_cookies = null; // list of cookies held at currently clicked node
|
||||
var highlighted = "ff0000"; // color to highlight node
|
||||
var faded = "fffaf0"; // color for faded out nodes
|
||||
|
||||
// dummy function: colors a node gray
|
||||
function hover_node(n) {
|
||||
// either we are not clicking on a node or we are hovering over that node
|
||||
// also, ignore nodes that are not currently highlighed
|
||||
if (curr_clicked == null || n.data.node.id == curr_clicked || n.data.node.color != highlighted) {
|
||||
return;
|
||||
}
|
||||
|
||||
// try to find the common cookies
|
||||
common_cookies = [];
|
||||
curr_cookies.forEach(function (c) {
|
||||
if (c in n.data.node.cookies) {
|
||||
common_cookies.push(c);
|
||||
}
|
||||
});
|
||||
|
||||
common_cookies.sort();
|
||||
console.log(common_cookies);
|
||||
fill_cookie_data(n.data.node.id);
|
||||
|
||||
s.refresh();
|
||||
}
|
||||
|
||||
function unhover_node(n) {
|
||||
if (curr_clicked == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
fill_cookie_data(null);
|
||||
}
|
||||
|
||||
function click_stage(stage) {
|
||||
reset_settings(stage);
|
||||
s.refresh();
|
||||
}
|
||||
|
||||
// sets the graph to its original coloring
|
||||
function reset_settings(stage) {
|
||||
s.graph.nodes().forEach(function(n) {
|
||||
n.color = n.original_color;
|
||||
});
|
||||
|
||||
s.graph.edges().forEach(function(e) {
|
||||
e.color = e.original_color;
|
||||
});
|
||||
}
|
||||
|
||||
function click_node(e) {
|
||||
if (e.data.node.id == curr_clicked) {
|
||||
return;
|
||||
}
|
||||
|
||||
color_flow(e);
|
||||
fill_cookie_data(null);
|
||||
}
|
||||
|
||||
// used for clicking, colors all nodes and edges that share a common cookie
|
||||
// with the currently clicked node
|
||||
function color_flow(e) {
|
||||
// gets the cookies placed at this node
|
||||
cookies = Object.keys(e.data.node.cookies);
|
||||
curr_clicked = e.data.node.id;
|
||||
curr_cookies = cookies;
|
||||
|
||||
// color all nodes that have a cookie shared with this node
|
||||
s.graph.nodes().forEach(function(n) {
|
||||
cookies.some(function(c) {
|
||||
if (c in n.cookies) {
|
||||
n.color = highlighted;
|
||||
}
|
||||
else {
|
||||
n.color = faded;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// next, color the edges
|
||||
s.graph.edges().forEach(function(e) {
|
||||
cookies.some(function(c) {
|
||||
if (c in e.cookies) {
|
||||
e.color = highlighted;
|
||||
}
|
||||
else {
|
||||
e.color = faded;
|
||||
}
|
||||
});
|
||||
});
|
||||
s.refresh();
|
||||
}
|
||||
|
||||
function fill_cookie_data(hovered_node) {
|
||||
if (hovered_node == null) {
|
||||
$("#owners").html(s.graph.nodes(curr_clicked).label);
|
||||
// in this case, we fill in all of the current cookies
|
||||
owned_cookies = "";
|
||||
curr_cookies.forEach(function(c) {
|
||||
owned_cookies += c + "</br>";
|
||||
});
|
||||
|
||||
$("#cookies").html(owned_cookies);
|
||||
}
|
||||
|
||||
else {
|
||||
console.log(s.graph.nodes(hovered_node).label);
|
||||
$("#owners").html(s.graph.nodes(curr_clicked).label + " and " + s.graph.nodes(hovered_node).label);
|
||||
|
||||
owned_cookies = "";
|
||||
curr_cookies.forEach(function(c) {
|
||||
if (c in s.graph.nodes(hovered_node).cookies) {
|
||||
owned_cookies += c + "</br>";
|
||||
}
|
||||
});
|
||||
|
||||
$("#cookies").html(owned_cookies);
|
||||
}
|
||||
}
|
||||
|
||||
function filter_out_low_weights(threshold_weight) {
|
||||
// first fade out the low-weight nodes
|
||||
s.graph.nodes().forEach(function(n) {
|
||||
if (n.weight < threshold_weight) {
|
||||
n.color = faded;
|
||||
}
|
||||
else {
|
||||
n.color = highlighted;
|
||||
}
|
||||
});
|
||||
|
||||
// next, fade out the edges with at least one faded node
|
||||
s.graph.edges().forEach(function(e) {
|
||||
if (s.graph.nodes(e.source).color == faded
|
||||
|| s.graph.nodes(e.target).color == faded) {
|
||||
e.color = faded;
|
||||
}
|
||||
else {
|
||||
e.color = highlighted;
|
||||
}
|
||||
});
|
||||
s.refresh();
|
||||
}
|
||||
|
||||
function highlight_cookie_owners(cookie) {
|
||||
console.log(cookie);
|
||||
// highlight only the nodes and edges with a single value
|
||||
s.graph.nodes().forEach(function(n) {
|
||||
if (cookie in n.cookies) {
|
||||
n.color = highlighted;
|
||||
}
|
||||
else {
|
||||
n.color = faded;
|
||||
}
|
||||
});
|
||||
// next, highlight the edges with a single value
|
||||
s.graph.edges().forEach(function(e) {
|
||||
if (cookie in e.cookies) {
|
||||
e.color = highlighted;
|
||||
}
|
||||
else {
|
||||
e.color = faded;
|
||||
}
|
||||
});
|
||||
s.refresh();
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
var base_color = "ff0000"; // standard node for colors
|
||||
var base_color = "0066ff"; // standard node for colors
|
||||
|
||||
function init() {
|
||||
// setup the graph
|
||||
|
@ -20,13 +20,13 @@ function init() {
|
|||
}
|
||||
});
|
||||
s.graph.edges().forEach(function(e) {
|
||||
e.color = base_color;
|
||||
e.color = "e6e6e6";
|
||||
e.original_color = e.color;
|
||||
e.weight = Object.keys(e.cookies).length;
|
||||
});
|
||||
s.refresh();
|
||||
|
||||
// set up the ui
|
||||
// ui, pt 1: build up a slider that filters nodes by weights
|
||||
$("#weight_slider").slider({
|
||||
range: "max",
|
||||
min: 0,
|
||||
|
@ -37,16 +37,27 @@ function init() {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
// ui, pt 2: build up an autocomplete feature to look up cookies
|
||||
// first get the list of all the cookies
|
||||
cookie_dict = {};
|
||||
s.graph.nodes().forEach(function(n) {
|
||||
Object.keys(n.cookies).forEach(function(c) {
|
||||
cookie_dict[c] = true;
|
||||
});
|
||||
});
|
||||
cookie_list = Object.keys(cookie_dict);
|
||||
cookie_list.sort();
|
||||
$("#tags").autocomplete({
|
||||
source: cookie_list,
|
||||
select: function(event, ui) {
|
||||
highlight_cookie_owners(ui.item.value);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
|
||||
// bind actions from graph_actions.js
|
||||
s.bind('overNode', hover_node);
|
||||
s.bind('outNode', unhover_node);
|
||||
s.bind('clickStage', click_stage);
|
||||
s.bind('clickNode', click_node);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
var base_color = "0066ff"; // standard node for colors
|
||||
|
||||
function init() {
|
||||
// setup the graph
|
||||
s = new sigma(document.getElementById('graph'));
|
||||
sigma.parsers.json(
|
||||
'graph.json',
|
||||
s,
|
||||
function() {
|
||||
max_weight = 0; // max weight of a node
|
||||
|
||||
// save the original color of the graph for later re-coloring
|
||||
// also, save the weights for each node and edge
|
||||
s.graph.nodes().forEach(function(n) {
|
||||
n.color = base_color;
|
||||
n.original_color = n.color;
|
||||
n.weight = Object.keys(n.cookies).length;
|
||||
if (n.weight > max_weight) {
|
||||
max_weight = n.weight;
|
||||
}
|
||||
});
|
||||
s.graph.edges().forEach(function(e) {
|
||||
e.color = "e6e6e6";
|
||||
e.original_color = e.color;
|
||||
e.weight = Object.keys(e.cookies).length;
|
||||
});
|
||||
s.refresh();
|
||||
|
||||
// ui, pt 1: build up a slider that filters nodes by weights
|
||||
$("#weight_slider").slider({
|
||||
range: "max",
|
||||
min: 0,
|
||||
max: max_weight,
|
||||
value: max_weight / 2,
|
||||
font-size: 1px,
|
||||
slide: function(event, ui) {
|
||||
filter_out_low_weights(ui.value);
|
||||
}
|
||||
});
|
||||
|
||||
// ui, pt 2: build up an autocomplete feature to look up cookies
|
||||
// first get the list of all the cookies
|
||||
cookie_dict = {};
|
||||
s.graph.nodes().forEach(function(n) {
|
||||
Object.keys(n.cookies).forEach(function(c) {
|
||||
cookie_dict[c] = true;
|
||||
});
|
||||
});
|
||||
cookie_list = Object.keys(cookie_dict);
|
||||
cookie_list.sort();
|
||||
$("#tags").autocomplete({
|
||||
source: cookie_list,
|
||||
select: function(event, ui) {
|
||||
highlight_cookie_owners(ui.item.value);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// bind actions from graph_actions.js
|
||||
s.bind('overNode', hover_node);
|
||||
s.bind('outNode', unhover_node);
|
||||
s.bind('clickStage', click_stage);
|
||||
s.bind('clickNode', click_node);
|
||||
}
|