我正在試圖在我的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));
實施例:
(UPDATE)
先前解決方案,因爲它重繪圖表上的箭頭的每一個時的時間是不太敏感瀏覽器被調整大小。
不過,我發現瞭如何使箭頭充分響應圖表:
(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
對我很有幫助!
需要注意的是,上面的代碼僅適用於圖形中只有一個系列的情況。我做了一些改變,讓它可以用於多個系列。問題在於,由於每個箭頭都有相同的ID,因此它會清除其他系列的先前箭頭,認爲它們是需要重新繪製的舊箭頭。我所做的只是將id更改爲「箭頭」和系列名稱的組合,因此它只能清除特定系列的先前箭頭。
(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]
]
}]
})
})
它完美。非常感謝你 –
這似乎是在最後畫出箭頭。 這是非常有用的,但如果箭頭指向最後一個數據點被繪製的話,它會更準確(看看excel和類似工具是如何做到的)。 – russelrillema
我遇到了一個新問題;我在同一個ASP.NET網頁中的另一個Highcharts圖(由導航標籤分隔)旁邊的圖上使用Highcharts箭頭。我的所有JS文件都被渲染在一起,並且在某種情況下,如果我更新另一個圖表(在另一個選項卡上)中的數據,則某個圖表中的箭頭會消失。有人知道這個問題怎麼解決? –