Гистограммы с накоплением D3 с использованием функции d3.stack () - PullRequest
0 голосов
/ 17 декабря 2018

Я пытаюсь создать гистограмму с помощью ползунка временной шкалы, содержащего только годы.Каждый раз, когда изменяется ползунок, данные фильтруются соответствующим образом.

На данный момент столбцы показывают сумму по каждой категории.

Я хочу, чтобы столбцы были сложены с использованием столбцов no_arrest и arrest, но у меня возникают проблемы с функцией d3.stack().

Мой код на данный момент:

<!DOCTYPE html>
<html lang="en">
<head>
  <style>
  #chart {
    height: 450px;
    width: 1000px;
    margin: 0;
  }
  div.tooltip {
    position: absolute;
    text-align: center;
    width: 30px;
    height: 15px;
    padding: 2px;
    font: 12px sans-serif;
    background: lightsteelblue;
    border: 10px;
    border-radius: 8px;
    pointer-events: none;
  }
  </style>
</head>
<body>
<div>
<div id="slider"></div>
<svg id="chart" width="750" height="300"></svg>
</div>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://unpkg.com/d3-simple-slider/build/d3-simple-slider.js"></script>
<script>
  // Load data files
  d3.csv("subcrimes.csv").then(d => chart(d));
  // d3.csv('subcrimes.csv').then(d => subchart(d));

  function chart(csv) {

    csv.forEach(function(d) {
        d.crime = d.crime;
      d.subcrime = d.subcrime;
        d.value = +d.total; //+ +d.no_arrest;
      d.year = +d.year;
      d.arrest = +d.arrest;
      d.no_arrest = +d.no_arrest;
        return d;
    })

    var years = [...new Set(csv.map(d => d.year))];
    var keys = ['arrest','no_arrest']

    // // Define the div for the tooltip
    var div = d3.select("body").append("div")
        .attr("class", "tooltip")
        .style("opacity", 0);

    var svg = d3.select("#chart"),
        margin = {top: 25, bottom: -50, left: 70, right: 25},
        width = +svg.attr("width") - margin.left - margin.right,
        height = +svg.attr("height") - margin.top - margin.bottom;

    var x = d3.scaleBand()
        .range([margin.left, width - margin.right])
        .padding(0.1)
        .paddingOuter(0.2)

    var y = d3.scaleLinear()
        .range([height - margin.bottom, margin.top])

    var z = d3.scaleOrdinal()
        .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

    // var colour_scale = d3.scaleQuantile()
    // // // .range(["#ffffe5", "#fff7bc", "#fee391", "#fec44f", "#fe9929", "#ec7014", "#cc4c02", "#993404", "#662506"]);
    //   .range(["#5E4FA2", "#3288BD", "#66C2A5", "#ABDDA4", "#E6F598",
    //   "#FFFFBF", "#FEE08B", "#FDAE61", "#F46D43", "#D53E4F", "#9E0142"]);

    var xAxis = g => g
        .attr("transform", "translate(0," + (height - margin.bottom) + ")")
        .call(d3.axisBottom(x).tickSizeOuter(0))

    var yAxis = g => g
        .attr("transform", "translate(" + margin.left + ",0)")
        .call(d3.axisLeft(y))

    svg.append("g")
        .attr("class", "x-axis")

    svg.append("g")
        .attr("class", "y-axis")
    //console.log(d3.stack().keys(keys)(data));

    update(slider.value(), 'ARSON', 0)

    function update(year, crime, speed) {

        var dat = csv.filter(f => f.year == year)
      var data = dat.filter(f => f.crime == crime)

      x.domain(data.map(d => d.subcrime))
        y.domain([0, d3.max(data, d => d.value)]).nice()
      z.domain(keys);
      // colour_scale.domain([0, d3.max(data, d => d.value)])
      // console.log(d3.max(data, d => d.value));

        // data.sort(d3.select("#sort").property("checked")
        //  ? (a, b) => b.value - a.value
        //  : (a, b) => crimes.indexOf(a.subcrime) - crimes.indexOf(b.subcrime))

        svg.selectAll(".x-axis").transition().duration(speed)
            .call(xAxis)
        .selectAll("text")
          .style("text-anchor", "end")
          .attr("dx", "-.5em")
          .attr("dy", "-.9em")
          .attr("transform", function(d) {
              return "rotate(-65)"
            });

      svg.selectAll(".y-axis").transition().duration(speed)
            .call(yAxis);

        var bar = svg.selectAll(".bar")
            .data(data, d => d.subcrime)

        bar.exit().remove();

        bar.enter().append("rect")
            .attr("class", "bar")
            .attr("fill", 'steelblue') //function(d) { return z(d.key); }
        // .attr('hover', 'red')
            .attr("width", x.bandwidth())
            .merge(bar)
        .on("mouseenter", function(d) {
          // d3.selectAll('.value')
          //   .attr('opacity', 0.6)
          d3.select(this)
            .attr('opacity', 0.6)
          div.transition()
            .duration(200)
            .style("opacity", .9);
          div.html((d.value))
            .style("left", (d3.event.pageX) + "px")
            .style("top", (d3.event.pageY - 28) + "px");
          })
        .on('mouseleave', function () {
          d3.select(this)
            .attr('opacity', 1)
          })
        // .on("mouseout", function(d) {
        //   div.transition()
        //     .duration(500)
        //     .style("opacity", 0);
        // })
          // .attr('fill', d => colour_scale(d.value))
        .transition().duration(speed)
            .attr("x", d => x(d.subcrime))
            .attr("y", d => y(d.value))
            .attr("height", d => y(0) - y(d.value))

    }
    chart.update = update;
  }

  var years = [2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018]

  var slider = d3.sliderHorizontal()
    .min(d3.min(years))
    .max(d3.max(years))
    .step(1)
    .width(500)
    .tickFormat(d3.format(''))
    .tickValues(years)
    .on('onchange', val => {
      d3.select("p#value").text(val);
        chart.update(val, 'ARSON', 750)
    });

  var group = d3.select("div#slider").append("svg")
    .attr("width", 650)
    .attr("height", 100)
    .append("g")
    .attr("transform", "translate(30,30)");

  group.call(slider);

  d3.select("p#value").text(slider.value());
  d3.select("a#setValue").on("click", () => { slider.value(2008); d3.event.preventDefault(); });
