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