Я использую angular6 и угловую оболочку office highcharts (https://github.com/highcharts/highcharts-угловой) в версии 2.4.0.
Все работает хорошо, кроме меток, которые можно разместить на графике вручную.
Я просто не успеваю их обновлять.
У меня есть график, который можно фильтровать через серверную часть. Когда я получаю новые сгенерированные данные, я обновляю данные в своих диаграммах, которые используются в html как [options] = "chartOptions" для углового компонента.
ChartOptions создается из моего класса по умолчанию следующим образом: this.chartOptions = new GraphConfigSeqAtteptedVsAchived().chartOptions;
Класс выглядит так: `импортировать * как Highcharts из 'highcharts';
класс экспорта GraphConfigSeqAtteptedVsAchived{ публичный график. Варианты: любые;
constructor(){
this.chartOptions = {
chart: {
height: 600,
width: 620,
events:{load: function(){
this.myTooltip = new Highcharts.Tooltip(this, this.options.tooltip);
}
},
backgroundColor: 'transparent',
},
credits: {
text: 'charname',
href: ''
},
labels: {
},
exporting:{
chartOptions:{
title: {
text:'not set',
style:{
color: '#000000'
},
margin: 0
}
}
},
tooltip: {
enabled: false
},
xAxis: {
min: -10,
max: 0,
width: 535,
title: {
text: 'Rainfall (mm)',
style: {
fontWeight: "bold",
color: '#000000'
}
},
reversed: true,
tickInterval: 1
},
yAxis: {
min: -10,
max: 0,
title: {
text: 'Rainfall (mm)',
style: {
fontWeight: "bold",
color: '#000000'
}
},
reversed: true,
tickInterval: 1
},
title: {
text: ' as',
margin: 0,
style:{
color: 'transparent'
}
},
legend: {
layout: 'vertical',
align: 'left',
verticalAlign: 'top',
x: 100,
y: 90,
floating: true,
backgroundColor: '#FFFFFF',
borderWidth: 1,
navigation: {
enabled: false
}
},
plotOptions: {
scatter: {
stickyTracking: false,
allowPointSelect: true,
marker: {
radius: 3,
states: {
hover: {
enabled: true,
lineColor: 'rgb(100,100,100)'
}
}
},
tooltip: {
headerFormat: '<b>{series.name}</b><br>',
pointFormat: '',
hideDelay: 500
},
symbol: "circle",
events: {
mouseOut: function() {
this.chart.myTooltip.hide();
this.chart.myTooltip.options.enabled = false;
},
mouseOver: function() {
if (this.halo) {
this.halo.attr({
'class': 'highcharts-tracker'
}).toFront();
}
},
click: function(event) {
this.chart.myTooltip.options.enabled = true;
this.chart.myTooltip.refresh(event.point, event);
}
}
},
line:{
events: {
legendItemClick: function () {
return false;
}
}
},
series:{
allowPointSelect: true
}
},
series: [{
type: 'line',
data: [[30, 30], [-30, -30]],
marker: {
enabled: false
},
states: {
hover: {
lineWidth: 1
}
},
showInLegend: false,
color: "rgba(0, 0, 0, 0.6)",
enableMouseTracking: false
},{
type: 'line',
data: [[30, 29.5], [-29.5, -30]],
marker: {
enabled: false
},
states: {
hover: {
lineWidth: 0
}
},
showInLegend: false,
dashStyle: 'ShortDash',
color: "rgba(125, 162, 159, 0.35)",
enableMouseTracking: false
},{
type: 'line',
data: [[29.5, 30], [-30, -29.5]],
marker: {
enabled: false
},
states: {
hover: {
lineWidth: 0
}
},
showInLegend: false,
dashStyle: 'ShortDash',
color: "rgba(125, 162, 159, 0.35)",
enableMouseTracking: false
},{
type: 'line',
data: [[29, 30], [-30, -29]],
marker: {
enabled: false
},
states: {
hover: {
lineWidth: 0
}
},
showInLegend: false,
dashStyle: 'ShortDash',
color: "rgba(197, 144, 161, 0.35)",
enableMouseTracking: false
},{
type: 'line',
data: [[30, 29], [-29, -30]],
marker: {
enabled: false
},
states: {
hover: {
lineWidth: 0
}
},
showInLegend: false,
dashStyle: 'ShortDash',
color: "rgba(197, 144, 161, 0.35)",
enableMouseTracking: false
}]
}
}
}`
Сгенерированные данные динамически добавляются в машинописный текст, и все это прекрасно работает. Все обновляется после того, как я установил updateFlag для [(update)] = "updateGraph". Названия осей тоже в порядке.
Единственное, что у меня не обновляется, это метки, которые я динамически добавляю на диаграмму, например:
let labelTotalNumberOfEyes = {
html : this.translate.instant('GRAPHS.TOTAL_NUMBER_OF_EYES') + ': ' + (scatterSeries.data.length + scatterSeriesRetreatment.data.length),
style : {
left : '330px',
top : '368px',
fontSize : '14px',
backgroundColor: '#FFFFFF',
borderWidth: 1,
}
}
this.chartOptions.labels.items.push(labelTotalNumberOfEyes);
Кто-нибудь знает, что я могу делать неправильно? Я не вижу другого варианта, кроме как просто установить этот флаг обновления, и он отлично работает для всего, кроме меток.
Пожалуйста, дайте мне знать, если вам не хватает какой-либо информации.
Заранее спасибо.
К сожалению, угловая оболочка не имеет такой возможности. Они реализовали для него флаг обновления, но, похоже, это работает только для серии и оси. Таким образом, chart.redraw() не подходит для этой настройки.
Не могли бы вы как-то воспроизвести это в онлайн-редакторе кода, таком как codeandbox или stackblitz? Вы можете использовать эту демонстрацию в качестве шаблона: codeandbox.io/s/543l0p0qq4.
Спасибо за хорошо подготовленный шаблон @WojciechChmiel. Я адаптировал шаблон и просто добавил одну метку и отредактировал текст в функции обновления символов. Вы можете видеть, что метка не изменилась, а все остальное. Вот именно такая проблема и у меня. Вот моя измененная версия codeandbox.io/s/l22jr69wjq



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Эта проблема на самом деле является ошибкой Highcharts. Я сообщил об этом здесь: https://github.com/highcharts/highcharts/issues/10429.
В качестве обходного пути вы можете использовать Highcharts.SVGRenderer, чтобы добавить пользовательскую метку и сохранить ссылку на нее в своем компоненте. Далее при обновлении вызовите метод attr() на метке (Highcharts.SVGElement) и установите новые параметры. Проверьте демо и код, размещенные ниже.
Добавьте метку обратного вызова диаграммы:
constructor() {
const self = this;
this.chartCallback = chart => {
self.chart = chart;
self.label = chart.renderer
.text("test", 100, 100)
.css({
fill: "#555",
fontSize: 16
})
.add()
.toFront();
};
}
вызовите attr() на метке при обновлении:
update_chart() {
const self = this,
chart = this.chart;
chart.showLoading();
setTimeout(() => {
chart.hideLoading();
self.chartOptions.series = [
{
data: [10, 25, 15],
name: "updatedSerieName"
}
];
self.chartOptions.yAxis.title.text = "updatedData";
self.label
.attr({
text: "test1",
x: 150,
y: 120
})
.css({
fill: "red",
fontSize: 20
});
self.updateFromInput = true;
}, 2000);
}
Демо:
Ссылка на API:
https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#text
https://api.highcharts.com/class-reference/Highcharts.SVGElement#attr
Большое спасибо @WojciechChmiel. Тогда я попробую на этой неделе и дам вам знать, сработало ли это для моей цели.
ваше предложение сработало нормально, но в конце концов я переключился на новые аннотации Highcharts, как указано в сообщении об ошибке: github.com/highcharts/highcharts/issues/10429
chart.redraw()?