Проблемы с сгруппированной гистограммой - PullRequest
1 голос
/ 26 мая 2019

Я новичок в d3 и пытаюсь создать сгруппированную гистограмму после этого и этого веб-сайтов.

Ниже приведен мой код для весов

x0 = d3.scaleTime()
               .domain([
                 d3.min(dataset, function(d) {return d.date;}),
                 d3.max(dataset, function(d) {return d.date;})
               ])
               .range([0,w]);

    x1 = d3.scaleOrdinal()
            .domain([dataset.WorldPopulation, dataset.InternetUser]);
    //        .rangeRound([0, x0.bandwidth()]);

   y = d3.scaleLinear()
          .domain([0, d3.max(dataset, function(d) {return d.WorldPopulation})])
          .range([h,0]);

На сайте выше они используют scaleOrdinal, но я использовал scaleTime в качестве x0.Поэтому я не слишком уверен, что это работает.

Это мой код для append(rect) для гистограммы

var date = svg.selectAll(".date")
                .data(dataset)
                .enter()
                .append("g")
                .attr("class", "g")
                .attr("transform", function(d) {return "translate(" + x0(d.date) + ",0)";});

              /* Add field1 bars */
            date.selectAll(".bar.field1")
              .data(d => [d])
              .enter()
              .append("rect")
              .attr("class", "bar field1")
            .style("fill","blue")
              .attr("x", d => x0(d.WorldPopulation))
              .attr("y", d => y(d.WorldPopulation))
              .attr("width", x1.bandwidth())
              .attr("height", d => {
                return height - margin.top - margin.bottom - y(d.WorldPopulation)
              });

            /* Add field2 bars */
            date.selectAll(".bar.field2")
              .data(d => [d])
              .enter()
              .append("rect")
              .attr("class", "bar field2")
            .style("fill","red")
              .attr("x", d => x0(d.InternetUser))
              .attr("y", d => y(d.InternetUser))
              .attr("width", x1.bandwidth())
              .attr("height", d => {
                return height - margin.top - margin.bottom - y(d.InternetUser)
              });

И это мой CSVфайл.Не слишком уверен, как загрузить Excel, поэтому я сделал снимок экрана.

Любая предоставленная помощь будет оценена.Не стесняйтесь запрашивать любые дополнительные фрагменты моего кода для уточнения.

edit: после настройки кода ошибки не отображаются, но svg также не создается.

1 Ответ

0 голосов
/ 26 мая 2019

Используя scaleBand для x0 и x1, работает следующий код:

<script src="js/d3.v4.js"></script>

<script>

    var margin = { top: 20, right: 20, bottom: 30, left: 40 },
        width = 960 - margin.left - margin.right,
        height = 500 - margin.top - margin.bottom;

    var x0 = d3.scaleBand()
        .rangeRound([0, width]).padding(.1);

    var x1 = d3.scaleBand();

    var y = d3.scaleLinear()
        .range([height, 0]);

    var xAxis = d3.axisBottom()
        .scale(x0)
        .tickSize(0);

    var yAxis = d3.axisLeft()
        .scale(y);

    var svg = d3.select('body').append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
      .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    d3.csv("InternetUserStats.csv", function (error, data) {

        var dates = data.map(function (d) { return d.date; });
        var ymax = d3.max(data, function (d) { return Math.max(d.WorldPopulation, d.InternetUser); });

        x0.domain(dates);
        x1.domain(['WorldPopulations', 'InternetUsers']).rangeRound([0, x0.bandwidth()]);
        y.domain([0, ymax]);

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

        svg.append("g")
            .attr("class", "y axis")
            .call(yAxis);

        var date = svg.selectAll(".g")
            .data(data)
            .enter().append("g")
            .attr("class", "g")
            .attr("transform", function (d) { return "translate(" + x0(d.date) + ",0)"; });

        /* Add field1 bars */
        date/*.selectAll(".bar.field1")
          .data(data)
          .enter()*/
          .append("rect")
          .attr("class", "bar field1")
        .style("fill", "blue")
          .attr("x", function (d) { return x1('WorldPopulations'); })
          .attr("y", function (d) { return y(+d.WorldPopulation); })
          .attr("width", x0.bandwidth() / 2)
          .attr("height", function (d) {
            return height /*- margin.top - margin.bottom*/ - y(d.WorldPopulation)
          });

        /* Add field2 bars */
        date/*.selectAll(".bar.field1")
          .data(data)
          .enter()*/
          .append("rect")
          .attr("class", "bar field2")
        .style("fill", "red")
          .attr("x", function (d) { return x1('InternetUsers'); })
          .attr("y", function (d) { return y(d.InternetUser); })
          .attr("width", x0.bandwidth() / 2)
          .attr("height", function (d) {
            return height /*- margin.top - margin.bottom*/ - y(d.InternetUser)
          });

    });

</script>

РЕДАКТИРОВАТЬ: следующий код добавляет легенду, основанную на вашем комментарии и вашей второй ссылке :

        //This code goes after field2 bars are added.

        /* Legend */
        var legend = svg.selectAll(".legend")
            .data(['WorldPopulations', 'InternetUsers'])  //Bind an array of the legend entries
        .enter().append("g")
            .attr("class", "legend")
            .attr("font-family", "sans-serif")
            .attr("font-size", 13)
            .style("text-anchor", "end")
            .attr("transform", function (d, i) { return "translate(0," + i * 20 + ")"; });

        legend.append("rect")
            .attr("x", width - 18)
            .attr("width", 18)
            .attr("height", 18)
            .style("fill", function (d) {
                // Return "blue" for "WorldPopulations" and "red" for "InternetUsers":
                return ((d === "WorldPopulations") ? "blue" : "red");
            });

        legend.append("text")
            .attr("x", width - 24)
            .attr("y", 9)
            .attr("dy", ".35em")
            //.style("text-anchor", "end")  //Already applied to .legend
            .text(function (d) { return d; });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...