const visitData = { title: "What Canadian Heritage Spent on Previous Royal Tours (2010–2022)", notes: "*Preliminary figure, which will be finalized in March 2023. These costs do not include those incurred by other government departments.", data: [ { dates: "May 17 to 19, 2022", visitors: "Prince of Wales and Duchess of Cornwall", cost: 509_714, notes: true, }, { dates: "June 29 to July 1, 2017", visitors: "Prince of Wales and Duchess of Cornwall", cost: 487_660, }, { dates: "Sept. 24 to Oct. 1, 2016", visitors: "Duke and Duchess of Cambridge, Prince George and Princess Charlotte of Cambridge", cost: 611_000, }, { dates: "Nov. 10 to 11, 2014", visitors: "Her Royal Highness The Princess Royal", cost: 128_000, }, { dates: "May 18 to 21, 2014", visitors: "Prince of Wales and Duchess of Cornwall", cost: 650_500, }, { dates: "May 20 to 23, 2012", visitors: "Prince of Wales and Duchess of Cornwall", cost: 700_000, }, { dates: "June 30 to July 8, 2011", visitors: "Duke and Duchess of Cambridge", cost: 1_200_000, }, { dates: "June 28 to July 6, 2010", visitors: "Her Majesty The Queen and The Duke of Edinburgh", cost: 2_790_000, }, ], }; const totalData = { title: "Royal Tour Spending Breakdown (2022)", totalTitle: "Preliminary Total", notes: "*Preliminary figure, which will be finalized in March 2023. These costs do not include those incurred by provinces, territories or other police forces.", data: [ { visitors: "National Defence", cost: 568_000, }, { visitors: "Canadian Heritage", cost: 509_714, notes: true, }, { visitors: "Royal Canadian Mounted Police", cost: 361_331, }, ], }; const makeChart = (container, data) => { const maxCost = d3.max(data.data, (d) => d.cost); const totalCost = d3.sum(data.data, (d) => d.cost); container.data([data]); // Chart Title container .append("div") .attr("class", "visits-title") .text((d) => d.title); const body = container.append("div").attr("class", "visits-body"); const visits = body .selectAll("div.visit") .data((d) => d.data) .join("div") .attr("class", "visit"); // Visits Title Container const visitorsContainer = visits .selectAll("div.visitors-container") .data((d) => [d]) .join("div") .attr("class", "visitors-container"); const visitors = visitorsContainer .selectAll("div.visitors") .data((d) => [d]) .join("div") .attr("class", "visitors") .text((d) => d.visitors); visitors .selectAll("span.dates") .data((d) => [d]) .join("span") .attr("class", "dates") .classed("hidden", (d) => !d.dates) .text((d) => `(${d.dates})`); // Visits Bar Container const visitorsBarContainer = visits .selectAll("div.visitors-bar-container") .data((d) => [d]) .join("div") .attr("class", "visitors-bar-container"); const visitorsBar = visitorsBarContainer .selectAll("div.visitors-bar") .data((d) => [d]) .join("div") .attr("class", "visitors-bar") .style("width", (d) => `${(100 * d.cost) / maxCost}%`); const visitorsCost = visitorsBarContainer .selectAll("div.visitors-cost") .data((d) => [d]) .join("div") .attr("class", "visitors-cost") .text((d) => `$${d.cost.toLocaleString()}${d.notes ? "*" : ""}`); // Chart Total container .append("div") .attr("class", "visits-total") .text( (d) => `${ d.totalTitle ? d.totalTitle : "Total" }: $${totalCost.toLocaleString()}` ); // Chart Notes container .append("div") .attr("class", "visits-notes") .text((d) => d.notes); const resize = () => { visits.each(function (d, i, arr) { const container = d3.select(arr[i]); const bar = container.select(".visitors-bar"); const barWidth = bar.node().offsetWidth; const cost = container.select(".visitors-cost"); const costWidth = cost.node().offsetWidth; cost.style( "left", costWidth + 10 > barWidth ? barWidth + "px" : 0 + "px" ); cost.classed("outside", costWidth + 10 > barWidth); }); }; resize(); d3.select(window).on("resize", resize); }; makeChart(d3.select(".heritage.visits-container"), visitData); makeChart(d3.select(".totals.visits-container"), totalData);