问题
I got a scenario where in I need to display value for every stack in stacked multi-bar chart - nvd3 graph as we can display value in discrete value - nvd3 graph.
I understand, 'showvalue' is used in discrete bar controller, can we use showvalue
in stacked graph, if not please suggest with an alternative solution.
Thanks in advance
回答1:
Currently isn't possible. That option is available only in the discrete bar chart.
From the maintainer:
We don't have this ability. Stacked/Grouped charts also have complex animations making this a tricky thing to solve. We use tooltips instead.
Source https://github.com/novus/nvd3/issues/150
If you want to do this you need to make your own implementation using d3. There is a good example here http://plnkr.co/edit/BNpAlFalKz0zkkSszHh1?p=preview. It's using the angular wrapper but it's a good starting point.
var app = angular.module('app', ['nvd3ChartDirectives']);
app.controller('chartCtrl', function($scope, $timeout) {
var ANIMATION_TIME = 1500,
countSeriesDisplayed = 2,
promise,
labels = ["label1", "label2", "label3", "label4", "label5"];
$scope.isStacked = false;
// Example data
$scope.chartData = [{
"key": "Series 1",
"values": [
[0, 10],
[1, 20],
[2, 30],
[3, 40],
[4, 50]
]
}, {
"key": "Series 2",
"values": [
[0, 10],
[1, 40],
[2, 60],
[3, 20],
[4, 40]
]
}];
/* To add labels, images, or other nodes on the created SVG, we need to wait
* for the chart to be rendered with a callback.
* Once the chart is rendered, a timeout is set to wait for the animation to
* finish.
*
* Then, we need to find the position of the labels and set it with the
* transform attribute in SVG.
* To do so, we have to get the width and height of each bar/group of bar
* which changes if stacked or not
*
*/
// Callback called when the chartData is assigned
$scope.initLabels = function() {
return function(graph) {
promise = $timeout(function() {
var svg = d3.select("svg"),
lastRects, rectWidth,
heightForXvalue = []; // Used for grouped mode
// We get one positive rect of each serie from the svg (here the last serie)
lastRects = svg.selectAll("g.nv-group").filter(
function(d, i) {
return i == countSeriesDisplayed - 1;
}).selectAll("rect.positive");
if ($scope.isStacked) {
// If stacked, we get the width of one rect
rectWidth = lastRects.filter(
function(d, i) {
return i == countSeriesDisplayed - 1;
}).attr("width");
} else {
// If grouped, we need to get the greatest height of each bar
var nvGroups = svg.selectAll("g.nv-group").selectAll("rect.positive");
nvGroups.each(
function(d, i) {
// Get the Min height space for each group (Max height for each group)
var rectHeight = parseFloat(d3.select(this).attr("y"));
if (angular.isUndefined(heightForXvalue[i])) {
heightForXvalue[i] = rectHeight;
} else {
if (rectHeight < heightForXvalue[i]) {
heightForXvalue[i] = rectHeight;
}
}
}
);
// We get the width of one rect multiplied by the number of series displayed
rectWidth = lastRects.filter(
function(d, i) {
return i == countSeriesDisplayed - 1;
}).attr("width") * countSeriesDisplayed;
}
// We choose a width equals to 70% of the group width
var labelWidth = rectWidth * 70 / 100;
var groupLabels = svg.select("g.nv-barsWrap").append("g");
lastRects.each(
function(d, index) {
var transformAttr = d3.select(this).attr("transform");
var yPos = parseFloat(d3.select(this).attr("y"));
groupLabels.append("text")
.attr("x", (rectWidth / 2) - (labelWidth /2)) // We center the label
// We add a padding of 5 above the highest rect
.attr("y", (angular.isUndefined(heightForXvalue[index]) ? yPos : heightForXvalue[index]) - 5)
// We set the text
.text(labels[index])
.attr("transform", transformAttr)
.attr("class", "bar-chart-label");
});
}, ANIMATION_TIME);
}
};
// Tooltips
$scope.toolTipContentFunction = function () {
return function (key, x, y, e, graph) {
return labels[x];
}
};
$scope.$on('$destroy', function () {
// Cancel timeout if still active
$timeout.cancel(promise);
});
});
UPDATE:
I've created a gist that could help you to implement this by yourself.
https://gist.github.com/topicus/217444acb4204f364e46
来源:https://stackoverflow.com/questions/30621208/how-to-display-values-in-stacked-multi-bar-chart-nvd3-graphs