如何在d3.js双条形图中选择Scale?

时间:2016-05-31 17:15:46

标签: javascript d3.js scale bar-chart

我的缩放比例有问题,选择用d3.js制作双重条形图。 任务是在两个值之间进行比较: 年度(Ytd)和去年的年度(Ytdn1)! 我认为诀窍是为两个值制作单个比例,以便图表显示两个柱之间的比较。

enter image description here

和hier是代码:

     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); });

1 个答案:

答案 0 :(得分:1)

如果您希望左右轴相同(如果YtdnYtdn1相等,则2个条的高度相同),则无需使用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数组中找到这些值的最大值。