</script>
</body>
</html>

Файл моих данных:

crime,subcrime,year,total,no_arrest,arrest
ARSON,AGGRAVATED,2008,194,160,34
ARSON,AGGRAVATED,2009,160,136,24
ARSON,AGGRAVATED,2010,155,122,33
ARSON,AGGRAVATED,2011,74,60,14
ARSON,AGGRAVATED,2012,55,40,15
ARSON,AGGRAVATED,2013,51,40,11
ARSON,AGGRAVATED,2014,47,41,6
ARSON,AGGRAVATED,2015,77,56,21
ARSON,AGGRAVATED,2016,71,53,18
ARSON,AGGRAVATED,2017,56,43,13
ARSON,AGGRAVATED,2018,57,42,15
ARSON,ATTEMPT ARSON,2008,208,188,20
ARSON,ATTEMPT ARSON,2009,194,162,32
ARSON,ATTEMPT ARSON,2010,185,172,13
ARSON,ATTEMPT ARSON,2011,88,77,11
ARSON,ATTEMPT ARSON,2012,84,77,7
ARSON,ATTEMPT ARSON,2013,65,55,10
ARSON,ATTEMPT ARSON,2014,46,42,4
ARSON,ATTEMPT ARSON,2015,57,52,5
ARSON,ATTEMPT ARSON,2016,70,61,9
ARSON,ATTEMPT ARSON,2017,50,45,5
ARSON,ATTEMPT ARSON,2018,36,29,7
ARSON,BY EXPLOSIVE,2010,12,10,2
ARSON,BY EXPLOSIVE,2011,1,0,1
ARSON,BY FIRE,2008,842,792,50
ARSON,BY FIRE,2009,844,772,72
ARSON,BY FIRE,2010,641,570,71
ARSON,BY FIRE,2011,337,317,20
ARSON,BY FIRE,2012,323,300,23
ARSON,BY FIRE,2013,240,219,21
ARSON,BY FIRE,2014,291,271,20
ARSON,BY FIRE,2015,305,284,21
ARSON,BY FIRE,2016,355,340,15
ARSON,BY FIRE,2017,332,312,20
ARSON,BY FIRE,2018,246,241,5
ARSON,POS: CHEMICAL/DRY-ICE DEVICE,2008,12,8,4
ARSON,POS: CHEMICAL/DRY-ICE DEVICE,2009,8,4,4
ARSON,POS: CHEMICAL/DRY-ICE DEVICE,2010,1,0,1
ARSON,POS: CHEMICAL/DRY-ICE DEVICE,2012,1,0,1
ARSON,POS: EXPLOSIVE/INCENDIARY DEV,2008,14,4,10
ARSON,POS: EXPLOSIVE/INCENDIARY DEV,2009,10,4,6
ARSON,POS: EXPLOSIVE/INCENDIARY DEV,2010,16,8,8
ARSON,POS: EXPLOSIVE/INCENDIARY DEV,2011,5,3,2
ARSON,POS: EXPLOSIVE/INCENDIARY DEV,2013,6,2,4
ARSON,POS: EXPLOSIVE/INCENDIARY DEV,2014,2,0,2
ARSON,POS: EXPLOSIVE/INCENDIARY DEV,2015,5,4,1
ARSON,POS: EXPLOSIVE/INCENDIARY DEV,2016,4,3,1
ARSON,POS: EXPLOSIVE/INCENDIARY DEV,2017,3,2,1
ARSON,POS: EXPLOSIVE/INCENDIARY DEV,2018,1,0,1
ASSAULT,AGG PO HANDS NO/MIN INJURY,2008,796,190,606
ASSAULT,AGG PO HANDS NO/MIN INJURY,2009,1034,160,874
ASSAULT,AGG PO HANDS NO/MIN INJURY,2010,1073,177,896
ASSAULT,AGG PO HANDS NO/MIN INJURY,2011,528,42,486
ASSAULT,AGG PO HANDS NO/MIN INJURY,2012,520,60,460
ASSAULT,AGG PO HANDS NO/MIN INJURY,2013,468,49,419
ASSAULT,AGG PO HANDS NO/MIN INJURY,2014,472,38,434
ASSAULT,AGG PO HANDS NO/MIN INJURY,2015,415,40,375
ASSAULT,AGG PO HANDS NO/MIN INJURY,2016,270,35,235
ASSAULT,AGG PO HANDS NO/MIN INJURY,2017,245,24,221
ASSAULT,AGG PO HANDS NO/MIN INJURY,2018,211,39,172
ASSAULT,AGG PRO.EMP: HANDGUN,2008,48,32,16
ASSAULT,AGG PRO.EMP: HANDGUN,2009,44,24,20
ASSAULT,AGG PRO.EMP: HANDGUN,2010,31,23,8
ASSAULT,AGG PRO.EMP: HANDGUN,2011,26,18,8
ASSAULT,AGG PRO.EMP: HANDGUN,2012,11,4,7
ASSAULT,AGG PRO.EMP: HANDGUN,2013,13,4,9
ASSAULT,AGG PRO.EMP: HANDGUN,2014,22,14,8
ASSAULT,AGG PRO.EMP: HANDGUN,2015,15,13,2
ASSAULT,AGG PRO.EMP: HANDGUN,2016,29,15,14
ASSAULT,AGG PRO.EMP: HANDGUN,2017,40,27,13
ASSAULT,AGG PRO.EMP: HANDGUN,2018,32,23,9
ASSAULT,AGG PRO.EMP: OTHER DANG WEAPON,2008,158,108,50
ASSAULT,AGG PRO.EMP: OTHER DANG WEAPON,2009,162,92,70
ASSAULT,AGG PRO.EMP: OTHER DANG WEAPON,2010,119,74,45
ASSAULT,AGG PRO.EMP: OTHER DANG WEAPON,2011,83,45,38
ASSAULT,AGG PRO.EMP: OTHER DANG WEAPON,2012,25,12,13
ASSAULT,AGG PRO.EMP: OTHER DANG WEAPON,2013,22,14,8
ASSAULT,AGG PRO.EMP: OTHER DANG WEAPON,2014,39,21,18
ASSAULT,AGG PRO.EMP: OTHER DANG WEAPON,2015,45,26,19
ASSAULT,AGG PRO.EMP: OTHER DANG WEAPON,2016,39,25,14
ASSAULT,AGG PRO.EMP: OTHER DANG WEAPON,2017,48,32,16
ASSAULT,AGG PRO.EMP: OTHER DANG WEAPON,2018,71,43,28
ASSAULT,AGG PRO.EMP: OTHER FIREARM,2008,20,16,4
ASSAULT,AGG PRO.EMP: OTHER FIREARM,2009,12,8,4
ASSAULT,AGG PRO.EMP: OTHER FIREARM,2011,4,1,3
ASSAULT,AGG PRO.EMP: OTHER FIREARM,2014,4,1,3
ASSAULT,AGG PRO.EMP: OTHER FIREARM,2015,4,2,2
ASSAULT,AGG PRO.EMP: OTHER FIREARM,2016,2,1,1
ASSAULT,AGG PRO.EMP: OTHER FIREARM,2017,1,0,1
ASSAULT,AGG PRO.EMP:KNIFE/CUTTING INST,2008,60,34,26
ASSAULT,AGG PRO.EMP:KNIFE/CUTTING INST,2009,90,50,40
ASSAULT,AGG PRO.EMP:KNIFE/CUTTING INST,2010,79,45,34
ASSAULT,AGG PRO.EMP:KNIFE/CUTTING INST,2011,40,26,14
ASSAULT,AGG PRO.EMP:KNIFE/CUTTING INST,2012,24,14,10
ASSAULT,AGG PRO.EMP:KNIFE/CUTTING INST,2013,21,11,10
ASSAULT,AGG PRO.EMP:KNIFE/CUTTING INST,2014,28,16,12
ASSAULT,AGG PRO.EMP:KNIFE/CUTTING INST,2015,17,8,9
ASSAULT,AGG PRO.EMP:KNIFE/CUTTING INST,2016,39,21,18
ASSAULT,AGG PRO.EMP:KNIFE/CUTTING INST,2017,40,21,19
ASSAULT,AGG PRO.EMP:KNIFE/CUTTING INST,2018,47,30,17
ASSAULT,AGGRAVATED PO: HANDGUN,2008,154,60,94
ASSAULT,AGGRAVATED PO: HANDGUN,2009,156,34,122
ASSAULT,AGGRAVATED PO: HANDGUN,2010,116,31,85
ASSAULT,AGGRAVATED PO: HANDGUN,2011,78,19,59
ASSAULT,AGGRAVATED PO: HANDGUN,2012,68,17,51
ASSAULT,AGGRAVATED PO: HANDGUN,2013,38,13,25
ASSAULT,AGGRAVATED PO: HANDGUN,2014,58,21,37
ASSAULT,AGGRAVATED PO: HANDGUN,2015,54,16,38
ASSAULT,AGGRAVATED PO: HANDGUN,2016,57,27,30
ASSAULT,AGGRAVATED PO: HANDGUN,2017,37,18,19
ASSAULT,AGGRAVATED PO: HANDGUN,2018,35,16,19
ASSAULT,AGGRAVATED PO: OTHER DANG WEAP,2008,132,42,90
ASSAULT,AGGRAVATED PO: OTHER DANG WEAP,2009,216,52,164
ASSAULT,AGGRAVATED PO: OTHER DANG WEAP,2010,182,56,126
ASSAULT,AGGRAVATED PO: OTHER DANG WEAP,2011,111,32,79
ASSAULT,AGGRAVATED PO: OTHER DANG WEAP,2012,56,6,50
ASSAULT,AGGRAVATED PO: OTHER DANG WEAP,2013,62,17,45
ASSAULT,AGGRAVATED PO: OTHER DANG WEAP,2014,54,10,44
ASSAULT,AGGRAVATED PO: OTHER DANG WEAP,2015,72,17,55
ASSAULT,AGGRAVATED PO: OTHER DANG WEAP,2016,45,18,27
ASSAULT,AGGRAVATED PO: OTHER DANG WEAP,2017,65,25,40
ASSAULT,AGGRAVATED PO: OTHER DANG WEAP,2018,45,17,28
ASSAULT,AGGRAVATED PO: OTHER FIREARM,2008,10,0,10
ASSAULT,AGGRAVATED PO: OTHER FIREARM,2009,22,4,18
ASSAULT,AGGRAVATED PO: OTHER FIREARM,2010,14,6,8
ASSAULT,AGGRAVATED PO: OTHER FIREARM,2011,4,0,4
ASSAULT,AGGRAVATED PO: OTHER FIREARM,2012,4,2,2
ASSAULT,AGGRAVATED PO: OTHER FIREARM,2013,3,2,1
ASSAULT,AGGRAVATED PO: OTHER FIREARM,2014,3,2,1
ASSAULT,AGGRAVATED PO: OTHER FIREARM,2015,3,0,3
ASSAULT,AGGRAVATED PO: OTHER FIREARM,2016,2,1,1
ASSAULT,AGGRAVATED PO: OTHER FIREARM,2017,2,1,1
ASSAULT,AGGRAVATED PO: OTHER FIREARM,2018,2,1,1
ASSAULT,AGGRAVATED PO:KNIFE/CUT INSTR,2008,58,34,24
ASSAULT,AGGRAVATED PO:KNIFE/CUT INSTR,2009,94,50,44
ASSAULT,AGGRAVATED PO:KNIFE/CUT INSTR,2010,92,43,49
ASSAULT,AGGRAVATED PO:KNIFE/CUT INSTR,2011,49,21,28
ASSAULT,AGGRAVATED PO:KNIFE/CUT INSTR,2012,35,19,16
ASSAULT,AGGRAVATED PO:KNIFE/CUT INSTR,2013,31,16,15
ASSAULT,AGGRAVATED PO:KNIFE/CUT INSTR,2014,36,19,17
ASSAULT,AGGRAVATED PO:KNIFE/CUT INSTR,2015,28,13,15
ASSAULT,AGGRAVATED PO:KNIFE/CUT INSTR,2016,32,25,7
ASSAULT,AGGRAVATED PO:KNIFE/CUT INSTR,2017,26,16,10
ASSAULT,AGGRAVATED PO:KNIFE/CUT INSTR,2018,26,15,11
ASSAULT,AGGRAVATED: HANDGUN,2008,5166,3834,1332
ASSAULT,AGGRAVATED: HANDGUN,2009,4864,3608,1256
ASSAULT,AGGRAVATED: HANDGUN,2010,4066,2987,1079
ASSAULT,AGGRAVATED: HANDGUN,2011,2043,1495,548
ASSAULT,AGGRAVATED: HANDGUN,2012,2080,1482,598
ASSAULT,AGGRAVATED: HANDGUN,2013,1777,1299,478
ASSAULT,AGGRAVATED: HANDGUN,2014,1795,1331,464
ASSAULT,AGGRAVATED: HANDGUN,2015,1972,1508,464
ASSAULT,AGGRAVATED: HANDGUN,2016,2855,2357,498
ASSAULT,AGGRAVATED: HANDGUN,2017,2890,2371,519
ASSAULT,AGGRAVATED: HANDGUN,2018,2753,2281,472
ASSAULT,AGGRAVATED: OTHER DANG WEAPON,2008,2994,2120,874
ASSAULT,AGGRAVATED: OTHER DANG WEAPON,2009,2888,1964,924
ASSAULT,AGGRAVATED: OTHER DANG WEAPON,2010,2632,1909,723
ASSAULT,AGGRAVATED: OTHER DANG WEAPON,2011,1216,799,417
ASSAULT,AGGRAVATED: OTHER DANG WEAPON,2012,1088,769,319
ASSAULT,AGGRAVATED: OTHER DANG WEAPON,2013,907,639,268
ASSAULT,AGGRAVATED: OTHER DANG WEAPON,2014,918,611,307
ASSAULT,AGGRAVATED: OTHER DANG WEAPON,2015,948,673,275
ASSAULT,AGGRAVATED: OTHER DANG WEAPON,2016,1000,767,233
ASSAULT,AGGRAVATED: OTHER DANG WEAPON,2017,1088,845,243
ASSAULT,AGGRAVATED: OTHER DANG WEAPON,2018,1068,855,213
ASSAULT,AGGRAVATED: OTHER FIREARM,2008,216,122,94
ASSAULT,AGGRAVATED: OTHER FIREARM,2009,196,118,78
ASSAULT,AGGRAVATED: OTHER FIREARM,2010,163,99,64
ASSAULT,AGGRAVATED: OTHER FIREARM,2011,111,67,44
ASSAULT,AGGRAVATED: OTHER FIREARM,2012,87,47,40
ASSAULT,AGGRAVATED: OTHER FIREARM,2013,78,41,37
ASSAULT,AGGRAVATED: OTHER FIREARM,2014,74,36,38
ASSAULT,AGGRAVATED: OTHER FIREARM,2015,83,55,28
ASSAULT,AGGRAVATED: OTHER FIREARM,2016,101,75,26
ASSAULT,AGGRAVATED: OTHER FIREARM,2017,86,56,30
ASSAULT,AGGRAVATED: OTHER FIREARM,2018,94,70,24
ASSAULT,AGGRAVATED:KNIFE/CUTTING INSTR,2008,3424,2348,1076
ASSAULT,AGGRAVATED:KNIFE/CUTTING INSTR,2009,3126,1988,1138
ASSAULT,AGGRAVATED:KNIFE/CUTTING INSTR,2010,2568,1737,831
ASSAULT,AGGRAVATED:KNIFE/CUTTING INSTR,2011,1390,913,477
ASSAULT,AGGRAVATED:KNIFE/CUTTING INSTR,2012,1393,914,479
ASSAULT,AGGRAVATED:KNIFE/CUTTING INSTR,2013,1302,835,467
ASSAULT,AGGRAVATED:KNIFE/CUTTING INSTR,2014,1229,779,450
ASSAULT,AGGRAVATED:KNIFE/CUTTING INSTR,2015,1214,773,441
ASSAULT,AGGRAVATED:KNIFE/CUTTING INSTR,2016,1337,936,401
ASSAULT,AGGRAVATED:KNIFE/CUTTING INSTR,2017,1464,1027,437
ASSAULT,AGGRAVATED:KNIFE/CUTTING INSTR,2018,1475,1079,396
ASSAULT,PRO EMP HANDS NO/MIN INJURY,2008,2562,1598,964
ASSAULT,PRO EMP HANDS NO/MIN INJURY,2009,2062,1174,888
ASSAULT,PRO EMP HANDS NO/MIN INJURY,2010,1912,1131,781
ASSAULT,PRO EMP HANDS NO/MIN INJURY,2011,849,480,369
ASSAULT,PRO EMP HANDS NO/MIN INJURY,2012,679,425,254
ASSAULT,PRO EMP HANDS NO/MIN INJURY,2013,704,419,285
ASSAULT,PRO EMP HANDS NO/MIN INJURY,2014,697,402,295
ASSAULT,PRO EMP HANDS NO/MIN INJURY,2015,569,349,220
ASSAULT,PRO EMP HANDS NO/MIN INJURY,2016,554,356,198
ASSAULT,PRO EMP HANDS NO/MIN INJURY,2017,523,369,154
ASSAULT,PRO EMP HANDS NO/MIN INJURY,2018,692,489,203
ASSAULT,SIMPLE,2008,34745,29438,5307
ASSAULT,SIMPLE,2009,30266,24612,5654
ASSAULT,SIMPLE,2010,28048,23129,4919
ASSAULT,SIMPLE,2011,13912,11293,2619
ASSAULT,SIMPLE,2012,13823,11330,2493
ASSAULT,SIMPLE,2013,12498,10106,2392
ASSAULT,SIMPLE,2014,11239,8881,2358
ASSAULT,SIMPLE,2015,11506,9406,2100
ASSAULT,SIMPLE,2016,11718,10022,1696
ASSAULT,SIMPLE,2017,12696,10964,1732
ASSAULT,SIMPLE,2018,12543,11046,1497

Как я могу сложить столбцы?

...