我不熟悉海图。我最近被困在绘制图表中。我正在使用绘图带来绘制背景色。如果存在一个值,则必须对其进行着色;如果不存在一个值,则不应对其进行着色。
例如,在此图表中,对于橙色来说,阴影是好的,因为正面和负面都有值。但是对于香蕉,阴影是不正确的。它只有正值,因此只应给正侧加上阴影,而不给负侧加上阴影,即0到-2.5不应带有灰色阴影。
感谢您的帮助。
带有图表带的Highchart列:
以下代码:
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Column chart with negative values'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas'],
plotBands: [{
color: 'gray',
from: 0.5,
to: 1.5
},
{
color: 'gray',
from: 3.5,
to: 4.5
}],
},
credits: {
enabled: false
},
series: [{
name: 'John',
data: [5, 3, 4, 7, 2]
}, {
name: 'Jane',
data: [2, -2, -2, 2, 1]
}, {
name: 'Joe',
data: [3, 4, 4, -2, 5]
}]
});
答案 0 :(得分:0)
您不能将绘图带用于所描述的范围,因为它们的范围是-∞到∞。但是,您可以使用自定义形状并使它们看起来像绘图带。
首先,您需要在加载图表时触发函数:
chart: {
events: {
load: function() {
this.customRect = [] //We use this to keep track off all the shapes we create
addPlotbands(this); //Function to find what area should be colored in what way
}
}
}
然后,您需要一个函数来检测所有值是正值,负值还是混合值。这可以通过以下方式完成(请注意,这假设所有系列的点数完全相同)是
function addPlotbands(chart) {
let series = chart.series
let yMin = chart.yAxis[0].getExtremes().min;
let yMax = chart.yAxis[0].getExtremes().max;
for (let i = 0; i < series[0].data.length; i++) {
let allAboveZero = true;
let allBelowZero = true;
for (let j = 0; j < chart.series.length; j++) {
if (series[j].data[i].y >= 0) {
allBelowZero = false;
} else {
allAboveZero = false;
}
}
if (allAboveZero) {
addCustomElement(chart, i, 0, yMax)
} else if (allBelowZero) {
addCustomElement(chart, i, yMin, 0)
} else {
addCustomElement(chart, i, yMin, yMax)
}
}
}
然后,最后,您需要一个函数来创建自定义矩形形状,可以像这样完成:
function addCustomElement(chart, x, yMin, yMax) { //yMin and yMax refers to the window, not the data
let yAxis = chart.yAxis[0]
let xAxis = chart.xAxis[0]
chart.customRect.push(chart.renderer.rect(
xAxis.toPixels(x - 0.5, false), //Leftmost pixel
yAxis.toPixels(yMax, false), //Top pixel
xAxis.toPixels(x + 0.5, false) - xAxis.toPixels(x - 0.5, false), //Width
yAxis.toPixels(yMin, false) - yAxis.toPixels(yMax, false) //Height
)
.attr({
'stroke-width': 2,
fill: 'gray',
zIndex: -1
})
.add());
}
这很好用,但是,当您调整窗口大小时,形状不会被调整大小。可以通过在redraw事件中添加一些额外的代码来解决此问题:
redraw: function() {
if (this.customRect) {
for (let i = 0; i < this.customRect.length; i++) {
this.customRect[i].destroy(); // Remove all the old rectangles before adding any new ones
}
this.customRect = [] //Empty the array of shapes
let chart = this;
setTimeout(function() { //We use a small timeout here to make sure the user is done resizing
addPlotbands(chart)
}, 100);
}
}
function addPlotbands(chart) {
let series = chart.series
let yMin = chart.yAxis[0].getExtremes().min;
let yMax = chart.yAxis[0].getExtremes().max;
for (let i = 0; i < series[0].data.length; i++) {
let allAboveZero = true;
let allBelowZero = true;
for (let j = 0; j < chart.series.length; j++) {
if (series[j].data[i].y >= 0) {
allBelowZero = false;
} else {
allAboveZero = false;
}
}
if (allAboveZero) {
addCustomElement(chart, i, 0, yMax)
} else if (allBelowZero) {
addCustomElement(chart, i, yMin, 0)
} else {
addCustomElement(chart, i, yMin, yMax)
}
}
}
function addCustomElement(chart, x, yMin, yMax) {
let yAxis = chart.yAxis[0]
let xAxis = chart.xAxis[0]
chart.customRect.push(chart.renderer.rect(
xAxis.toPixels(x - 0.5, false), //Leftmost pixel
yAxis.toPixels(yMax, false), //Topmost pixel
xAxis.toPixels(x + 0.5, false) - xAxis.toPixels(x - 0.5, false), //Width
yAxis.toPixels(yMin, false) - yAxis.toPixels(yMax, false) //Height
)
.attr({
'stroke-width': 2,
fill: 'gray',
zIndex: -1
})
.add());
}
Highcharts.chart('container', {
chart: {
type: 'column',
events: {
load: function() {
this.customRect = []
addPlotbands(this);
},
redraw: function() {
if (this.customRect) {
for (let i = 0; i < this.customRect.length; i++) {
this.customRect[i].destroy();
}
this.customRect = []
let chart = this;
setTimeout(function() {
addPlotbands(chart)
}, 100);
}
}
}
},
title: {
text: 'Column chart with negative values'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas'],
},
credits: {
enabled: false
},
series: [{
name: 'John',
data: [5, 3, 4, 7, 2, -3],
}, {
name: 'Jane',
data: [2, -2, -2, 2, 1, -1]
}, {
name: 'Joe',
data: [3, 4, 4, -2, 5, -2]
}]
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
工作中的JSFiddle示例: https://jsfiddle.net/ewolden/gbrjd2uk/
答案 1 :(得分:0)
除了使用plotBands外,您还可以创建(由Highcharts SVGRenderer创建)白色矩形,以覆盖plotBands的多余部分。您可以在下面找到此解决方案的响应示例:
events: {
render: function() {
var chart = this,
yAxis = chart.yAxis[0],
xAxis = chart.xAxis[0],
minPxY = yAxis.toPixels(yAxis.min),
zeroPxY = yAxis.toPixels(0),
series = chart.series,
i,
j,
xValue,
startCategory,
endCategory,
hasNegative;
if (chart.correctedPlotBand) {
Highcharts.each(chart.correctedPlotBand, function(el) {
el.destroy();
});
chart.correctedPlotBand = [];
} else {
chart.correctedPlotBand = [];
}
for (i = 0; i < series[0].points.length; i++) {
hasNegative = false;
for (j = 0; j < series.length; j++) {
if (series[j].points[i].y < 0) {
hasNegative = true;
}
}
if (!hasNegative) {
xValue = series[0].points[i].x;
startCategory = xAxis.toPixels(xValue - 0.5) - 1;
endCategory = Math.ceil(xAxis.toPixels(xValue + 0.5));
chart.correctedPlotBand.push(chart.renderer.rect(startCategory, zeroPxY, endCategory - startCategory, minPxY - zeroPxY)
.attr({
fill: '#fff',
zIndex: 0
})
.add())
}
}
}
}
实时演示:https://jsfiddle.net/BlackLabel/sm1kev4t/
API参考:https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#rect