d3js - 如何将x域值向右移动

时间:2017-07-08 16:43:58

标签: javascript html5 css3 d3.js charts

我正在使用d3.js版本4在一个图表上工作。 所以我想将条形图的绘图向右移动,如下所示。 enter image description here

通常条形图从起始位置渲染,如下所示 enter image description here

请帮忙......!     Demo fiddle

2 个答案:

答案 0 :(得分:1)

在D3 v4.x中,没有本地方法在频段刻度中设置第一个刻度之前的填充绝对量。

如果你接受一个hacky解决方案,有几个 hacks

其中一个hacky解决方案包括在真实域之前简单地添加假值...

xScale.domain(["foo", "bar", "baz"].concat(stackedData[0].map(function(d) {
    return d.data.day;
})));

...并且仅显示轴中的真实域:

xAxis.scale(xScale)
    .tickValues(stackedData[0].map(function(d) {
        return d.data.day;
    }));

结果如下:



var self = this;
self.plannedHours = 80;
self.averagePlannedHours = 70;
self.averagPlannedItems = 7;
self.isStoryPoints = false;
self.availableHours = 0;
self.data = [{
  "day": "Mon",
  "avgPlannedHours": 70,
  "overPlannedHours": 80,
  "doneWork": 0
}, {
  "day": "Tue",
  "avgPlannedHours": 70,
  "overPlannedHours": 80,
  "doneWork": 30
}, {
  "day": "Wed",
  "avgPlannedHours": 70,
  "overPlannedHours": 90,
  "doneWork": 35
}, {
  "day": "Thu",
  "avgPlannedHours": 70,
  "overPlannedHours": 90,
  "doneWork": 50
}, {
  "day": "Fri",
  "avgPlannedHours": 70,
  "overPlannedHours": 90,
  "doneWork": 55
}, {
  "day": "Sat",
  "avgPlannedHours": 0,
  "overPlannedHours": 0,
  "doneWork": 0
}, {
  "day": "Sun",
  "avgPlannedHours": 0,
  "overPlannedHours": 0,
  "doneWork": 0
}, {
  "day": "Mon1",
  "avgPlannedHours": 70,
  "overPlannedHours": 80,
  "doneWork": 0
}, {
  "day": "Tue1",
  "avgPlannedHours": 70,
  "overPlannedHours": 80,
  "doneWork": 30
}, {
  "day": "Wed1",
  "avgPlannedHours": 70,
  "overPlannedHours": 90,
  "doneWork": 35
}, {
  "day": "Thu1",
  "avgPlannedHours": 70,
  "overPlannedHours": 90,
  "doneWork": 50
}, {
  "day": "Fri1",
  "avgPlannedHours": 70,
  "overPlannedHours": 90,
  "doneWork": 55
}, {
  "day": "Sat1",
  "avgPlannedHours": 0,
  "overPlannedHours": 0,
  "doneWork": 0
}, {
  "day": "Sun1",
  "avgPlannedHours": 0,
  "overPlannedHours": 0,
  "doneWork": 0
}];
self.dataCopy = self.data.slice();
self.normalisedData = [];
normalizeData();

function normalizeData() {
  self.normalisedData = self.data.map(function(data, index) {
    if (self.plannedHours > self.averagePlannedHours) {
      data.overPlannedHours = data.overPlannedHours - data.avgPlannedHours;
    } else if (self.plannedHours < self.averagePlannedHours) {
      data.avgPlannedHours = data.avgPlannedHours - data.overPlannedHours;
    }
    return data;
  });
}

renderChart();

