Сгруппированные гистограммы с выпадающими в d3. js - PullRequest
0 голосов
/ 19 апреля 2020
<html>
<head>
  <meta charset="utf-8">
  <meta name="description" content="L4F - Axes and scales ">
  <title>SVG</title>
  <script src="https://d3js.org/d3.v5.min.js" charset="utf-8"></script>
  <body>
    <form>
      <select>
        <option value="first" selected>First</option>
        <option value="second">Second</option>
      </select>
    </form>
    <svg width="960" height="500"></svg>
  </body>
  <script>

  var vals = '[{"Department":"CAM","UG":71,"PG":81,"Foundation":55},{"Department":"CSIS","UG":66,"PG":80,"Foundation":43},{"Department":"GAV","UG":60,"PG":77,"Foundation":50}]'
  var vals1 = '[{"Department":"CAM","UG":51,"PG":91,"Foundation":65},{"Department":"CSIS","UG":76,"PG":60,"Foundation":32},{"Department":"GAV","UG":86,"PG":87,"Foundation":70}]'
  data = JSON.parse(vals);
  data1 = JSON.parse(vals1);

  d3.selectAll("select").on("change", selectDataset);
  function selectDataset()
  {
       value = this.value;
      if (value == "first")
      {
          // change(datasetTotal);
          change(vals);
      }
      else if (value == "second")
      {
          // change(datasetOption1);
          change(vals1);
      }
    }
    var svg = d3.select("svg"),
            margin = { top: 20, right: 20, bottom: 30, left: 40 },
            width = +svg.attr("width") - margin.left - margin.right,
            height = +svg.attr("height") - margin.top - margin.bottom,
            g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        var x0 = d3.scaleBand()
            .rangeRound([0, width])
            .paddingInner(0.1);

        var x1 = d3.scaleBand()
            .padding(0.05);

        var y = d3.scaleLinear()
            .rangeRound([height, 0]);
// "#98abc5", "#8a89a6", "#7b6888", "#6b486b",
        var z = d3.scaleOrdinal()
            .range([ "rgba(255, 99, 132, 0.5)", "rgba(153, 102, 255, 0.5)", "rgba(54, 162, 235, 0.5)"])

//added extra for testing
            var xAxis=d3.axisBottom(x0);

                 // add the y Axis
         var yAxis=d3.axisLeft(y);
//till here
        console.log(data)
        var keys = Object.keys(data[0]).slice(1);


//added extra
        svg.append("g")
           .attr("class", "x axis")
           .attr("transform", "translate(0," + height + ")")
           .call(xAxis);

       d3.select("input[value=\"first\"]").property("checked", true);
       change(vals);
       //till here

       var legend = g.append("g")
           .attr("font-family", "sans-serif")
           .attr("font-size", 10)
           .attr("text-anchor", "end")
           .selectAll("g")
           .data(keys.slice().reverse())
           .enter().append("g")
           .attr("transform", function (d, i) { return "translate(0," + i * 20 + ")"; });

       legend.append("rect")
           .attr("x", width - 19)
           .attr("width", 19)
           .attr("height", 19)
           .attr("fill", z);

       legend.append("text")
           .attr("x", width - 24)
           .attr("y", 9.5)
           .attr("dy", "0.32em")
           .text(function (d) { return d; });


        function change(data)
        {
          console.log(data)
        x0.domain(data.map(function (d) { return d.key; }));
        x1.domain(keys).rangeRound([0, x0.bandwidth()]);
        // y.domain([0, d3.max(data, function (d) { return d3.max(keys, function (key) { return d[key]; }); })]).nice();
        y.domain([0, 100]).nice();

       svg.select(".y.axis").remove();
       svg.select(".x.axis").remove();


        g.append("g")
            .selectAll("g")
            .data(data)
            .enter().append("g")
            .attr("transform", function (d) { return "translate(" + x0(d.Department) + ",0)"; })
            .selectAll("rect")
            .data(function (d) { return keys.map(function (key) { return { key: key, value: d[key] }; }); })
            .enter().append("rect")
            .attr("x", function (d) { return x1(d.key); })
            .attr("y", function (d) { return y(d.value); })
            .attr("width", x1.bandwidth())
            .attr("height", function (d) { return height - y(d.value); })
            .attr("fill", function (d) { return z(d.key); });

        g.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis);

        g.append("g")
            .attr("class", "y axis")
            .call(yAxis.ticks(null, "s"))
            .append("text")
            .attr("x", 250)
            .attr("y", y(y.ticks().pop()) + 0.5)
            .attr("dy", "0.32em")
            .attr("fill", "#000")
            .attr("font-weight", "bold")
            .attr("text-anchor", "start")
            .text("Average Attendance of Departments")
            .attr("font-size",20)
            .style('fill', 'rgb(0,0,255,1)');

            bar.exit().remove();

                    // updated data:
                    // bar.transition()
                    //         .duration(750)
                    //         .attr("x", function(d) { return 0; })
                    //         .attr("y", function(d) { return y(d.ModuleCode); })
                    //         .attr("height", function(d) { return x(d.avgAtt); })
                    //         .attr("width", x.bandwidth());
          }

  </script>
  </html>

