2017-07-28 273 views
0

我有兩個圖表顯示時間序列數據,我試圖同步十字線和工具提示。但是,圖表並不總是具有相同數量的數據點。這會導致十字線和工具提示在兩個圖形之間不同步。Highcharts缺少數據點的同步圖

我已啓用connectNulls: true兩者,並且這會平滑行,它不添加數據點爲他們不存在的時間段。

有沒有辦法配置connectNulls,以便它插入填充點?

enter image description here

修訂

下面是一個簡單jsFiddle例如,當值是從每天這導致十字線到2個圖形之間不同步的丟失。

+0

更新用的jsfiddle例子。 –

回答

0

要設置點之間的實際x距離,可以將xAxis.ordinal設置爲false。另一種解決方案是在空白處放置一個空值。您還可以設置pointStartpointInterval屬性。

API參考:
http://api.highcharts.com/highstock/xAxis.ordinal
http://api.highcharts.com/highstock/plotOptions.series.pointStart
http://api.highcharts.com/highstock/plotOptions.series.pointInterval

實例:
http://jsfiddle.net/csgbxdaj/ - 設置序號爲false
http://jsfiddle.net/gjxhbf7w/ - 在series.data陣列把零點

+0

雖然這些建議很棒,但我使用高圖表不高的股票。 此外,我擔心這不能解決我跨兩個不同圖形同步十字準線的問題,每個圖形都有多個系列。 –

+0

你是對的,序數屬性只在Highstock中可用,但是在數據數組中放置空值的解決方案應該可以工作。請給我提供一個可用的JSFiddle來展示這些圖表。謝謝。 –

+0

見例如: https://jsfiddle.net/jknipp/8j9wtw46/6/(使用pointStart/pointInterval用null) https://jsfiddle.net/jknipp/sp6x9vq3/6/(使用connectNulls) 通知當在8月5日或8月8日懸停在最下面的圖表中時,頂部圖表作業到最近的可用點。相反,我想讓十字線跟隨鼠標指針,但我也想在頂部圖形中顯示一個工具提示,指示沒有可用於該點的數據。 –

0

@d_paul下面是一個更新顯示接近預期的行爲,但我仍然w當頂部圖形中的十字線在底部圖形中的同一點處沒有數據時,開始防止點懸停/暈圈。

https://jsfiddle.net/jknipp/g3vr5v44/13/

// Global state variable 
 
window.isOutOfSync = false; 
 

 
/** 
 
* Override the reset function, we don't need to hide the tooltips and crosshairs. 
 
*/ 
 
Highcharts.Pointer.prototype.reset = function() { 
 
    return undefined; 
 
}; 
 

 
/** 
 
* Synchronize zooming through the setExtremes event handler. 
 
*/ 
 
function syncExtremes(e) { 
 
    var thisChart = this.chart; 
 

 
    if (e.trigger !== 'syncExtremes') { // Prevent feedback loop 
 
    Highcharts.each(Highcharts.charts, function(chart) { 
 
     if (chart !== thisChart) { 
 
     if (chart.xAxis[0].setExtremes) { // It is null while updating 
 
      chart.xAxis[0].setExtremes(e.min, e.max, undefined, false, { 
 
      trigger: 'syncExtremes' 
 
      }); 
 
     } 
 
     } 
 
    }); 
 
    } 
 
} 
 

 
/** 
 
* In order to synchronize tooltips and crosshairs, override the 
 
* built-in events with handlers defined on the parent element. 
 
*/ 
 
