【问题标题】:How to choose the Scale in a d3.js dual bar chart?如何在 d3.js 双条形图中选择比例?
【发布时间】:2016-05-31 17:15:46
【问题描述】:

我在选择使用 d3.js 制作双条形图时遇到问题。 任务是在两个值之间进行比较: 年初至今 (Ytd) 和去年年初至今 (Ytdn1) ! 我认为诀窍是为两个值制作一个比例,以便图表显示两个条形之间的比较。

然后是代码:

     var windowsize = $(window).width() - 150;

            var margin = { top: 50, right: 60, bottom: 170, left: 60 },
            elementWidth = parseInt(windowsize, 10),
            elementHeight = parseInt(d3.select(element).style("height"), 10),
            width = elementWidth - margin.left - margin.right,
            height = elementHeight - margin.top - margin.bottom;

                // parsin the data from the data-view-model
                var data = ko.unwrap(valueAccessor());

                data.forEach(function (d) {
                    if (d.Ytd == null) {
                        d.Ytd = 0;
                    }
                    if (d.Ytdn1 == null) {
                        d.Ytdn1 = 0;
                    }              
                });

                d3.select(element).select("svg").remove();
                if (!data || data.length === 0) return;


                    })

                var svg = d3.select(element).append("svg")
                .attr("width", width + margin.left + margin.right)
                .attr("height", height + margin.top + margin.bottom)
                .append("g")
                .attr("class", "graph")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
                var x = d3.scale.ordinal().rangeRoundBands([0, width], .1);

//*********************** HOW to choose the right  Scale  ?? ************************************

                var y0 = d3.scale.linear().domain([0, d3.max(d3.values(data.Ytdn))]).range([height, 0]);
                var y1 = d3.scale.linear().domain([0, d3.max(d3.values(data.Ytdn1))]).range([height, 0]);
 //*********************** HOW to choose the right  Scale  ?? ************************************

                var xAxis = d3.svg.axis().scale(x).orient("bottom");

                // create left yAxis
                var yAxisLeft = d3.svg.axis().scale(y0).ticks(5).orient("left");
                // create right yAxis
                var yAxisRight = d3.svg.axis().scale(y0).ticks(5).orient("right");

                x.domain(data.map(function (d) { return d.Name; }));
                y0.domain([0, d3.max(data, function (d) { return d.Ytd; })]);
                y0.domain([0, d3.max(data, function (d) { return d.Ytdn1; })]);

                svg.append("g")
                 .attr("class", "x axis")
                 .attr("transform", "translate(0," + height + ")")
                 .call(xAxis)
                 .selectAll("text")
                 .style("text-anchor", "end")
                 .attr("dx", "-.8em")
                 .attr("dy", ".15em")
                 .attr("transform", function (d) {
                     return "rotate(-65)"
                 });

     svg.append("g")
      .attr("class", "y axis axisLeft")
      .attr("transform", "translate(0,0)")
      .call(yAxisLeft)
      .append("text")
      .attr("y", 6)
      .attr("dy", "-2em")
      .style("text-anchor", "end")
      .style("text-anchor", "end")
      .text("YTD €");

     svg.append("g")
      .attr("class", "y axis axisRight")
      .attr("transform", "translate(" + (width) + ",0)")
      .call(yAxisRight)
      .append("text")
      .attr("y", 6)
      .attr("dy", "-2em")
      .attr("dx", "2em")
      .style("text-anchor", "end")
      .text("YTD N1 €");

      var bars = svg.selectAll(".bar").data(data).enter();

       bars.append("rect")
      .attr("class", "bar1")
      .attr("x", function (d) { return x(d.Name); })
      .attr("width", x.rangeBand() / 2)
      .attr("y", function (d) { return y0(d.Ytd); })
        .attr("height", function (d, i, j) { return height - y0(d.Ytd); })
      .on('mouseover', tip.show)
      .on('mouseout', tip.hide);

       bars.append("rect")
      .attr("class", "bar2")
      .attr("x", function (d) { return x(d.Name) + x.rangeBand() / 2; })
      .attr("width", x.rangeBand() / 2)
      .attr("y", function (d) { return y1(d.Ytdn1); })
        .attr("height", function (d, i, j) { return height - y1(d.Ytdn1); });

【问题讨论】:

  • 您将获得 Ytdn 和 Ytdn1 的最大值,只需获得两者的最大值并将其用作两个条形高度计算的 yScale。
  • 请同时提供d3 v4版本的答案

标签: javascript d3.js scale bar-chart


【解决方案1】:

如果您希望左右轴相同(如果它们的YtdnYtdn1 相等,则两个条将具有相同的高度),则无需使用 2 个刻度。因此,首先,只需将所有内容切换为使用单个 y 刻度。我们就叫它y吧。

然后您需要为y 计算一个域,该域占YtdnYtdn1 两个数据集的最大值。应该这样做:

var y0 = d3.scale.linear()
  .domain([0, d3.max(data, function(d) {
    return Math.max(d.Ytdn, d.Ytdn1);
  })])
  .range([height, 0]);

它选择每个 d.Ytdnd.Ytdn1 的最大值,并在整个 data 数组中找到这些值的最大值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多