function renderChart() {

  var colors1 = ['#FFD692', '#A9EEFF'],
    avgPlannedHoursLineColor = "#36CFF5",
    plannedHoursLineColor = self.plannedHours > self.averagePlannedHours ? "#F5A623" : "#A8EEFF",
    color = d3.scaleOrdinal(colors1),
    margin = {
      top: 25,
      right: 180,
      bottom: 30,
      left: 40
    },
    svg = d3.select("#chart-container"),
    width = +svg.attr("width") - margin.left - margin.right,
    height = +svg.attr("height") - margin.top - margin.bottom;

  var g = svg.append('g')
    .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

  // var stackedData = d3.layout.stack()(self.normalisedData);
  var stack = d3.stack().keys(["avgPlannedHours", "overPlannedHours"]);
  var stackedData = stack(self.normalisedData);
  stackedData[1] = stackedData[1].map(function(stData, index) {
    stData[0] = 0;
    return stData;
  });

  var xAxis = d3.axisBottom();
  if (self.plannedHours > self.averagePlannedHours) {
    var swappedStack = stackedData[0];
    stackedData[0] = stackedData[1];
    stackedData[1] = swappedStack;
  }

  var yAxis = d3.axisLeft()

  var xScale = d3.scaleBand()
    .rangeRound([0, width])
    .padding(0.4)
    .align(0.3);

  xScale.domain(["foo", "bar", "baz"].concat(stackedData[0].map(function(d) {
    return d.data.day;
  })));

  var x1Scale = d3.scaleBand()
    .rangeRound([0, width])
    .padding(0.6);

  x1Scale.domain(["foo", "bar", "baz"].concat(stackedData[0].map(function(d) {
    return d.data.day;
  })));

  xAxis.scale(xScale)
    .tickValues(stackedData[0].map(function(d) {
      return d.data.day;
    }));

  var yScale = d3.scaleLinear()
    .rangeRound([height, 0]);
  if (self.plannedHours > self.averagePlannedHours) {
    yScale.domain([0,
      d3.max(stackedData[0],
        function(d) {
          return d[0] + d[1];
        })
    ]).nice();
  } else {
    yScale.domain([0,
      d3.max(stackedData[stackedData.length - 1],
        function(d) {
          return d[0] + d[1];
        })
    ]).nice();
  }

  yAxis.scale(yScale)
    .ticks(10);


  var layer = g.selectAll(".stack")
    .data(stackedData)
    .enter().append("g")
    .attr("class", "stack")
    .style("fill", function(d, i) {
      return color(i);
    });

  layer.selectAll("rect")
    .data(function(d) {
      return d;
    })
    .enter().append("rect")
    .attr("x", function(d) {
      return xScale(d.data.day);
    })
    .attr("y", function(d) {
      return yScale(d[1] + d[0]);
    })
    .attr("height", function(d) {
      return yScale(d[0]) - yScale(d[1] + d[0]);
    })
    .attr("width", 24);

  var workDoneLayer = g.selectAll(".work-done")
    .data(self.dataCopy)
    .enter().append("rect")
    .attr("class", "work-done")
    .attr("x", function(d) {
      return x1Scale(d.day);
    })
    .attr("y", function(d) {
      return yScale(d.doneWork);
    })
    .attr("width", 24)
    .attr("height", function(d) {
      return height - yScale(d.doneWork);
    });

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

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

  var averagLineData = self.dataCopy[0].avgPlannedHours;
  var plannedHoursDotted = d3.max(self.dataCopy, function(d) {
    return d.overPlannedHours;
  });
  g.append("svg:line")
    .attr("x1", 0)
    .attr("x2", width)
    .attr("y1", yScale(averagLineData))
    .attr("y2", yScale(averagLineData))
    .attr("stroke-dasharray", ("5, 5"))
    .style("stroke", avgPlannedHoursLineColor);
  g.append("svg:line")
    .attr("x1", 0)
    .attr("x2", width)
    .attr("y1", yScale(plannedHoursDotted))
    .attr("y2", yScale(plannedHoursDotted))
    .attr("stroke-dasharray", ("5, 5"))
    .style("stroke", plannedHoursLineColor);
}
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg id="chart-container" width="750" height="251"> </svg>
&#13;
&#13;
&#13;

答案 1 :(得分:-1)

将您的svg视为HTML元素。你在里面,酒吧按照&#34; d&#34;元件。您只需添加transform: translateX(50px)即可将整个栏移到右侧。

例如,只需在文档中添加此css规则以对齐黑色,蓝色和黄色条:

g.stack {
    transform: translateX(48px);
}