currently my pie chart in d3 shows the sum of numbers,i want percentage instead .
for eg: currently i have a pie chart for how many people submitted application who visited our site. our current pie chart shows like this : people submitted 17,000 and people didn't submitted-10,000 but i need this in percentage also. how can i get that. please find the pie code below and let me know what changes do i need to make this work. I am new to JavaScript and D3.
ko.bindingHandlers.pieChart = {
init: function (element, valueAccessor) {
var _options = valueAccessor();
var _data = _options.transformer(_options.data);
$(element).css("marginLeft", "auto");
$(element).css("marginRight", "auto");
if (typeof _options.maxWidth != "undefined") {
var _max = _options.maxWidth * 1;
$(element).width(Math.min($(element).parent().width(), _max));
}
if ($(element).find("svg").length > 0 && _data.length == 0) {
$(element).find("svg").empty();
}
if (_data.length > 0 && isNaN(_data[0].value)) {
_data = [];
$(element).find("svg").empty();
}
if ($(element).is(":visible")) {
nv.addGraph(function () {
var _chart = nv.models.growingPieChart()
.x(function (d) {
return d.label
})
.y(function (d) {
return d.value
})
.height($(element).width())
.showLabels(true).showLegend(false)
.tooltipContent(function (key, y, e, graph) {
return '<h3>' + hueUtils.htmlEncode(key) + '</h3><p>' + y + '</p>'
});
var _d3 = ($(element).find("svg").length > 0) ? d3.select($(element).find("svg")[0]) : d3.select($(element)[0]).append("svg");
_d3.datum(_data)
.transition().duration(150)
.each("end", _options.onComplete != null ? _options.onComplete : void(0))
.call(_chart);
if (_options.fqs) {
$.each(_options.fqs(), function (cnt, item) {
if (item.id() == _options.data.widget_id && item.field() == _options.field()) {
_chart.selectSlices($.map(item.filter(), function (it) {
return it.value();
}));
}
});
}
$(element).data("chart", _chart);
var _resizeTimeout = -1;
nv.utils.windowResize(function () {
window.clearTimeout(_resizeTimeout);
_resizeTimeout = window.setTimeout(function () {
_chart.update();
}, 200);
});
$(element).on("forceUpdate", function () {
_chart.update();
});
$(element).height($(element).width());
var _parentSelector = typeof _options.parentSelector != "undefined" ? _options.parentSelector : ".card-widget";
$(element).parents(_parentSelector).on("resize", function () {
if (typeof _options.maxWidth != "undefined") {
var _max = _options.maxWidth * 1;
$(element).width(Math.min($(element).parent().width(), _max));
}
$(element).height($(element).width());
_chart.update();
});
return _chart;
}, function () {
var _d3 = ($(element).find("svg").length > 0) ? d3.select($(element).find("svg")[0]) : d3.select($(element)[0]).append("svg");
_d3.selectAll(".nv-slice").on("click",
function (d, i) {
if (typeof _options.onClick != "undefined") {
chartsUpdatingState();
_options.onClick(d);
}
});
});
}
},
update: function (element, valueAccessor) {
var _options = valueAccessor();
var _data = _options.transformer(_options.data);
var _chart = $(element).data("chart");
if (_chart) {
var _d3 = d3.select($(element).find("svg")[0]);
_d3.datum(_data)
.transition().duration(150)
.each("end", _options.onComplete != null ? _options.onComplete : void(0))
.call(_chart);
if (_options.fqs) {
$.each(_options.fqs(), function (cnt, item) {
if (item.id() == _options.data.widget_id && item.field() == _options.field()) {
_chart.selectSlices($.map(item.filter(), function (it) {
return it.value();
}));
}
});
}
chartsNormalState();
}
else if (_data.length > 0) {
ko.bindingHandlers.pieChart.init(element, valueAccessor);
}
}
};
答案 0 :(得分:0)
A fiddle would be useful to test this against (hint hint), but I'm pretty sure you want to change this line:
.y(function (d) {
return d.value
})
to this
.y(function (d) {
return d.value/total
})
You may have to define total. Like I said, without a jsfiddle or at least some indication of the format of your data, it's hard to determine if this is actually what's wrong or how to fix it.
Note: a pie chart of relative percentages will look exactly the same as a pie chart of the original numbers. You might be able to change the label and only the label, as follows:
return '<h3>' + hueUtils.htmlEncode(key) + '</h3><p>' + y + '</p>'
to this
return '<h3>' + hueUtils.htmlEncode(key) + '</h3><p>' + (y/total) + '</p>'
Hopefully both of those should work. You will have to define total, if it isn't already defined elsewhere. If not:
var total = 0;
_data.forEach(function(d){total += d.value});
Good luck!
答案 1 :(得分:0)
It would be even more helpful to include information such as the library you are using and a fully reproducible example using a gist, codepen, jsfiddle, etc. I am guessing you are using hue and more specifically growingPieChart. If my guesses are correct, then you can modify your tooltipContent
function similar to @Vyross answer that posted while I was typing this.
.tooltipContent(function (key, y, e, graph) {
return '<h3>' + hueUtils.htmlEncode(key) + '</h3><p>' +
(+y) / d3.sum(
d3.select(graph.container).select('g').datum(),
function(d){return d.value}
) +
'</p>'
});