2016-07-15 188 views

回答

3

你應該換行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)); 

實施例:

+0

它完美。非常感謝你 –

+0

這似乎是在最後畫出箭頭。 這是非常有用的,但如果箭頭指向最後一個數據點被繪製的話,它會更準確(看看excel和類似工具是如何做到的)。 – russelrillema

+0

我遇到了一個新問題;我在同一個ASP.NET網頁中的另一個Highcharts圖(由導航標籤分隔)旁邊的圖上使用Highcharts箭頭。我的所有JS文件都被渲染在一起,並且在某種情況下,如果我更新另一個圖表(在另一個選項卡上)中的數據,則某個圖表中的箭頭會消失。有人知道這個問題怎麼解決? –

2

(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)); 

希望這可以幫助。乾杯!

+1

這不適用於IE 11或以下版本 您可以更改 pathTag.remove(pathTag); 至 pathTag.parentNode.removeChild(pathTag); – russelrillema

2

對我很有幫助!

需要注意的是,上面的代碼僅適用於圖形中只有一個系列的情況。我做了一些改變,讓它可以用於多個系列。問題在於,由於每個箭頭都有相同的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)); 
0

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] 
     ] 
    }] 
    }) 
})