$('#success-graphs-container').bind('mousemove touchmove touchstart', function(e) { 
 
    var charts = Highcharts.charts.filter(function(chart) { 
 
    return (chart.title.textStr.match(/success/i)) ? chart : null; 
 
    }); 
 

 
    for (i = 0; i < charts.length; i++) { 
 
    chart = charts[i]; 
 
    e = chart.pointer.normalize(e); // Find coordinates within the chart 
 
    points = [chart.series[0].searchPoint(e, true), chart.series[1].searchPoint(e, true)]; // Get the hovered point 
 

 
    var show = function() { 
 
     if (points[0] && points[1]) { 
 
     chart.tooltip.refresh(points); // Show the tooltip 
 
     points[0].onMouseOver(); // Show the hover marker 
 
     points[1].onMouseOver(); // Show the hover marker 
 

 
     chart.xAxis[0].drawCrosshair(e, points[0]); // Show the crosshair 
 
     } 
 
    } 
 

 
    if (i == 0) { 
 
     chart2 = charts[i + 1]; 
 
     e2 = chart2.pointer.normalize(e); // Find coordinates within the chart 
 
     points2 = [chart2.series[0].searchPoint(e2, true), chart2.series[1].searchPoint(e2, true)]; 
 

 
     if (((points[0] && points[1]) && points[0].x != points2[0].x && points[1].x != points2[1].x)) { 
 
     console.log("val set " + window.isOutOfSync); 
 
     //console.log("The points are different AF!"); 
 
\t \t \t \t //if(!window.isOutOfSync) { 
 
     points[0].onMouseOut(); 
 
     points[1].onMouseOut(); 
 
     points[0].select(false); 
 
     points[1].select(false); 
 
     chart.tooltip.refresh(points); // Show the tooltip 
 
     
 
     //chart.tooltip.hide(points); // Hide the tooltip 
 
     //points[0].(); // Show the hover marker 
 
     //points[1].onMouseOut(); // Show the hover marker 
 

 
     chart.xAxis[0].drawCrosshair(e, points[0]); // Show the crosshair 
 
\t \t \t \t window.isOutOfSync = true; 
 
     //} 
 
     } else { 
 
     window.isOutOfSync = false 
 
     show(); 
 
     } 
 

 
    } else { 
 
     show(); 
 
    } 
 

 
    } 
 
}); 
 

 
// Remove tool tips when the user leaves the container 
 
// We do this for all charts because we had to override the reset function 
 
