Highcharts 更新分组系列数据点颜色
Highcharts Update Grouped Series Data Point Colors
我有一个类似于 here, but with custom colors for the volume bars and candlesticks. This works fine until the graph is redrawn or grouped due to new data being added or a range selector button press. When the graph is redrawn or grouped, neither the candle color nor the volume bar color seems to be transferring properly. I'm using the following redraw function, but it does not seem to be having any effect. Strangely, each time the data is grouped in a new data grouping, the volume bars will display the correct color when you hover over them, and will stay the correct color until the graph is redrawn. Here 的烛台和交易量图表是显示这种情况的 fiddle。我的重绘功能如下。
编辑:如果 fiddle 出现 500 错误,请尝试 here
有什么方法可以解决这个问题或得到它以便我可以正确绘制颜色吗?
const redraw = (event) => {
const chartTarget = event.target;
if (chartTarget.series[0].hasGroupedData) {
// Get all the candlesticks that are shown
const candlesticks = chartTarget.series[0].points;
// Get all the volume bards that are shown
const volumeBars = chartTarget.series[1].points;
// Go through the candle chart and volume points and update the colors
for (let i = 0; i < candlesticks.length; i++) {
const candle = candlesticks[i];
const volumeBar = volumeBars[i];
if (candle.close > candle.open) {
const color = 'green';
volumeBar.color = color;
candle.color = color;
} else if (candle.close < candle.open) {
const color = 'red';
candle.color = color;
volumeBar.color = color;
}
}
}
};
整个周末我都在为同一个问题苦苦思索。我根本不是高级图表专家,但这是我想出的。它的灵感来自这个 question and this question.
fiddle 的相关部分是:
Highcharts.stockChart('container', {
chart: {
events: {
load: function(event) {
// Get the volume series by id.
var volSeries = this.series.find(function(s) {
return s.userOptions.id === 'volume';
});
// Override the pointAttribs function on the volume series.
volSeries.pointAttribs = (function(original) {
return function(point, state) {
// Call the original pointAttribs function.
var attribs = original.apply(this, arguments);
// Get the price series using the id.
var priceSeries = point.series.chart.series.find(function(s) {
return s.userOptions.id === 'price';
});
// Find the candle corresponding to the current volume point.
var candle;
if (point.series.hasGroupedData) {
// With grouped data, we need to find the candle from the grouped data.
var datagroup = point.dataGroup;
var groupIdx = point.series.groupMap.indexOf(datagroup);
candle = priceSeries.groupedData[groupIdx];
} else {
// Non-grouped data, we can just use the normal data.
candle = priceSeries.data[point.index];
}
// Choose the color for the volume point based on the candle properties.
var color = 'blue';
if (candle.close > candle.open) {
color = 'green';
} else if (candle.close < candle.open) {
color = 'red';
}
// Set the volume point's attribute(s) accordingly.
attribs.fill = color;
// Return the updated attributes.
return attribs;
};
})(volSeries.pointAttribs);
// Need to call update so the changes get taken into account on first draw.
this.update({});
}
}
},
...
基本上,我们覆盖体积系列上的 pointAttribs function,以便我们可以进行颜色计算。 pointAttribs 函数是一个内部函数,因此使用风险自负。
在性能方面,这应该不会太昂贵 - 对于非分组数据,它使用预先存在的索引;对于分组数据,它必须在 series.groupMap 上使用 indexOf 来获取索引。
卷系列颜色设置为标准 candlestick options - "color" 和 "upColor",还有 "lineColor" 和 "upLineColor" 选项可用。
如果您使用此 post 中的解决方案,似乎一切正常:
const color = 'green';
volumeBar.graphic.css({
color: color
});
candle.graphic.css({
color: color
});
我有一个类似于 here, but with custom colors for the volume bars and candlesticks. This works fine until the graph is redrawn or grouped due to new data being added or a range selector button press. When the graph is redrawn or grouped, neither the candle color nor the volume bar color seems to be transferring properly. I'm using the following redraw function, but it does not seem to be having any effect. Strangely, each time the data is grouped in a new data grouping, the volume bars will display the correct color when you hover over them, and will stay the correct color until the graph is redrawn. Here 的烛台和交易量图表是显示这种情况的 fiddle。我的重绘功能如下。
编辑:如果 fiddle 出现 500 错误,请尝试 here
有什么方法可以解决这个问题或得到它以便我可以正确绘制颜色吗?
const redraw = (event) => {
const chartTarget = event.target;
if (chartTarget.series[0].hasGroupedData) {
// Get all the candlesticks that are shown
const candlesticks = chartTarget.series[0].points;
// Get all the volume bards that are shown
const volumeBars = chartTarget.series[1].points;
// Go through the candle chart and volume points and update the colors
for (let i = 0; i < candlesticks.length; i++) {
const candle = candlesticks[i];
const volumeBar = volumeBars[i];
if (candle.close > candle.open) {
const color = 'green';
volumeBar.color = color;
candle.color = color;
} else if (candle.close < candle.open) {
const color = 'red';
candle.color = color;
volumeBar.color = color;
}
}
}
};
整个周末我都在为同一个问题苦苦思索。我根本不是高级图表专家,但这是我想出的。它的灵感来自这个 question and this question.
fiddle 的相关部分是:
Highcharts.stockChart('container', {
chart: {
events: {
load: function(event) {
// Get the volume series by id.
var volSeries = this.series.find(function(s) {
return s.userOptions.id === 'volume';
});
// Override the pointAttribs function on the volume series.
volSeries.pointAttribs = (function(original) {
return function(point, state) {
// Call the original pointAttribs function.
var attribs = original.apply(this, arguments);
// Get the price series using the id.
var priceSeries = point.series.chart.series.find(function(s) {
return s.userOptions.id === 'price';
});
// Find the candle corresponding to the current volume point.
var candle;
if (point.series.hasGroupedData) {
// With grouped data, we need to find the candle from the grouped data.
var datagroup = point.dataGroup;
var groupIdx = point.series.groupMap.indexOf(datagroup);
candle = priceSeries.groupedData[groupIdx];
} else {
// Non-grouped data, we can just use the normal data.
candle = priceSeries.data[point.index];
}
// Choose the color for the volume point based on the candle properties.
var color = 'blue';
if (candle.close > candle.open) {
color = 'green';
} else if (candle.close < candle.open) {
color = 'red';
}
// Set the volume point's attribute(s) accordingly.
attribs.fill = color;
// Return the updated attributes.
return attribs;
};
})(volSeries.pointAttribs);
// Need to call update so the changes get taken into account on first draw.
this.update({});
}
}
},
...
基本上,我们覆盖体积系列上的 pointAttribs function,以便我们可以进行颜色计算。 pointAttribs 函数是一个内部函数,因此使用风险自负。
在性能方面,这应该不会太昂贵 - 对于非分组数据,它使用预先存在的索引;对于分组数据,它必须在 series.groupMap 上使用 indexOf 来获取索引。
卷系列颜色设置为标准 candlestick options - "color" 和 "upColor",还有 "lineColor" 和 "upLineColor" 选项可用。
如果您使用此 post 中的解决方案,似乎一切正常:
const color = 'green';
volumeBar.graphic.css({
color: color
});
candle.graphic.css({
color: color
});