Files
2023-07-18 10:47:46 +01:00

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;
}
}