2016-07-15 2 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

Это похоже на стрелку в конце строки. Это очень полезно, но было бы более точным (посмотрите, как отлично и нравится это), если стрелка указана на последней точке данных, которая будет нанесена на график. – russelrillema

+0

Я столкнулся с новой проблемой; Я использую эту стрелку Highcharts на графике рядом с другим графиком Highcharts (разделенным вкладками навигации) на той же веб-странице ASP.NET. Все мои файлы JS визуализируются вместе, и каким-то образом стрелка из одной диаграммы исчезает, если я обновляю данные с другого графика (на другой вкладке). Попросите кого-нибудь представить, как это можно решить? –

2

(ОБНОВЛЕНИЕ)

Предыдущее решение не является достаточно отзывчивым, поскольку он перерисовывает стрелку на графике каждый раз, когда размер браузера изменяется.

Однако я узнал, как сделать диаграмму со стрелкой полностью отзывчивым:

(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

Отличная помощь для меня!

Одно примечание, код выше работает только в том случае, если на графике имеется только одна серия. Я сделал несколько изменений, которые позволяют работать с несколькими сериями. Проблема заключалась в том, что, поскольку каждая стрелка имела одинаковый идентификатор, она бы уничтожила предыдущие стрелки для других серий, считая, что это старые стрелки, которые нужно перерисовать. Все, что я сделал, это изменить идентификатор, чтобы быть комбо «стрелки» и названия серии, поэтому он только уничтожает предыдущие стрелки для конкретной серии.

(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] 
     ] 
    }] 
    }) 
}) 
Смежные вопросы