let squareChartContainer = d3.select('#covid-canada-square-chart'); let squareChartSVG = squareChartContainer.append('svg') .attr('width', '100%') .attr('viewBox', '0 0 750 80') let squareChart100Layer = squareChartSVG.append('rect').attr('width', '100%').attr('height', '100%').attr('fill', '#fff') let squareChartLayer = squareChartSVG.append('g') .attr('class', 'chart-layer') let squareChartTextLayer = squareChartSVG.append('g') .attr('class', 'text-layer') let squareChartWordLayer = squareChartTextLayer.append('g') let squareChartNumberLayer = squareChartTextLayer.append('g').attr('class','square-words') function createSquareChart(squareData) { let dataArray = []; Object.keys(squareData).forEach(key => { if (key === 'active' || key === 'recovered' || key === 'deaths') { dataArray.push({ status: key, number: squareData[key] }) } }) let obj = dataArray.find(o => o.status === 'active') obj.number -= BC_FACTOR numberArray = []; dataArray.forEach(data => numberArray.push(data.number)) let max = numberArray.reduce((a, b) => a + b, 0) let scale = d3.scaleLinear() .domain([1, Math.max(1, max)]) .range([0, 750]) statusArray = []; dataArray.forEach(data => statusArray.push(data.status)) let colorScale = d3.scaleOrdinal().domain(statusArray) .range(["#1C8FA9", "#E07E2E", '#535353']) .unknown("#d3d3d3"); let areaColorScale = d3.scaleOrdinal().domain(colorCategories).range(areaColors); let lineColorScale = d3.scaleOrdinal().domain(colorCategories).range(lineColors); let dotColorScale = d3.scaleOrdinal().domain(colorCategories).range(dotColors); let thing = squareChartLayer.selectAll('rect').data(dataArray); thing.enter().append('rect') .attr('x', (d, i, N) => { let w = 0; if (i > 0) { for (let j = i; j > 0; j--) { w += N[j-1].__data__.number; } } return scale(w); }) .attr('y', 1) .attr('fill', d => areaColorScale(d.status.trim())) //.attr('stroke', d => lineColorScale(d.status.trim())) //.attr('stroke-width', 2) .attr('shape-rendering', 'crispEdges') .attr('height', 32) .attr('width', (d, i, N) => { let w = 0; if (i > 0) { for (let j = i; j > 0; j--) { w += N[j-1].__data__.number; } } return scale(max-w); }) //squareChartTextLayer.attr('transform', `translate(0, ${50 + 35})`) let n = squareChartNumberLayer.selectAll('text').data(dataArray) n.enter().append('text') .html(d => { let status = ''; //console.log(d.status, d.cases) if (d.status === 'deaths' && d.cases !== 1) { status = 'deaths'; } else { status = d.status; } return `${d.number.toLocaleString()} ${status}` }) .attr('fill', d => colorScale(d)) .attr('y', 0) .attr('text-anchor', 'start') .attr('font-family', `'CTVSans-Bold','CTV Sans',Arial`) .attr('font-size', 30) .attr('fill', d=> colorScale(d.status.trim())) squareChartNumberLayer.selectAll('text') .attr('x', (d, i, N) => placeText(N, i)) squareChartNumberLayer .attr('transform', `translate(${(squareChart100Layer.node().getBBox().width-squareChartNumberLayer.node().getBBox().width)/2}, 68)`) } //////////////////////////// function updateSquareChart(squareData, provinceName=null) { dataArray = []; Object.keys(squareData).forEach(key => { if (key === 'active' || key === 'recovered' || key === 'deaths') { dataArray.push({ status: key, number: squareData[key] }) } }) ///LIKE AUTODATA, SUBTRACTING TO ACCOUNT FOR B.C. BOOKKEEPING if (provinceName === 'British Columbia' || provinceName === 'Canada') { let obj = dataArray.find(o => o.status === 'active') obj.number -= BC_FACTOR } numberArray = []; dataArray.forEach(data => numberArray.push(data.number)) let max = numberArray.reduce((a, b) => a + b, 0) let scale = d3.scaleLinear() .domain([0, Math.max(1, max)]) .range([0, 750]) statusArray = []; dataArray.forEach(data => statusArray.push(data.status)) let colorScale = d3.scaleOrdinal().domain(statusArray) .range(["#1C8FA9", "#E07E2E", '#535353']) .unknown("#d3d3d3"); let thing = squareChartLayer.selectAll('rect').data(dataArray); thing.transition().duration(1000) .attr('x', (d, i, N) => { let w = 0; if (i > 0) { for (let j = i; j > 0; j--) { w += N[j-1].__data__.number; } } return scale(w); }) .attr('width', (d, i, N) => { let w = 0; if (i > 0) { for (let j = i; j > 0; j--) { w += N[j-1].__data__.number; } } return scale(max-w); }) //squareChartTextLayer.attr('transform', `translate(0, ${50 + 35})`) let n = squareChartNumberLayer.selectAll('text').data(dataArray) n .html(d => { let status = ''; //console.log(d.status, d.cases) if (d.status === 'deaths' && d.cases !== 1) { status = 'deaths'; } else { status = d.status; } return `${d.number.toLocaleString()} ${status}` }) .attr('fill', d => colorScale(d)) .attr('y', 0) .attr('text-anchor', 'start') .attr('font-family', `'CTVSans-Bold','CTV Sans',Arial`) .attr('font-size', 30) .attr('fill', d=> colorScale(d.status.trim())) squareChartNumberLayer.selectAll('text') //.transition().duration(1000) .attr('x', (d, i, N) => placeText(N, i)) squareChartNumberLayer //.transition().duration(1000) .attr('transform', `translate(${(squareChart100Layer.node().getBBox().width-squareChartNumberLayer.node().getBBox().width)/2}, 68)`) } function placeText(N, i) { let L = 0; for (let j = i; j > 0; j--) { L += N[j-1].getComputedTextLength() + 50; } return L }