У меня проблема с добавлением выпадающего списка на вышеупомянутый сгруппированный график. Кто-нибудь может мне с этим помочь. Часть этого кода взята из другого источника, чтобы создать выпадающие списки. Это работало как шарм на простых столбцах, но я застрял на второй строке в функции изменения, так как я новичок в двух осях x x0 и x1. Если дело касается только одной оси, я каким-то образом заставил работать простую гистограмму.

Оригинальный код до изменений выглядит следующим образом:

<html>
<head>
  <meta charset="utf-8">
  <meta name="description" content="L4F - Axes and scales ">
  <title>SVG</title>
  <script src="https://d3js.org/d3.v5.min.js" charset="utf-8"></script>
  <body>
    <svg width="960" height="500"></svg>
  </body>
  <script>
    var svg = d3.select("svg"),
            margin = { top: 20, right: 20, bottom: 30, left: 40 },
            width = +svg.attr("width") - margin.left - margin.right,
            height = +svg.attr("height") - margin.top - margin.bottom,
            g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        var x0 = d3.scaleBand()
            .rangeRound([0, width])
            .paddingInner(0.1);

        var x1 = d3.scaleBand()
            .padding(0.05);

        var y = d3.scaleLinear()
            .rangeRound([height, 0]);
// "#98abc5", "#8a89a6", "#7b6888", "#6b486b",
        var z = d3.scaleOrdinal()
            .range([ "rgba(255, 99, 132, 0.5)", "rgba(153, 102, 255, 0.5)", "rgba(54, 162, 235, 0.5)"])
        var vals = '[{"Department":"CAM","UG":"71","PG":"81","Foundation":"55"},{"Department":"CSIS","UG":"66","PG":"80","Foundation":"43"},{"Department":"GAV","UG":"60","PG":"77","Foundation":"50"}]'
        data = JSON.parse(vals);
        // data=[{"Department":"CAM","UG":"75","PG":"83","Foundation":"52"}]
        console.log(data)
        var keys = Object.keys(data[0]).slice(1);

        x0.domain(data.map(function (d) { return d.Department; }));
        x1.domain(keys).rangeRound([0, x0.bandwidth()]);
        y.domain([0, d3.max(data, function (d) { return d3.max(keys, function (key) { return d[key]; }); })]).nice();

        g.append("g")
            .selectAll("g")
            .data(data)
            .enter().append("g")
            .attr("transform", function (d) { return "translate(" + x0(d.Department) + ",0)"; })
            .selectAll("rect")
            .data(function (d) { return keys.map(function (key) { return { key: key, value: d[key] }; }); })
            .enter().append("rect")
            .attr("x", function (d) { return x1(d.key); })
            .attr("y", function (d) { return y(d.value); })
            .attr("width", x1.bandwidth())
            .attr("height", function (d) { return height - y(d.value); })
            .attr("fill", function (d) { return z(d.key); });

        g.append("g")
            .attr("class", "axis")
            .attr("transform", "translate(0," + height + ")")
            .call(d3.axisBottom(x0));

        g.append("g")
            .attr("class", "axis")
            .call(d3.axisLeft(y).ticks(null, "s"))
            .append("text")
            .attr("x", 250)
            .attr("y", y(y.ticks().pop()) + 0.5)
            .attr("dy", "0.32em")
            .attr("fill", "#000")
            .attr("font-weight", "bold")
            .attr("text-anchor", "start")
            .text("Average Attendance of Departments")
            .attr("font-size",20)
            .style('fill', 'rgb(0,0,255,1)');

        var legend = g.append("g")
            .attr("font-family", "sans-serif")
            .attr("font-size", 10)
            .attr("text-anchor", "end")
            .selectAll("g")
            .data(keys.slice().reverse())
            .enter().append("g")
            .attr("transform", function (d, i) { return "translate(0," + i * 20 + ")"; });

        legend.append("rect")
            .attr("x", width - 19)
            .attr("width", 19)
            .attr("height", 19)
            .attr("fill", z);

        legend.append("text")
            .attr("x", width - 24)
            .attr("y", 9.5)
            .attr("dy", "0.32em")
            .text(function (d) { return d; });
  </script>
  </html>

И вывод: Grouped bar before drop down

Мой желаемый вывод - обновлять бары, подавая разные данные, используя выпадающие списки. Поскольку у меня очень ограниченные знания о d3. js, любая помощь или любая ссылка на рабочую сгруппированную гистограмму с фильтрами очень ценится. Спасибо.

1 Ответ

0 голосов
/ 25 апреля 2020

Насколько я понимаю, вы хотите, чтобы выпадающий список изменял данные диаграммы прямо так.

d3. js Вы можете проверить URL-адрес упоминания, я думаю, что это именно то, что вы ожидаете dropdwon с изменением Я надеюсь, что эта ссылка поможет вам.

И если вы не понимаете, укажите URL-адрес d3. JS, чтобы вы могли связаться со мной по почте, чтобы я подробно объяснил.

Спасибо. give me your mail ID

...