Я пытаюсь добавить стрелку в конец моей диаграммы Highcharts. Я уже просмотрел similar questions но решения не похоже на работу:Как нарисовать стрелки на линейной диаграмме с Highcharts?
В результате я ищу (добавлено в цветах),
Я пытаюсь добавить стрелку в конец моей диаграммы Highcharts. Я уже просмотрел similar questions но решения не похоже на работу:Как нарисовать стрелки на линейной диаграмме с Highcharts?
В результате я ищу (добавлено в цветах),
Вы должны обернуть метод drawGraph и добавьте код для стрелки. Он может быть реализован методом пути.
(function(H) {
H.wrap(H.Series.prototype, 'drawGraph', function(proceed) {
// Now apply the original function with the original arguments,
// which are sliced off this function's arguments
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
var arrowLength = 15,
arrowWidth = 9,
series = this,
data = series.data,
len = data.length,
segments = data,
lastSeg = segments[segments.length - 1],
path = [];
var lastPoint = null;
var nextLastPoint = null;
if (lastSeg.y == 0) {
lastPoint = segments[segments.length - 2];
nextLastPoint = segments[segments.length - 1];
} else {
lastPoint = segments[segments.length - 1];
nextLastPoint = segments[segments.length - 2];
}
var angle = Math.atan((lastPoint.plotX - nextLastPoint.plotX)/
(lastPoint.plotY - nextLastPoint.plotY));
if (angle < 0) angle = Math.PI + angle;
path.push('M', lastPoint.plotX, lastPoint.plotY);
if (lastPoint.plotX > nextLastPoint.plotX) {
path.push(
'L',
lastPoint.plotX + arrowWidth * Math.cos(angle),
lastPoint.plotY - arrowWidth * Math.sin(angle)
);
path.push(
lastPoint.plotX + arrowLength * Math.sin(angle),
lastPoint.plotY + arrowLength * Math.cos(angle)
);
path.push(
lastPoint.plotX - arrowWidth * Math.cos(angle),
lastPoint.plotY + arrowWidth * Math.sin(angle),
'Z'
);
} else {
path.push(
'L',
lastPoint.plotX - arrowWidth * Math.cos(angle),
lastPoint.plotY + arrowWidth * Math.sin(angle)
);
path.push(
lastPoint.plotX - arrowLength * Math.sin(angle),
lastPoint.plotY - arrowLength * Math.cos(angle)
);
path.push(
lastPoint.plotX + arrowWidth * Math.cos(angle),
lastPoint.plotY - arrowWidth * Math.sin(angle),
'Z'
);
}
series.chart.renderer.path(path)
.attr({
fill: series.color
})
.add(series.group);
});
}(Highcharts));
Пример:
(ОБНОВЛЕНИЕ)
Предыдущее решение не является достаточно отзывчивым, поскольку он перерисовывает стрелку на графике каждый раз, когда размер браузера изменяется.
Однако я узнал, как сделать диаграмму со стрелкой полностью отзывчивым:
(function(H) {
var arrowCheck = false,
pathTag;
H.wrap(H.Series.prototype, 'drawGraph', function(proceed) {
// Now apply the original function with the original arguments,
// which are sliced off this function's arguments
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
var arrowLength = 15,
arrowWidth = 9,
series = this,
data = series.data,
len = data.length,
segments = data,
lastSeg = segments[segments.length - 1],
path = [],
lastPoint = null,
nextLastPoint = null;
if (lastSeg.y == 0) {
lastPoint = segments[segments.length - 2];
nextLastPoint = segments[segments.length - 1];
} else {
lastPoint = segments[segments.length - 1];
nextLastPoint = segments[segments.length - 2];
}
var angle = Math.atan((lastPoint.plotX - nextLastPoint.plotX)/
(lastPoint.plotY - nextLastPoint.plotY));
if (angle < 0) angle = Math.PI + angle;
path.push('M', lastPoint.plotX, lastPoint.plotY);
if (lastPoint.plotX > nextLastPoint.plotX) {
if (arrowCheck === true) {
pathTag = document.getElementById("arrow");
if (pathTag != null) {
pathTag.remove(pathTag);
}
}
path.push(
'L',
lastPoint.plotX + arrowWidth * Math.cos(angle),
lastPoint.plotY - arrowWidth * Math.sin(angle)
);
path.push(
lastPoint.plotX + arrowLength * Math.sin(angle),
lastPoint.plotY + arrowLength * Math.cos(angle)
);
path.push(
lastPoint.plotX - arrowWidth * Math.cos(angle),
lastPoint.plotY + arrowWidth * Math.sin(angle),
'Z'
);
} else {
if (arrowCheck === true) {
pathTag = document.getElementById("arrow");
if (pathTag != null) {
pathTag.remove(pathTag);
}
}
path.push(
'L',
lastPoint.plotX - arrowWidth * Math.cos(angle),
lastPoint.plotY + arrowWidth * Math.sin(angle)
);
path.push(
lastPoint.plotX - arrowLength * Math.sin(angle),
lastPoint.plotY - arrowLength * Math.cos(angle)
);
path.push(
lastPoint.plotX + arrowWidth * Math.cos(angle),
lastPoint.plotY - arrowWidth * Math.sin(angle),
'Z'
);
}
series.chart.renderer.path(path)
.attr({
fill: series.color,
id: 'arrow'
})
.add(series.group);
arrowCheck = true;
});
}(Highcharts));
Надеюсь это поможет. Ура!
Это не работает в IE 11 или ниже Вы можете изменить pathTag.remove (pathTag); - pathTag.parentNode.removeChild (pathTag); – russelrillema
Отличная помощь для меня!
Одно примечание, код выше работает только в том случае, если на графике имеется только одна серия. Я сделал несколько изменений, которые позволяют работать с несколькими сериями. Проблема заключалась в том, что, поскольку каждая стрелка имела одинаковый идентификатор, она бы уничтожила предыдущие стрелки для других серий, считая, что это старые стрелки, которые нужно перерисовать. Все, что я сделал, это изменить идентификатор, чтобы быть комбо «стрелки» и названия серии, поэтому он только уничтожает предыдущие стрелки для конкретной серии.
(function(H) {
var arrowCheck = false,
pathTag;
H.wrap(H.Series.prototype, 'drawGraph', function(proceed) {
// Now apply the original function with the original arguments,
// which are sliced off this function's arguments
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
// used a bit of regex to clean up the series name enough to be used as an id
var arrowName = "arrow"+this.name.replace(/\W/g,"_").toLowerCase();
// console.log("----------->arrowName:"+arrowName)
var arrowLength = 15,
arrowWidth = 7,
series = this,
data = series.data,
len = data.length,
segments = data,
lastSeg = segments[segments.length - 1],
path = [],
lastPoint = null,
nextLastPoint = null;
if (lastSeg.y == 0) {
lastPoint = segments[segments.length - 2];
nextLastPoint = segments[segments.length - 1];
} else {
lastPoint = segments[segments.length - 1];
nextLastPoint = segments[segments.length - 2];
}
var angle = Math.atan((lastPoint.plotX - nextLastPoint.plotX)/
(lastPoint.plotY - nextLastPoint.plotY));
if (angle < 0) angle = Math.PI + angle;
path.push('M', lastPoint.plotX, lastPoint.plotY);
if (lastPoint.plotX > nextLastPoint.plotX) {
if (arrowCheck === true) {
//replaced 'arrow' with arrowName
pathTag = document.getElementById(arrowName);
if (pathTag != null) {
pathTag.remove(pathTag);
}
}
path.push(
'L',
lastPoint.plotX + arrowWidth * Math.cos(angle),
lastPoint.plotY - arrowWidth * Math.sin(angle)
);
path.push(
lastPoint.plotX + arrowLength * Math.sin(angle),
lastPoint.plotY + arrowLength * Math.cos(angle)
);
path.push(
lastPoint.plotX - arrowWidth * Math.cos(angle),
lastPoint.plotY + arrowWidth * Math.sin(angle),
'Z'
);
} else {
if (arrowCheck === true) {
//replaced 'arrow' with arrowName
pathTag = document.getElementById(arrowName);
if (pathTag != null) {
pathTag.remove(pathTag);
}
}
path.push(
'L',
lastPoint.plotX - arrowWidth * Math.cos(angle),
lastPoint.plotY + arrowWidth * Math.sin(angle)
);
path.push(
lastPoint.plotX - arrowLength * Math.sin(angle),
lastPoint.plotY - arrowLength * Math.cos(angle)
);
path.push(
lastPoint.plotX + arrowWidth * Math.cos(angle),
lastPoint.plotY - arrowWidth * Math.sin(angle),
'Z'
);
}
series.chart.renderer.path(path)
.attr({
fill: series.color,
id: arrowName //changed from 'arrow' to arrowName to enable more than one series with an arrow
})
.add(series.group);
arrowCheck = true;
});
}(Highcharts));
Linted/очищены версия ответа jmfeland с двумя серии
http://jsfiddle.net/vyfsf1ft/18/
$(function() {
(function(H) {
var arrowCheck = false
var pathTag
H.wrap(H.Series.prototype, 'drawGraph', function(proceed) {
// Apply the original function with the original arguments,
// which are sliced off this function's arguments
var series = this
proceed.apply(series, Array.prototype.slice.call(arguments, 1))
var arrowName = 'arrow' + series.name.replace(/\W/g, '_').toLowerCase()
var arrowLength = 15
var arrowWidth = 7
var data = series.data
var len = data.length
var lastSeg = data[len - 1]
var path = []
var lastPoint = null
var nextLastPoint = null
if (lastSeg.y == 0) {
lastPoint = data[len - 2]
nextLastPoint = data[len - 1]
} else {
lastPoint = data[len - 1]
nextLastPoint = data[len - 2]
}
var angle = Math.atan((lastPoint.plotX - nextLastPoint.plotX)/
(lastPoint.plotY - nextLastPoint.plotY))
if (angle < 0) angle = Math.PI + angle
path.push('M', lastPoint.plotX, lastPoint.plotY)
if (lastPoint.plotX > nextLastPoint.plotX) {
if (arrowCheck === true) {
pathTag = document.getElementById(arrowName)
if (pathTag != null) {
pathTag.remove(pathTag)
}
}
path.push(
'L',
lastPoint.plotX + arrowWidth * Math.cos(angle),
lastPoint.plotY - arrowWidth * Math.sin(angle)
)
path.push(
lastPoint.plotX + arrowLength * Math.sin(angle),
lastPoint.plotY + arrowLength * Math.cos(angle)
)
path.push(
lastPoint.plotX - arrowWidth * Math.cos(angle),
lastPoint.plotY + arrowWidth * Math.sin(angle),
'Z'
)
} else {
if (arrowCheck === true) {
pathTag = document.getElementById(arrowName)
if (pathTag != null) {
pathTag.remove(pathTag)
}
}
path.push(
'L',
lastPoint.plotX - arrowWidth * Math.cos(angle),
lastPoint.plotY + arrowWidth * Math.sin(angle)
)
path.push(
lastPoint.plotX - arrowLength * Math.sin(angle),
lastPoint.plotY - arrowLength * Math.cos(angle)
)
path.push(
lastPoint.plotX + arrowWidth * Math.cos(angle),
lastPoint.plotY - arrowWidth * Math.sin(angle),
'Z'
)
}
series.chart.renderer.path(path)
.attr({
fill: series.color,
id: arrowName,
})
.add(series.group)
arrowCheck = true
})
}(Highcharts))
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
defaultSeriesType: 'scatter'
},
xAxis: {
min: 0,
max: 10
},
plotOptions: {
series: {
animation: {
duration: 2000
},
lineWidth: 2,
marker: {
enabled: false
}
},
states: {
hover: {
enabled: true,
lineWidth: 2
},
}
},
series: [{
name: 'main',
id: 'main',
data: [
[0, 0],
[3, 4]
]
}, {
name: 'secondary',
id: 'secondary',
data: [
[1, 0],
[5, 8]
]
}]
})
})
Он работает отлично. Большое спасибо –
Это похоже на стрелку в конце строки. Это очень полезно, но было бы более точным (посмотрите, как отлично и нравится это), если стрелка указана на последней точке данных, которая будет нанесена на график. – russelrillema
Я столкнулся с новой проблемой; Я использую эту стрелку Highcharts на графике рядом с другим графиком Highcharts (разделенным вкладками навигации) на той же веб-странице ASP.NET. Все мои файлы JS визуализируются вместе, и каким-то образом стрелка из одной диаграммы исчезает, если я обновляю данные с другого графика (на другой вкладке). Попросите кого-нибудь представить, как это можно решить? –