$('#success-graphs-container').bind('mouseleave', function(e) { 
 
    Highcharts.each(Highcharts.charts, function(chart) { 
 
    var event = chart.pointer.normalize(e.originalEvent); 
 
    var point = chart.series[0].searchPoint(event, true); 
 

 

 
    if (point) { 
 
     point.onMouseOut(); 
 
     chart.tooltip.hide(point); 
 
     chart.xAxis[0].hideCrosshair(); 
 
    } 
 
    }); 
 
}); 
 

 

 

 
function formatSuccessRateToolTip(pointValue, isSuccessful) { 
 
    var text = (isSuccessful) ? "Success" : "Failure"; 
 
    var style = (isSuccessful) ? "color:#1EC06A; font-family: BentonSans Medium, sans-serif;" : "color:#E23C3F; font-family: BentonSans Medium, sans-serif;"; 
 
    // Use whole numbers if no decimal places to report 
 
    var decimalPlaces = (Number(pointValue) === pointValue && pointValue % 1 === 0) ? 0 : 1; 
 
    return "<span style=\"" + style + "\">" + Highcharts.numberFormat(pointValue, decimalPlaces, ".", ",") + "% " + text + "</span>"; 
 
} 
 

 
var App = { 
 
    renderSubsetSuccessRateChart: function renderSubsetSuccessRateChart(container) { 
 
    Highcharts.chart(container, { 
 
     chart: { 
 
     renderTo: container, 
 
     type: 'areaspline', 
 
     height: '220', 
 
     spacingBottom: 20, 
 
     spacingTop: 20, 
 
     spacingLeft: 20, 
 
     spacingRight: 20 
 
     }, 
 
     title: { 
 
     align: 'center', 
 
     text: 'Your Success Rate', 
 
     margin: 10, 
 
     style: { 
 
      fontFamily: '\'BentonSans Medium\', sans-serif', 
 
      fontSize: '14px' 
 
     } 
 
     }, 
 
     xAxis: { 
 
     type: 'datetime', 
 
     crosshair: { 
 
      zIndex: 4, 
 
      snap: false 
 
     }, 
 
     events: { 
 
      setExtremes: syncExtremes 
 
     }, 
 
     }, 
 
     yAxis: { 
 
     title: { 
 
      text: '' 
 
     }, 
 
     min: 0, 
 
     max: 100 
 
     }, 
 
     legend: { 
 
     enabled: true, 
 
     align: 'left' 
 
     }, 
 
     plotOptions: { 
 
     series: { 
 
      connectNulls: true, 
 
      fillOpacity: 1, 
 
      stacking: 'normal', 
 
      //stickyTracking: true, 
 
      point: { 
 
      events: { 
 
       mouseOver: function(e) { 
 
       /* 
 
       var chart = this.series.chart; 
 
       e = chart.pointer.normalize(e); // Find coordinates within the chart 
 
       console.log("here"); 
 
       points = [chart.series[0].searchPoint(e, true), chart.series[1].searchPoint(e, true)]; // Get the hovered point 
 
\t \t \t \t \t 
 
        var chart2 = $("#total_success_rates").highcharts(); 
 
        var e2 = chart2.pointer.normalize(e); // Find coordinates within the chart 
 
        var points2 = [chart2.series[0].searchPoint(e2, true), chart2.series[1].searchPoint(e2, true)]; 
 
\t \t \t \t \t \t \t \t \t 
 
        console.log(points); 
 
\t \t \t \t \t \t \t \t \t console.log(points2); 
 
        if (points[0].x != points2[0].x && points[1].x != points2[1].x) { 
 
        console.log("The points are different AF!"); 
 
        chart.tooltip.hide(points); // Show the tooltip 
 
        points[0].onMouseOut(); // Don't hover marker 
 
        \t points[1].onMouseOut(); // Don't hover marker 
 
        } 
 
        */ 
 
       } 
 
      } 
 
      }, 
 
      events: { 
 
      mouseOut: function() { 
 
       //console.log("mouse out"); 
 
      } 
 
      } 
 
     } 
 
     }, 
 
     series: [{ 
 
     name: "Failure", 
 
     data: [ 
 
      [Date.UTC(2017, 7, 1), 20], 
 
      [Date.UTC(2017, 7, 2), 25], 
 
      [Date.UTC(2017, 7, 3), 24], 
 
      [Date.UTC(2017, 7, 4), 7], 
 
      [Date.UTC(2017, 7, 6), 0], 
 
      [Date.UTC(2017, 7, 7), 35], 
 
      [Date.UTC(2017, 7, 9), 12], 
 
      [Date.UTC(2017, 7, 10), 10] 
 
     ], 
 
     color: '#1C81C6', 
 
     lineColor: 'none', 
 
     legendIndex: 1 
 
     }, { 
 
     name: 'Success', 
 
     data: [ 
 
      [Date.UTC(2017, 7, 1), 80], 
 
      [Date.UTC(2017, 7, 2), 75], 
 
      [Date.UTC(2017, 7, 3), 76], 
 
      [Date.UTC(2017, 7, 4), 93], 
 
      [Date.UTC(2017, 7, 6), 100], 
 
      [Date.UTC(2017, 7, 7), 65], 
 
      [Date.UTC(2017, 7, 9), 88], 
 
      [Date.UTC(2017, 7, 10), 90] 
 
     ], 
 
     color: '#E2EFF8', 
 
     lineColor: 'none', 
 
     legendIndex: 0 
 
     }], 
 
     tooltip: { 
 
     padding: 12, 
 
     shared: true, 
 
     borderWidth: 2, 
 
     borderRadius: 3, 
 
     //snap: 0, 
 
     style: { 
 
      fontSize: '12px', 
 
      fontFamily: '\'BentonSans\', sans-serif' 
 
     }, 
 
     formatter: function(tooltip) { 
 
      var header, 
 
      s = []; 
 

 
      console.log(window.isOutOfSync); 
 
      if (window.isOutOfSync) { 
 
      console.log("don't show tooltip"); 
 
      //return false; 
 
      return "No data"; 
 
      } 
 

 
      $.each(this.points, function(i, point) { 
 

 
      // check to see if the point is in the overall graph 
 
      //var overallChart = $("#total_success_rates").highcharts(); 
 
      //console.log(overallChart); 
 

 
      var isSuccessRate = (point.series.name == 'Success'); 
 

 
      if (header == null) { 
 
       var config = point.point.getLabelConfig(); 
 
       header = tooltip.tooltipFooterHeaderFormatter(config); 
 
      } 
 
      s.push(formatSuccessRateToolTip(point.y, isSuccessRate)); 
 
      // $("#" + point.series.name.toLowerCase() + "-rate").html(point.y + "%"); 
 
      }); 
 

 
      return header + s.reverse().join('<br>'); 
 
     }, 
 
     shared: true 
 
     }, 
 
    }); 
 
    }, 
 
    renderTotalSuccessRateChart: function renderTotalSuccessRateChart(container) { 
 
    Highcharts.chart(container, { 
 
     chart: { 
 
     renderTo: container, 
 
     type: 'areaspline', 
 
     height: '220', 
 
     spacingBottom: 20, 
 
     spacingTop: 20, 
 
     spacingLeft: 20, 
 
     spacingRight: 20, 
 
     }, 
 
     title: { 
 
     align: 'center', 
 
     text: "Overall Success Rate", 
 
     margin: 10, 
 
     style: { 
 
      fontFamily: '\'BentonSans Medium\', sans-serif', 
 
      fontSize: '14px' 
 
     } 
 
     }, 
 
     xAxis: { 
 
     type: 'datetime', 
 
     crosshair: { 
 
      zIndex: 4, 
 
      snap: false 
 
     }, 
 
     events: { 
 
      setExtremes: syncExtremes 
 
     }, 
 
     }, 
 
     yAxis: { 
 
     title: { 
 
      text: '' 
 
     }, 
 
     min: 0, 
 
     max: 100 
 
     }, 
 
     legend: { 
 
     enabled: true, 
 
     align: 'left' 
 
     }, 
 
     plotOptions: { 
 
     series: { 
 
      connectNulls: true, 
 
      fillOpacity: 1, 
 
      stacking: 'normal', 
 
      stickyTracking: true, 
 
     } 
 
     }, 
 
     series: [{ 
 
     name: "Failure", 
 
     data: [ 
 
      [Date.UTC(2017, 7, 1), 20], 
 
      [Date.UTC(2017, 7, 2), 25], 
 
      [Date.UTC(2017, 7, 3), 24], 
 
      [Date.UTC(2017, 7, 4), 7], 
 
      [Date.UTC(2017, 7, 5), 15], 
 
      [Date.UTC(2017, 7, 6), 0], 
 
      [Date.UTC(2017, 7, 7), 35], 
 
      [Date.UTC(2017, 7, 8), 18], 
 
      [Date.UTC(2017, 7, 9), 12], 
 
      [Date.UTC(2017, 7, 10), 10] 
 
     ], 
 
     color: '#1C81C6', 
 
     lineColor: 'none', 
 
     legendIndex: 1 
 
     }, { 
 
     name: 'Success', 
 
     data: [ 
 
      [Date.UTC(2017, 7, 1), 80], 
 
      [Date.UTC(2017, 7, 2), 75], 
 
      [Date.UTC(2017, 7, 3), 76], 
 
      [Date.UTC(2017, 7, 4), 93], 
 
      [Date.UTC(2017, 7, 5), 85], 
 
      [Date.UTC(2017, 7, 6), 100], 
 
      [Date.UTC(2017, 7, 7), 65], 
 
      [Date.UTC(2017, 7, 8), 82], 
 
      [Date.UTC(2017, 7, 9), 88], 
 
      [Date.UTC(2017, 7, 10), 90] 
 
     ], 
 
     color: '#E2EFF8', 
 
     lineColor: 'none', 
 
     legendIndex: 0 
 
     }], 
 
     tooltip: { 
 
     padding: 12, 
 
     crosshair: true, 
 
     shared: true, 
 
     borderWidth: 2, 
 
     borderRadius: 3, 
 
     snap: 0, 
 
     style: { 
 
      fontSize: '12px', 
 
      fontFamily: '\'BentonSans\', sans-serif' 
 
     }, 
 
     formatter: function(tooltip) { 
 
      var header, 
 
      s = []; 
 

 
      $.each(this.points, function(i, point) { 
 
      var isSuccessRate = (point.series.name == 'Success'); 
 

 
      if (header == null) { 
 
       var config = point.point.getLabelConfig(); 
 
       header = tooltip.tooltipFooterHeaderFormatter(config); 
 
      } 
 
      s.push(formatSuccessRateToolTip(point.y, isSuccessRate)); 
 
      // $("#overall-" + point.series.name.toLowerCase() + "-rate").html(point.y + "%"); 
 
      }); 
 

 
      return header + s.reverse().join('<br>'); 
 
     }, 
 
     shared: true 
 
     }, 
 
    }); 
 
    } 
 
} 
 
window.App = App; 
 

 
App.renderSubsetSuccessRateChart('subset_success_rates'); 
 
App.renderTotalSuccessRateChart('total_success_rates');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://code.highcharts.com/5.0.6/highcharts.js"></script> 
 

 
<div id="success-graphs-container" class="success-graphs"> 
 
    <div id="subset_success_rates" style="width:100%; border-bottom: 1px solid #F8F8F8"></div> 
 
    <div id="total_success_rates" style="width:100%;"></div> 
 
</div>