我实际上有一个包含多个数据系列的饼图,每个数据都以饼图表示(参见JSFiddle链接)。
我正在寻找一种方法来实现每个饼图的最佳大小的“自动”计算和最佳位置,以便以通用方式将它们全部呈现在一个单个容器中。
我已经开始提出解决方案,但它确实不是最佳选择。
要么我不了解Highcharts在生成图表时如何工作,要么我的系统能够进行计算或者两者都有未知的价值。
请注意,如果使用更多系列,生成器仅适用于1到6个不同系列的数据,因为我没有进行计算,因此无法获得放置。
此外,它确实只适用于这些尺寸的容器:
在宽度或高度较高的容器上,系统将无法计算位置。
这实际上是我寻找如何获得最佳和通用位置计算器的想法的一部分。
这是我附带的代码和代码示例后的JSFiddle链接。
// Pie Chart Class
var pieChart = {
create: function(_title, _data, _color, _height, _width) {
return (function() {
var type = 'pie';
var title = _title || "defaultName";
var color = _color || "#EBEBEB";
var height = _height || 170;
var width = _width || 340;
var series = [];
var chart;
var sizeData = getSize(height, width);
if (_data)
newSeries(_data);
// Public functions
function newSeries(_data) {
var _datas = [];
for (var dataSet in _data) {
if (_data.hasOwnProperty(dataSet) && (color != null && color != undefined)) {
_datas.push({
name: dataSet,
y: _data[dataSet],
});
}
}
series.push({
data: _datas,
borderWidth: 0,
center: []
});
setPos(series.length);
}
function Series() {
return (JSON.stringify(series));
}
function drawOn(item) {
if (!item || !document.getElementById(item) && !chart)
return (null);
else {
chart = new Highcharts.Chart({
chart: {
renderTo: item,
backgroundColor: color,
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
title: {
text: title
},
plotOptions: {
pie: {
allowPointSelect: false,
borderWidth: 0,
dataLabels: {
distance: -1,
enabled: true,
format: '<b>{point.name}</b>: {point.y}',
style: {
color: 'black'
}
},
size: sizeData.size
}
},
series: JSON.parse(Series())
});
}
}
// Private functions
function setPos(_len) {
if (_len == 1)
series[0].center = [sizeData.center, sizeData.h];
else if (_len == 2) {
series[0].center = [sizeData.second, sizeData.h];
series[1].center = [sizeData.fourth, sizeData.h];
} else if (_len == 3) {
series[0].center = [sizeData.w1, sizeData.h];
series[1].center = [sizeData.center, sizeData.h];
series[2].center = [sizeData.w6, sizeData.h];
} else if (_len == 4) {
series[0].center = [(sizeData.w1 + sizeData.w2) / 2, sizeData.h];
series[1].center = [sizeData.w3, sizeData.h];
series[2].center = [(sizeData.w4 + sizeData.w5) / 2, sizeData.h];
series[3].center = [sizeData.w6, sizeData.h];
} else if (_len == 5) {
series[0].center = [sizeData.w1, sizeData.h];
series[1].center = [sizeData.second, sizeData.h];
series[2].center = [sizeData.center, sizeData.h];
series[3].center = [sizeData.fourth, sizeData.h];
series[4].center = [sizeData.w6, sizeData.h];
} else if (_len == 6) {
series[0].center = [sizeData.w1, sizeData.h];
series[1].center = [sizeData.w2, sizeData.h];
series[2].center = [sizeData.w3, sizeData.h];
series[3].center = [sizeData.w4, sizeData.h];
series[4].center = [sizeData.w5, sizeData.h];
series[5].center = [sizeData.w6, sizeData.h];
}
}
function getSize(height, width) {
var nbChart = 6;
var diam;
var tmpWidth = width - 30;
if (nbChart == 1)
diam = height - ( height / 3);
else {
diam = (tmpWidth - (tmpWidth / nbChart)) / nbChart;
}
var test = (tmpWidth - (diam * nbChart));
var h = ((height - diam) / 2) / 2;
var w = diam + (test / (nbChart * 2));
var decal;
if (width >= 680)
decal = test / 10;
else
decal = 0;
return {
width: width,
height: height,
size: diam,
h: h,
w1: ((diam / 2) + decal),
w2: (((w) + diam / 2) + decal),
w3: (((w * 2) + diam / 2) + decal),
w4: (((w * 3) + diam / 2) + decal),
w5: (((w * 4) + diam / 2) + decal),
w6: (((w * 5) + diam / 2) + decal),
center: (((((w * 2) + diam / 2) + decal) + (((w * 3) + diam / 2) + decal)) / 2),
second: (((diam / 2) + decal) + (((((w * 2) + diam / 2) + decal) + (((w * 3) + diam / 2) + decal)) / 2)) / 2,
fourth: ((((((w * 2) + diam / 2) + decal) + (((w * 3) + diam / 2) + decal)) / 2) + (((w * 5) + diam / 2) + decal)) / 2
}
}
return {
Series: Series,
drawOn: drawOn,
newSeries: newSeries
}
})();
}
};
var crPie = pieChart.create('Test', {T1: 500, T2: 700}, "#EBEBEB", 170, 680);
crPie.newSeries({T1: 700, T2: 800});
crPie.drawOn('container');
(这是JSFiddle链接:https://jsfiddle.net/jcL0wuwp/)
我通过互联网进行多项研究,但没有找到我想要的东西,这是获得数据系列最佳位置和大小的方法。
(我知道代码的某些部分不是最优的,但我的问题不是关于如何优化或使用JS中的类,尽管我不是很好的建议。)
答案 0 :(得分:2)
我会改变你对馅饼系列定位的想法。我更喜欢包装Higcharts的getCenter方法,因此可以使用响应式图表:
(function(H) {
H.wrap(H.Chart.prototype, 'addSeries', function(proceed, options, redraw, animation) {
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
var chart = this;
Highcharts.each(chart.series, function(s) {
s.isDirty = true;
});
chart.redraw();
});
H.wrap(H.seriesTypes.pie.prototype, 'getCenter', function(proceed) {
var series = this,
chart = series.chart,
width = chart.chartWidth,
height = chart.chartHeight,
numberOfSeries = chart.series.length,
index = series._i,
initialSize, size, centerY = height / 2,
centerX;
centerX = (index + 1) * (width / (numberOfSeries + 1));
initialSize = width / (numberOfSeries + 1);
size = initialSize > height ? height : initialSize;
return [centerX, centerY, size, 0]
});
}(Highcharts));
我使用了多个系列来计算你的馅饼系列的新尺寸和中心位置。我已经更改了addSeries方法,因此您也可以添加自定义饼图系列。
在这里您可以找到一个如何工作的示例: http://jsfiddle.net/oohn3q22/6/