我正在使用d3.js版本4制作一个图表。
所以我想把条形图的绘制向右移动,如下所示。
通常条形图从起始位置渲染,如下所示
请帮忙。。。。!Demo fiddle
最佳答案
在D3 v4.x中,没有本机方法来设置带刻度中第一个刻度之前的填充绝对量。
不过,如果你接受一个老套的解决方案,就有好几种方法。
其中一个棘手的解决方案是在真正的域之前简单地添加假值。。。
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);
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg id="chart-container" width="750" height="251"> </svg>
关于javascript - d3js-如何将x-域值向右移动,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44988496/