Advertisement
NTahmid

bar_chart_pointwise_comparison_v3

Mar 25th, 2024
761
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 7.16 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <meta charset="utf-8">
  3.  
  4. <style>
  5.   /*hides tick marks on bottom xaxis */
  6.   .axis line {
  7.     visibility: hidden;
  8.   }
  9.  
  10.   /* hides bottom xaxis line*/
  11.   .axis .domain {
  12.     display: none;
  13.   }
  14.  
  15.   .axis {
  16.     font: 13px sans-serif;
  17.   }
  18.  
  19.   .yUnits {
  20.     font: 14px sans-serif;
  21.   }
  22.  
  23.   .caption {
  24.     font: 12px sans-serif;
  25.   }
  26.  
  27.   .chartDisplayTitle {
  28.     fill: #354B5F;
  29.     font-weight: bold;
  30.     font: 20px sans-serif;
  31.   }
  32.  
  33.   .annotation-connector {
  34.     stroke: #c86984;
  35.     stroke-width: 2;
  36.   }
  37.  
  38.   .annotation-circle {
  39.     fill: none;
  40.     stroke: #c86984;
  41.     stroke-width: 2;
  42.   }
  43.  
  44.   .annotation-text {
  45.     fill: #c86984;
  46.     font-size: 14px;
  47.   }
  48. </style>
  49.  
  50. <svg class="chart" width="960" height="590" aria-labelledby="graph-title" aria-describedby="graph-desc">
  51.   <title>GDP Growth Remains Broad Based</title>
  52.   <desc id="graph-desc">GDP Growth Remains Broad Based, with values for 2017 quarters 1-3.</desc>
  53.   <text transform="translate(10, 20)" class="chartDisplayTitle">Chart1</text>
  54.   <text id="graph-title" transform="translate(10, 45)" class="chartDisplayTitle">GDP Growth Remains Broad Based</text>
  55.   <text transform="translate(10, 70)" class="yUnits">Percentage points*</text>
  56.   <text transform="translate(10, 570)" class="caption">*Contribution to total gross domestic product (GDP) growth; seasonally adjusted annualized rate.</text>
  57.   <text transform="translate(10, 585)" class="caption">SOURCE: Bureau of Economic Analysis.</text>
  58. </svg>
  59. <script src="https://d3js.org/d3.v4.min.js"></script>
  60. <script>
  61.   var econ2 = [
  62.     {
  63.       "Category": "GDP",
  64.       "2017 Q1": 1.2,
  65.       "2017 Q2": 3.1,
  66.       "2017 Q3 First Estimate": 3.0
  67.     },
  68.     {
  69.       "Category": "Consumption",
  70.       "2017 Q1": 1.3,
  71.       "2017 Q2": 2.2,
  72.       "2017 Q3 First Estimate": 1.6
  73.     },
  74.     {
  75.       "Category": "Nonresidential investment",
  76.       "2017 Q1": 0.9,
  77.       "2017 Q2": 0.8,
  78.       "2017 Q3 First Estimate": 0.5
  79.     },
  80.     {
  81.       "Category": "Residential investment",
  82.       "2017 Q1": 0.4,
  83.       "2017 Q2": -0.3,
  84.       "2017 Q3 First Estimate": -0.2
  85.     },
  86.     {
  87.       "Category": "Inventories",
  88.       "2017 Q1": -1.5,
  89.       "2017 Q2": 0.1,
  90.       "2017 Q3 First Estimate": 0.7
  91.     },
  92.     {
  93.       "Category": "Net exports",
  94.       "2017 Q1": 0.2,
  95.       "2017 Q2": 0.2,
  96.       "2017 Q3 First Estimate": 0.4
  97.     },
  98.     {
  99.       "Category": "Government",
  100.       "2017 Q1": -0.1,
  101.       "2017 Q2": 0.0,
  102.       "2017 Q3 First Estimate": 0.0
  103.     }
  104.   ]
  105.  
  106.   var svg = d3.select("svg"),
  107.       margin = {top: 80, right: 10, bottom: 80, left: 25},
  108.       width = svg.attr("width") - margin.left - margin.right,
  109.       height = svg.attr("height") - margin.top - margin.bottom,
  110.       g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
  111.  
  112.   var y = d3.scaleLinear()
  113.         .domain([-2, 4])
  114.         .range([height, 0]);
  115.  
  116.   var x0 = d3.scaleBand()
  117.         .rangeRound([0, width])
  118.         .paddingInner(0.1)
  119.         .paddingOuter(0.1);
  120.  
  121.   var x1 = d3.scaleBand()
  122.       .paddingOuter(0.25)
  123.       .paddingInner(0.15);
  124.  
  125.   var z = d3.scaleOrdinal()
  126.           .range(["#BC151E", "#D3B178", "#354B5F"]);
  127.  
  128.   const yAxis = d3.axisLeft(y).ticks(7);
  129.  
  130.   var subCategories = Object.keys(econ2[0]).slice(1);
  131.  
  132.   x0.domain(econ2.map(d => d.Category));
  133.   x1.domain(subCategories).rangeRound([0, x0.bandwidth()])
  134.  
  135.   var selection = g.selectAll("g")
  136.     .data(econ2)
  137.     .enter().append("g")
  138.       .attr("transform", d => "translate(" + x0(d.Category) + ",0)")
  139.     selection.selectAll("rect")
  140.      .data(function(d) { return subCategories.map(function(key) { return {key: key, value: d[key]}; }); })
  141.       .enter().append("rect")
  142.       .attr("x", d => x1(d.key))
  143.       .attr("y", d => (d.value<0 ? y(0) : y(d.value)))
  144.      .attr("width", x1.bandwidth())
  145.      .attr("height", d => Math.abs(y(d.value) - y(0)))
  146.       .attr("fill", d => z(d.key))
  147.     selection.selectAll("text")
  148.        .data(function(d) { return subCategories.map(function(key) { return {key: key, value: d[key]}; }); })
  149.         .enter().append("text")
  150.         .attr("x", d => x1(d.key))
  151.         .attr("y", d => d.value<=0 ? y(0) - (y(4) - (Math.abs(y(d.value) - y(0)) + 20)) : y(d.value) - 10)
  152.        .style('fill', d => z(d.key))
  153.         .style('font-size', '1.25em')
  154.         .text(d => Number.parseFloat(d.value).toFixed(1))
  155.  
  156.   g.append("g")
  157.       .attr("class", "axis")
  158.       .attr("transform", "translate(0," + height + ")")
  159.       .call(d3.axisBottom(x0))
  160.       .selectAll(".tick text")
  161.       .call(wrap, x0.bandwidth());
  162.  
  163.   g.append('g')
  164.   .call(yAxis)
  165.  
  166.   g.append("line")
  167.       .attr("y1", y(0))
  168.       .attr("y2", y(0))
  169.       .attr("x1", 0)
  170.       .attr("x2", width)
  171.       .attr("stroke", "black");
  172.  
  173.   var legend = g.append("g")
  174.         .attr("font-family", "sans-serif")
  175.         .attr("font-size", 13)
  176.         .attr("text-anchor", "end")
  177.       .selectAll("g")
  178.       .data(subCategories)
  179.       .enter().append("g")
  180.         .attr("transform", function(d, i) { return "translate(0," + i * 24 + ")"; });
  181.     legend.append("rect")
  182.         .attr("x", width - 142)
  183.         .attr("width", 8)
  184.         .attr("height", 8)
  185.         .attr("fill", z);
  186.     legend.append("text")
  187.             .attr("x", d => d.length > 7 ? (width + 5) : (width - 80))
  188.             .attr("y", 5.5)
  189.             .attr("dy", "0.22em")
  190.             .text(d => (d));
  191.  
  192.   function wrap(text, width) {
  193.               text.each(function() {
  194.                 var text = d3.select(this),
  195.                     words = text.text().split(/\s+/).reverse(),
  196.                     word,
  197.                     line = [],
  198.                     lineNumber = 0,
  199.                     lineHeight = 1.1, // ems
  200.                     y = text.attr("y"),
  201.                     dy = parseFloat(text.attr("dy")),
  202.                     tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
  203.                 while (word = words.pop()) {
  204.                   line.push(word);
  205.                   tspan.text(line.join(" "));
  206.                   if (tspan.node().getComputedTextLength() > width) {
  207.                     line.pop();
  208.                     tspan.text(line.join(" "));
  209.                     line = [word];
  210.                     tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
  211.                   }
  212.                 }
  213.               });
  214.             }
  215.  
  216.   // Annotations
  217.   // Connector for Consumption Q1 to Q2
  218.   g.append("line")
  219.     .attr("x1", x0("Consumption") + x1("2017 Q1") + x1.bandwidth() / 2)
  220.     .attr("y1", y(1.3))
  221.     .attr("x2", x0("Consumption") + x1("2017 Q2") + x1.bandwidth() / 2)
  222.     .attr("y2", y(2.2))
  223.     .attr("class", "annotation-connector");
  224.  
  225.   // Circle around Consumption Q2
  226.   g.append("circle")
  227.     .attr("cx", x0("Consumption") + x1("2017 Q2") + x1.bandwidth() / 2)
  228.     .attr("cy", y(2.2))
  229.     .attr("r", 15)
  230.     .attr("class", "annotation-circle");
  231.  
  232.   // Text for Consumption Q2
  233.   g.append("text")
  234.     .attr("x", x0("Consumption") + x1("2017 Q2") + x1.bandwidth() / 2 + 20)
  235.     .attr("y", y(2.2) + 5)
  236.     .attr("class", "annotation-text")
  237.     .text("Q2 Increase");
  238.  
  239. </script>
  240. ```
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement