Skip to content

Instantly share code, notes, and snippets.

@pierreelliott
Last active January 7, 2020 07:42
Show Gist options
  • Save pierreelliott/83aabd3640a5fc3effd1734a101aabd2 to your computer and use it in GitHub Desktop.
Save pierreelliott/83aabd3640a5fc3effd1734a101aabd2 to your computer and use it in GitHub Desktop.
Projet Dataviz - Simple visu
license: mit
{"categories": [{"cat_name": "Search", "sites": [{"total": 26730129, "session_length": 0.1433833333334178, "data": {"text": {"html": {"val": 4983005, "prop": 186}, "javascript": {"val": 14881339, "prop": 556}, "css": {"val": 959916, "prop": 35}, "plain": {"val": 81125, "prop": 3}, "val": 20905385, "prop": 780}, "image": {"png": {"val": 2628541, "prop": 98}, "webp": {"val": 263175, "prop": 9}, "x-icon": {"val": 28769, "prop": 1}, "svg+xml": {"val": 30735, "prop": 1}, "jpeg": {"val": 2231486, "prop": 83}, "gif": {"val": 158254, "prop": 5}, "vnd.microsoft.icon": {"val": 0, "prop": 0}, "val": 5340960, "prop": 197}, "font": {"woff2": {"val": 275701, "prop": 10}, "val": 275701, "prop": 10}, "others": {"val": 208083, "prop": 13, "types": "x-unknown, application"}}, "total_proportion": 1000, "website": "Google"}], "average": {"website": "Average Search website", "data": {"text": {"val": 20905385, "prop": 782}, "image": {"val": 5340960, "prop": 199}, "font": {"val": 275701, "prop": 10}, "others": {"val": 208083, "prop": 9}}, "total": 26730129, "total_proportion": 1000}}]}
{"categories": [{"cat_name": "Search", "sites": [{"total": 26730129, "session_length": 0.1433833333334178, "data": {"text": {"html": {"val": 4983005, "prop": 186}, "javascript": {"val": 14881339, "prop": 556}, "css": {"val": 959916, "prop": 35}, "plain": {"val": 81125, "prop": 3}, "val": 20905385, "prop": 780, "type": "text"}, "image": {"png": {"val": 2628541, "prop": 98}, "webp": {"val": 263175, "prop": 9}, "x-icon": {"val": 28769, "prop": 1}, "svg+xml": {"val": 30735, "prop": 1}, "jpeg": {"val": 2231486, "prop": 83}, "gif": {"val": 158254, "prop": 5}, "vnd.microsoft.icon": {"val": 0, "prop": 0}, "val": 5340960, "prop": 197, "type": "image"}, "font": {"woff2": {"val": 275701, "prop": 10}, "val": 275701, "prop": 10, "type": "font"}, "others": {"val": 208083, "prop": 13, "types": ["x-unknown", "application"], "type": "others"}}, "total_proportion": 1000, "array_data": [{"html": {"val": 4983005, "prop": 186}, "javascript": {"val": 14881339, "prop": 556}, "css": {"val": 959916, "prop": 35}, "plain": {"val": 81125, "prop": 3}, "val": 20905385, "prop": 780, "type": "text"}, {"png": {"val": 2628541, "prop": 98}, "webp": {"val": 263175, "prop": 9}, "x-icon": {"val": 28769, "prop": 1}, "svg+xml": {"val": 30735, "prop": 1}, "jpeg": {"val": 2231486, "prop": 83}, "gif": {"val": 158254, "prop": 5}, "vnd.microsoft.icon": {"val": 0, "prop": 0}, "val": 5340960, "prop": 197, "type": "image"}, {"woff2": {"val": 275701, "prop": 10}, "val": 275701, "prop": 10, "type": "font"}, {"val": 208083, "prop": 13, "types": ["x-unknown", "application"], "type": "others"}], "website": "Google"}], "average": {"website": "Average Search website", "data": {"text": {"val": 20905385, "prop": 782}, "image": {"val": 5340960, "prop": 199}, "font": {"val": 275701, "prop": 10}, "others": {"val": 208083, "prop": 9}}, "total": 26730129, "total_proportion": 1000}}]}
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v5.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
.back-grey { background-color: grey; }
svg { background-color: pink}
.hidden {
display: none;
}
div.tooltip {
color: #222;
background-color: #fff;
padding: .5em;
text-shadow: #f5f5f5 0 1px 0;
border-radius: 2px;
opacity: 0.9;
position: absolute;
}
</style>
</head>
<body>
<div id="my_dataviz" class="back-grey"></div>
<script>
// Bind MIME types to readable types (HTML, Scripts, Images, ...)
var bindings = {
"text/html": "HTML",
"text/javascript": "script"
}
</script>
<script>
var margin = {top: 20, right: 30, bottom: 20, left: 50},
width = 960 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
var svg = d3.select("#my_dataviz")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", `translate(${margin.left}, ${margin.top})`);
var graph = svg;
d3.json("data2.json").then(data => {
console.warn(data)
showSimpleConsumption2(graph, data.categories[0].sites[0], data.categories[0])
});
function showSimpleConsumption(svg, site, category) {
console.log(site)
var x = d3.scaleLinear()
.range([0, width/2])
.domain([0, 1000]);
var tooltip = d3.select('#my_dataviz').append('div')
.attr('class', 'hidden tooltip');
var color = d3.scaleQuantize() .range(["#93c3df","#6daed5","#4b97c9","#2f7ebc","#1864aa","#0a4a90","#08306b"])
.domain([0, site.array_data.length]);
var data = site.array_data
data.sort((x, y) => {
return d3.descending(x.prop, y.prop);
});
console.log(data)
var stack = createStack()
svg.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("class", "data")
.attr("height", 100)
.attr("fill", (d,i) => color(i))
.attr("width", (d) => {
return x(d.prop)
})
.attr("x", (d, i, arr) => {
return stack(x(d.prop))
})
.attr("y", 0)
.on("mouseover", function(d) {
var elem = d3.select(this);
elem.style("fill", d3.rgb(elem.style("fill")).darker(0.5));
})
.on('mousemove', function(d) {
// on recupere la position de la souris
var mousePos = d3.mouse(this);
// on affiche le toolip
var subtypes = Object.keys(d)
.filter(e => typeof d[e] === "object" && !Array.isArray(d[e]))
if(d.type === "others") subtypes = d.types
tooltip.classed('hidden', false)
// on positionne le tooltip en fonction de la position de la souris
.attr('style', 'left:' + (mousePos[0] + 15) +
'px; top:' + (mousePos[1] - 35) + 'px')
// on affiche le nom de l'etat et sa valeur (ou un message d'erreur)
.html(`${d.type} (${subtypes.join(", ")})`);
})
.on('mouseout', function() {
// on cache le tooltip
tooltip.classed('hidden', true);
var elem = d3.select(this);
elem.style("fill", d3.rgb(elem.style("fill")).brighter(0.5));
});
svg.append("g")
.attr("class", "y_axis")
.attr("transform", `translate(0,0)`)
.call(d3.axisBottom(d3.scaleBand()
.domain(["Mon site"])))
}
function createStack() {
var items = []
const reducer = (accumulator, currentValue) => accumulator + currentValue;
return function(item) {
let totalProportion = items.length > 0 ? items.reduce(reducer): 0;
items.push(item);
return totalProportion;
}
}
function showSimpleConsumption2(svg, site, category) {
console.log(site)
var layers = site.array_data;
// var x = d3.scaleLinear()
// .range([0, width/2])
// .domain([0, 1000]);
var x = d3.scaleBand()
.rangeRound([0, width/2])
.paddingInner(0.05)
.align(0.1);
var y = d3.scaleLinear()
.rangeRound([height, 0]);
var names = [site.website, category.average.website]
var data = [site, category.average];
console.log(data)
var keys = [];
for (key in category.average.data){
keys.push(key);
}
var color = d3.scaleQuantize()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"])
.domain([0, site.array_data.length]);
console.log("array_data length", keys.length)
// data.forEach(function(d){
// d.total = 0;
// keys.forEach(function(k){
// d.total += d[k];
// })
// });
x.domain(data.map(function(d) {
return d.website;
}));
y.domain([0, site.total]).nice();
var tooltip = d3.select('body').append('div')
.attr('class', 'hidden tooltip');
console.log("data", data)
stack = dataToStackedData(data);
console.log("stack", stack)
var stackedData = d3
.stack()
.keys(keys)
(stack); // Note : d3 veut un tableau
console.log("D3 Stacked data:", stackedData)
// Based on : https://stackoverflow.com/questions/45941427/d3-stacked-chart-with-json-data
svg.append("g")
.selectAll("g")
.data(stackedData)
.enter().append("g")
.attr("fill", function(d) {
console.log("d",d);
return color(d.key);
})
.selectAll("rect")
.data(function(d) {
return d;
})
.enter().append("rect")
.attr("x", function(d) {
console.log(d)
return x(d.data.website);
})
.attr("y", function(d) {
return y(d[1]);
})
.attr("height", function(d) {
return y(d[0]) - y(d[1]);
})
.attr("width", x.bandwidth())
.on("mouseover", function(d) {
var elem = d3.select(this);
elem.style("fill", d3.rgb(elem.style("fill")).darker(0.5));
})
.on('mousemove', function(d, i, n) {
// on recupere la position de la souris
var mousePos = d3.mouse(this);
console.log("=======")
console.warn(d)
console.warn(i)
console.warn(n)
// on affiche le toolip
tooltip.classed('hidden', false)
// on positionne le tooltip en fonction de la position de la souris
.attr('style', 'left:' + (mousePos[0] + 15) +
'px; top:' + (mousePos[1] - 35) + 'px')
// on affiche le nom de l'etat et sa valeur (ou un message d'erreur)
.html(`${d.data.website}`);
})
.on('mouseout', function() {
// on cache le tooltip
tooltip.classed('hidden', true);
var elem = d3.select(this);
elem.style("fill", d3.rgb(elem.style("fill")).brighter(0.5));
});
}
function dataToStackedData(data) {
var stacked = []
data.forEach(site => {
ob = {};
ob.website = site.website;
for([key, d] of Object.entries(site.data)) {
ob[key] = d.val
}
stacked.push(ob);
})
return stacked;
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment