513 lines
16 KiB
JavaScript
Executable File
513 lines
16 KiB
JavaScript
Executable File
|
|
function displayDataviz(data){
|
|
console.log(data);
|
|
let lane_array = [];
|
|
let now = Date.now();
|
|
|
|
let earlier = now;
|
|
|
|
// ICI CACLCULER UNE HAUTEUR TOTAL EN FONCTION DU NOMBRE D'ACTIVISTE PAR LIGNE
|
|
//height of items 10
|
|
let item_height = 15;
|
|
//object pour la hauteur
|
|
// juste un array que je prendrai dans l'ordre des line
|
|
const lineHeight_array = [];
|
|
|
|
|
|
data.forEach(function(e){
|
|
lane_array.push(e)
|
|
if(e.start < earlier){
|
|
earlier = e.start;
|
|
}
|
|
|
|
});
|
|
let items_array = [];
|
|
data.forEach(function(e){
|
|
e.activist.forEach(function(d){
|
|
items_array.push(d);
|
|
if(d.start < earlier){
|
|
earlier = d.start;
|
|
}
|
|
});
|
|
if (e.activist.length*item_height > 50) {
|
|
lineHeight_array.push(e.activist.length*item_height);
|
|
}else{
|
|
lineHeight_array.push(50);
|
|
}
|
|
});
|
|
var lanes = lane_array,
|
|
laneLength = lanes.length,
|
|
items = items_array;
|
|
|
|
var t1 = new Date(earlier);
|
|
var t2 = new Date(now);
|
|
|
|
|
|
var timeBegin = earlier,
|
|
timeEnd = now ;
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
let pw = $(".post_content").width();
|
|
var m = [20, 15, 15, 120], //top right bottom left
|
|
w = pw - m[1] - m[3],
|
|
h = sumArray(lineHeight_array) + (sumArray(lineHeight_array)/10) + 180,
|
|
miniHeight = sumArray(lineHeight_array)/10 + 80,
|
|
mainHeight = h - miniHeight - 40;
|
|
|
|
//scales
|
|
var x = d3.scaleLinear()
|
|
.domain([timeBegin, timeEnd])
|
|
.range([0, w]);
|
|
var revert_x = d3.scaleLinear()
|
|
.domain([0, w])
|
|
.range([timeBegin, timeEnd]);
|
|
var x1 = d3.scaleLinear()
|
|
.range([0, w]);
|
|
var y1 = d3.scaleLinear()
|
|
.domain([0, laneLength])
|
|
.range([0, mainHeight]);
|
|
var y2 = d3.scaleLinear()
|
|
.domain([0, laneLength])
|
|
.range([0, miniHeight]);
|
|
|
|
var chart = d3.select("#datavis")
|
|
.append("svg")
|
|
.attr("width", w + m[1] + m[3])
|
|
.attr("height", h + m[0] + m[2])
|
|
/*.attr("viewBox", '0 0 '+(h + m[0] + m[2])+' '+(w + m[1] + m[3])+'')*/
|
|
.attr("class", "chart");
|
|
|
|
chart.append("defs").append("clipPath")
|
|
.attr("id", "clip")
|
|
.append("rect")
|
|
.attr("width", w)
|
|
.attr("height", mainHeight);
|
|
|
|
var main = chart.append("g")
|
|
.attr("transform", "translate(" + m[3] + "," + m[0] + ")")
|
|
.attr("width", w)
|
|
.attr("height", mainHeight)
|
|
.attr("class", "main");
|
|
|
|
|
|
var mini = chart.append("g")
|
|
.attr("transform", "translate(" + m[3] + "," + (mainHeight + m[0]+ 20) + ")")
|
|
.attr("width", w-100)
|
|
.attr("height", miniHeight)
|
|
.attr("class", "mini");
|
|
|
|
//main lanes and texts
|
|
|
|
main.append("g").selectAll(".laneText")
|
|
.data(lanes)
|
|
.enter().append("text")
|
|
.text(function(d) {return d.title;})
|
|
.attr("x", -m[1])
|
|
.attr("y", function(d, i) { if(d.lane == 0){ return lineHeight_array[i]/2}else{ return lineHeight_array[i]+sumArray(lineHeight_array, i-1)-lineHeight_array[i]/2};})
|
|
.attr("dy", ".5ex")
|
|
.attr("text-anchor", "end")
|
|
.attr("class", "laneText");
|
|
|
|
main.append("g").selectAll(".laneLines")
|
|
.data(lanes)
|
|
.enter().append("line")
|
|
.attr("x1", m[1])
|
|
.attr("y1", function(d,i) { if(d.lane == 0){ return lineHeight_array[i]}else{ return lineHeight_array[i]+sumArray(lineHeight_array, i-1)};})
|
|
.attr("x2", w)
|
|
.attr("y2", function(d,i) {if(d.lane == 0){return lineHeight_array[i]}else{return lineHeight_array[i]+sumArray(lineHeight_array, i-1)};})
|
|
.attr("stroke", "black")
|
|
|
|
|
|
const xaxis = d3.scaleLinear()
|
|
.domain([timeBegin, timeEnd])
|
|
.range([0, w]);
|
|
|
|
mini.append("g")
|
|
.attr("transform", "translate(0," + miniHeight + ")")
|
|
.call(d3.axisBottom(xaxis).ticks(t2.getFullYear()-t1.getFullYear()).tickFormat(d3.timeFormat('%Y')))
|
|
.selectAll("text")
|
|
/*.attr("transform", "translate(-10,10)rotate(-45)")*/
|
|
.style("text-anchor", "center")
|
|
.style("font-size", 20)
|
|
.style("fill", "black");
|
|
|
|
|
|
|
|
// coalition
|
|
// adapt in display
|
|
/*var coa = main.append("g").selectAll("rect")
|
|
.data(lanes)
|
|
.enter().append("rect")
|
|
.attr("class", "coalition")
|
|
.attr("x", function(d) {var date = new Date(d.start); return x(d.start);})
|
|
.attr("y", function(d) {return y1(d.lane) + 10;})
|
|
.attr("height", function(d) {return .8 * y1(1);})
|
|
.attr("width", function(d) { return x(d.end) - x(d.start);})
|
|
.attr("pos", function(d) {return d.lane });*/
|
|
|
|
|
|
//mini lanes and texts
|
|
mini.append("g").selectAll(".laneLines")
|
|
.data(items)
|
|
.enter().append("line")
|
|
.attr("x1", m[1])
|
|
.attr("y1", function(d) {return y2(d.lane);})
|
|
.attr("x2", w)
|
|
.attr("y2", function(d) {return y2(d.lane);})
|
|
.attr("stroke", "lightgray");
|
|
|
|
mini.append("g").selectAll(".laneText")
|
|
.data(lanes)
|
|
.enter().append("text")
|
|
.text(function(d) {return d.title;})
|
|
.attr("x", -m[1])
|
|
.attr("y", function(d, i) {return y2(i + .5);})
|
|
.attr("dy", ".5ex")
|
|
.attr("text-anchor", "end")
|
|
.attr("class", "laneText");
|
|
|
|
var itemCoa = main.append("g").attr("clip-path", "url(#clip)");
|
|
var itemCircles = main.append("g")
|
|
.attr("clip-path", "url(#clip)");
|
|
var itemRects = main.append("g")
|
|
.attr("clip-path", "url(#clip)");
|
|
|
|
var axisMain = main.append("g")
|
|
.attr("clip-path", "url(#clip)");
|
|
|
|
coa = mini.append("g").selectAll("rect")
|
|
.data(lanes)
|
|
.enter().append("rect")
|
|
.attr("class", "coalition")
|
|
.attr("x", function(d) { return x(d.start);})
|
|
.attr("y", function(d) {return y2(d.lane) + 2;})
|
|
.attr("height", function(d) {return .8 * y2(1);})
|
|
.attr("width", function(d) { return x(d.end) - x(d.start);})
|
|
.attr("pos", function(d) {return d.lane });
|
|
|
|
//mini item rects
|
|
mini.append("g").selectAll("miniItems")
|
|
.data(items)
|
|
.enter().append("rect")
|
|
.attr("class", function(d) {return "markers";})
|
|
.attr("x", function(d) {return x(d.start);})
|
|
/*.attr("y", function(d, i) {let l1 = d.lane+1; let increments = (y2(l1)-y2(d.lane)) / (lanes[d.lane].activist.length)*i; return y2(d.lane)+increments;})*/
|
|
.attr("y", function(d){ let idx = lanes[d.lane].activist.indexOf(d); let increments = y2(1) / (lanes[d.lane].activist.length)*idx; return y2(d.lane)+(increments) })
|
|
.attr("width", function(d) {return x(d.end) - x(d.start);})
|
|
.attr("height", 1);
|
|
|
|
mini.append("g").selectAll("miniCircle")
|
|
.data(items)
|
|
.enter().append("circle")
|
|
.attr("class", function(d) {return "markers";})
|
|
.attr("cx", function(d) {return x(d.start);})
|
|
/*.attr("y", function(d, i) {let l1 = d.lane+1; let increments = (y2(l1)-y2(d.lane)) / (lanes[d.lane].activist.length)*i; return y2(d.lane)+increments;})*/
|
|
.attr("cy", function(d){ let idx = lanes[d.lane].activist.indexOf(d); let increments = y2(1) / (lanes[d.lane].activist.length)*idx; return y2(d.lane)+(increments) })
|
|
.attr("r", 1);
|
|
|
|
|
|
|
|
//mini labels
|
|
/*mini.append("g").selectAll(".miniLabels")
|
|
.data(items)
|
|
.enter().append("text")
|
|
.text(function(d) {return d.id;})
|
|
.attr("x", function(d) {return x(d.start);})
|
|
.attr("y", function(d, i) { let l1 = d.lane+1; let increments = (y2(l1)-y2(d.lane)) / (lanes[d.lane].activist.length)*i; return y2(d.lane)+increments;})
|
|
.attr("dy", ".5ex");
|
|
*/
|
|
|
|
// data interaction
|
|
$("body").on("mouseover", ".label_info", function(){
|
|
let id = $(this).data("id");
|
|
let elem = $("body").find('.miniItem[data-id="'+id+'"]');
|
|
let c = $("body").find('.miniCircle[data-id="'+id+'"]');
|
|
let y = parseFloat(elem.attr("y"))-10;
|
|
elem.css({
|
|
"y" :y,
|
|
"height": "25px",
|
|
"fill": 'black'
|
|
});
|
|
/*c.css({
|
|
"r" : "13px",
|
|
"fill": 'black'
|
|
});*/
|
|
$(this).css({
|
|
"font" : "15px sans-serif",
|
|
"fill": '#e94d1a'
|
|
});
|
|
});
|
|
|
|
$("body").on("mouseleave", ".label_info", function(){
|
|
let id = $(this).data("id");
|
|
let elem = $("body").find('.miniItem[data-id="'+id+'"]');
|
|
let c = $("body").find('.miniCircle[data-id="'+id+'"]');
|
|
let y = parseFloat(elem.attr("y"));
|
|
elem.css({
|
|
"y" :y,
|
|
"height" : "10px",
|
|
"fill": '#e94d1a'
|
|
});
|
|
/*c.css({
|
|
"r" : "5px",
|
|
"fill": '#e94d1a'
|
|
});*/
|
|
$(this).css({
|
|
"font" : "10px sans-serif",
|
|
"fill": 'black'
|
|
})
|
|
});
|
|
|
|
$("body").on("mouseover", ".miniItem", function(){
|
|
let id = $(this).data("id");
|
|
let elem = $("body").find('.label_info[data-id="'+id+'"]');
|
|
let c = $("body").find('.miniCircle[data-id="'+id+'"]');
|
|
let y = parseFloat($(this).attr("y"))-10;
|
|
elem.css({
|
|
"font" : "15px sans-serif",
|
|
"fill": '#e94d1a'
|
|
});
|
|
/*c.css({
|
|
"r" : "13px",
|
|
"fill": 'black'
|
|
});*/
|
|
$(this).css({
|
|
"y" :y,
|
|
"height": "25px",
|
|
"fill": 'black'
|
|
});
|
|
});
|
|
|
|
$("body").on("mouseleave", ".miniItem", function(){
|
|
let id = $(this).data("id");
|
|
let elem = $("body").find('.label_info[data-id="'+id+'"]');
|
|
let c = $("body").find('.miniCircle[data-id="'+id+'"]');
|
|
let y = parseFloat($(this).attr("y"));
|
|
elem.css({
|
|
"font" : "10px sans-serif",
|
|
"fill": 'black'
|
|
});
|
|
/*c.css({
|
|
"r" : "5px",
|
|
"fill": '#e94d1a'
|
|
});*/
|
|
$(this).css({
|
|
"y" :y,
|
|
"height" : "10px",
|
|
"fill": '#e94d1a'
|
|
})
|
|
});
|
|
|
|
// brush function
|
|
/*const brush = d3.brushX().on('brush', handleBrush);
|
|
|
|
|
|
initBrush();*/
|
|
// mini.select(".brush")
|
|
// .call(brush.extent([[0, 0], [w, miniHeight]]));
|
|
// Selecting SVG element
|
|
/*mini.call(d3.brush().move, [[0, 0], [w, miniHeight]])*/
|
|
/*function initBrush() {
|
|
mini.append("g")
|
|
.attr("class", "brush")
|
|
.call(brush.extent([[0, 0], [w, miniHeight]]));
|
|
|
|
}*/
|
|
// brush old
|
|
var brush = d3.brushX()
|
|
.on("brush", handleBrush)
|
|
|
|
mini.append("g")
|
|
.attr("class", "brush")
|
|
.call(brush.extent([[0, 0], [w, miniHeight]]));
|
|
|
|
handleBrush();
|
|
|
|
function handleBrush() {
|
|
|
|
var minExtent = d3.brushSelection(this) == null ? 0 : d3.brushSelection(this)[0] ;
|
|
var maxExtent = d3.brushSelection(this) == null ? w : d3.brushSelection(this)[1] ;
|
|
|
|
|
|
var rects, points, labels,
|
|
visItems = items.filter(function(d) {return x(d.start) < maxExtent && x(d.end) > minExtent;});
|
|
|
|
vislanes = lanes.filter(function(d) {return x(d.start) < maxExtent && x(d.end) > minExtent;});
|
|
|
|
var checkable = [];
|
|
visItems.forEach(function(e){ checkable.push(e.id)});
|
|
vislanes.forEach(function(e){
|
|
e.activist.forEach(function(d){
|
|
|
|
if(checkable.includes(d.id) == false){
|
|
//console.log(d.id);
|
|
const index = e.activist.indexOf(d);
|
|
if (index == -1) {
|
|
e.activist.splice(index, 1);
|
|
}
|
|
}
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
/* */
|
|
|
|
x1.domain([revert_x(minExtent), revert_x(maxExtent)]);
|
|
|
|
//update main item rects
|
|
rects = itemRects.selectAll("rect")
|
|
.data(visItems, function(d) { return d.id; })
|
|
.attr("x", function(d) {return x1(d.start);})
|
|
.attr("width", function(d) {return x1(d.end) - x1(d.start);});
|
|
|
|
rects.enter().append("rect")
|
|
.attr("class", function(d) {return "miniItem";})
|
|
.attr('data-id',function(d,i) {return i+'-'+d.lane+'_'+d.id;} )
|
|
.attr('data-ref',function(d,i) {return d.pos+'_'+d.id.replace(/\s/g, '');} )
|
|
.attr("x", function(d) {return x1(d.start);})
|
|
.attr("y", function(d) {
|
|
let idx = lanes[d.lane].activist.indexOf(d);
|
|
let increments = ( lineHeight_array[d.lane]-15) / (lanes[d.lane].activist.length)*idx;
|
|
|
|
|
|
return sumArray(lineHeight_array, d.lane, true)+(increments)+7
|
|
|
|
})
|
|
.attr("width", function(d) {return x1(d.end) - x1(d.start);})
|
|
.attr("height", function(d) {return 10;});
|
|
|
|
|
|
rects.exit().remove();
|
|
|
|
//axis
|
|
const bigAxis = d3.scaleLinear()
|
|
.domain([revert_x(minExtent), revert_x(maxExtent)])
|
|
.range([0, w]);
|
|
|
|
let t2 =new Date(revert_x(maxExtent));
|
|
let t1 =new Date(revert_x(minExtent));
|
|
axisMain.attr("transform", "translate(0," + (mainHeight - 50) +")")
|
|
.call(d3.axisBottom(bigAxis).ticks(t2.getFullYear()-t1.getFullYear()).tickFormat(d3.timeFormat('%Y')))
|
|
.selectAll("text")
|
|
/*.attr("transform", "translate(-10,10)rotate(-45)")*/
|
|
.style("text-anchor", "center")
|
|
.style("font-size", 20)
|
|
.style("fill", "black");
|
|
|
|
axisMain.exit().remove();
|
|
|
|
|
|
//update the item labels
|
|
labels = itemRects.selectAll("text")
|
|
.data(visItems, function (d) { return d.id; })
|
|
.attr("x", function(d) {return x1(Math.max(d.start, revert_x(minExtent) + 2))+10;});
|
|
|
|
labels.enter().append("text")
|
|
.text(function(d) {return d.id;})
|
|
.attr('class', 'label_info')
|
|
.attr('data-id',function(d,i) {return i+'-'+d.lane+'_'+d.id;} )
|
|
.attr('data-ref',function(d,i) {return d.pos+'_'+d.id.replace(/\s/g, '');} )
|
|
.attr("x", function(d) {return x1(Math.max(d.start, revert_x(minExtent)));})
|
|
.attr("y", function(d) {
|
|
let idx = lanes[d.lane].activist.indexOf(d);
|
|
let increments = (lineHeight_array[d.lane]-15) / (lanes[d.lane].activist.length)*idx;
|
|
|
|
return sumArray(lineHeight_array, d.lane, true)+(increments)+15
|
|
|
|
})
|
|
.attr("text-anchor", "start");
|
|
|
|
labels.exit().remove();
|
|
//circles
|
|
ccs = itemCircles.selectAll("circle")
|
|
.data(visItems, function(d) { return d.id; })
|
|
.attr("cx", function(d) {return x1(Math.max(d.start, revert_x(minExtent)));});
|
|
/*.attr("width", function(d) {return x1(d.end) - x1(d.start);});*/
|
|
|
|
ccs.enter().append("circle")
|
|
.attr("class", function(d) {return "miniCircle";})
|
|
.attr('data-id',function(d,i) {return i+'-'+d.lane+'_'+d.id;} )
|
|
.attr("cx", function(d) {return x1(Math.max(d.start, revert_x(minExtent)))-7;})
|
|
.attr("cy", function(d) {
|
|
let idx = lanes[d.lane].activist.indexOf(d);
|
|
let increments = (( lineHeight_array[d.lane] -15 ) / (lanes[d.lane].activist.length))*idx;
|
|
|
|
|
|
return sumArray(lineHeight_array, d.lane, true)+(increments)+12
|
|
|
|
})
|
|
.attr("r", function(d,i) {
|
|
let id = i+'-'+d.lane+'_'+d.id;
|
|
let itemw = $("body").find('.miniItem[data-id="'+id+'"]').attr("width");
|
|
let lbw = $("body").find('.label_info[data-id="'+id+'"]')[0].getBoundingClientRect().width;
|
|
|
|
if (lbw > itemw && itemw < 8 ) {
|
|
return 5;
|
|
}else{
|
|
return 0;
|
|
}
|
|
|
|
|
|
});
|
|
ccs.exit().remove();
|
|
//redraw coa lane
|
|
coa = itemCoa.selectAll("rect")
|
|
.data(lanes)
|
|
.attr("x", function(d) {return x1(d.start);})
|
|
.attr("width", function(d) {return x1(d.end) - x1(d.start);});
|
|
|
|
coa.enter().append("rect")
|
|
.attr("class", "coalition")
|
|
.attr("x", function(d) {return x1(d.start);})
|
|
.attr("y", function(d, i ) {return sumArray(lineHeight_array, i, true)+5;})
|
|
.attr("height", function(d, i) {return lineHeight_array[i]-10;})
|
|
.attr("width", function(d) {return x1(d.end) - x1(d.start);})
|
|
.attr("pos", function(d) {return d.lane });
|
|
|
|
coa.exit().remove();
|
|
|
|
labelcoa = itemCoa.selectAll("text")
|
|
.data(lanes)
|
|
.attr("x", function(d) {return x1(Math.max(d.start, revert_x(minExtent)))+20;});
|
|
|
|
|
|
labelcoa.enter().append("text")
|
|
.text(function(d) {return d.coa_name})
|
|
.attr('class', 'coa_name')
|
|
.attr('fill','white')
|
|
.attr("y", function(d, i ) {return sumArray(lineHeight_array, i, true)+lineHeight_array[i]/2+10;})
|
|
|
|
|
|
labelcoa.exit().remove();
|
|
|
|
}
|
|
|
|
function sumArray(array, to, strict){
|
|
let s = 0;
|
|
if (to == null) {
|
|
array.forEach(function(e){
|
|
s = s+e;
|
|
});
|
|
}else{
|
|
if (strict == false || strict == null) {
|
|
for (var i = 0; i <= to; i++) {
|
|
s = s+array[i];
|
|
}
|
|
}else{
|
|
for (var i = 0; i < to; i++) {
|
|
s = s+array[i];
|
|
}
|
|
}
|
|
}
|
|
return s;
|
|
}
|
|
|
|
} |