2017-04-03 108 views
8

我正在使用morris.js圖表​​以及引導滑塊。設置事件行後,chart.redraw()不工作

我想要做什麼:
如果滑塊移動,我想在滑塊值的位置插入一個事件行到圖表。沒什麼特別的。

問題:
設置事件後圖表不重繪。插入新數據時,圖表將自動重新繪製。所以我嘗試刷新(檢查是否有正確的語法)再次現有的數據傳遞到圖表所示:

chart.setData(chart.options.data); 

這是工作!新事件被繪製到圖表中。不幸的是,當圖表重新繪製所有數據時,這表現不佳。

該文檔說有chart.redraw()。它只是不適合我。也許你的某個人可以找出原因。

只需運行代碼段並切換單選按鈕以測試兩種方法,您就會看到問題。

// Chart creation - not interesting 
 
var chart = new Morris.Line({ 
 
    element: 'chart', 
 
    ymin: 0, 
 
    ymax: 100, 
 
    gridIntegers: true, 
 
    parseTime:false, 
 
    // Will be set below 
 
    data: [ ], 
 
    xkey: 'position', 
 
    ykeys: ['value'], 
 
    labels: ['Value'], 
 
    hideHover: "always", 
 
    pointSize: 0, 
 
    continuousLine: false, 
 
    goalStrokeWidth: 3, 
 
    axes: true, 
 
    grid: true, 
 
    numLines: 6, 
 
    eventLineColors: [ "red" ], 
 
    smooth: true 
 
}); 
 

 
// Inserting some values 
 
var values = [101] 
 
for(i = 1; i <= 100; i += 1) { 
 
    var x = 100/(Math.pow((i-50), 2)+4); 
 
    values.push({ position: i, value: x }); 
 
} 
 
chart.setData(values); 
 

 
// Create slider 
 
$('#slider').slider({ 
 
    tooltip: 'never', 
 
    tooltip_position:'left', 
 
    height: 300, 
 
    length: 300, 
 
}); 
 

 
// If the slider moves, I want to set its value as an event-line 
 
$("#slider").on("slideStop", function(slideEvt) { 
 
    chart.options.events = [ slideEvt.value ]; 
 

 
    // Check inserting-data VS chart.redraw() 
 
    // Both should work... chart.redraw() isnt. 
 
    if(document.getElementById('insert').checked) 
 
     chart.setData(chart.options.data); 
 
    else if(document.getElementById('redraw').checked) 
 
     chart.redraw(); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script> 
 
<script src="http://cdn.oesmith.co.uk/morris-0.5.1.min.js"></script> 
 
<link href="http://cdn.oesmith.co.uk/morris-0.5.1.css" rel="stylesheet"/> 
 

 
<!-- Bootstrap slider --> 
 
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/9.7.2/bootstrap-slider.min.js"></script> 
 
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/9.7.2/css/bootstrap-slider.min.css"> 
 

 
<div id="chart" style="height: 150px;width:500px;"></div> 
 
<form action=""> 
 
    <input checked="true" id="insert" type="radio" name="refreshMethod"> Insert (working)<br> 
 
    <input id="redraw" type="radio" name="refreshMethod"> Redraw (not working)<br> 
 
</form> 
 
<input id="slider" type="text" data-slider-min="0" data-slider-max="100" data-slider-step="1" data-slider-value="50"/>

我感謝這裏的每一個幫助。非常感謝你!

重要編輯:
只要我可以設置一個賞金(+1小時),我會這麼做。這個問題非常重要的另一部分是如何將滑塊綁定到單個圖表事件而沒有滯後。目前使用slide事件而不是slideStop時,性能非常低。

+0

「的文件說有'chart.redraw()'。」 - 你可以指出哪裏/哪個文件你正在參考?我找不到它(請參閱我的答案中的鏈接) – ochi

回答

2

這不起作用,因爲當您撥打chart.redraw()時沒有設置內部chart.events。這家旅館位於setData,行號爲this.events = this.options.events

爲解決這個問題:在代碼中使用chart.events = [val]而非chart.options.events = [val];

個人而言,我將它們都在的情況下setData再次調用,但是這取決於你。

因此,在您的演示:

... 
else if(document.getElementById('redraw').checked) { 
    chart.events = [ slideEvt.value ]; 
    chart.redraw(); 
} 

編輯:

增加了chart.quickRedraw功能。這將刪除重繪功能不必要的重新計算(參閱什麼是現在排除註釋掉的代碼):

chart.quickRedraw = function() { 
     this.raphael.clear(); 
     //this._calc(); 
     this.drawGrid(); 
     //this.drawGoals(); 
     this.drawEvents(); 
     this.draw();  
}; 

演示已經與第三個選項更新。

// Chart creation - not interesting 
 
var chart = new Morris.Line({ 
 
    element: 'chart', 
 
    ymin: 0, 
 
    ymax: 100, 
 
    gridIntegers: true, 
 
    parseTime:false, 
 
    // Will be set below 
 
    data: [ ], 
 
    xkey: 'position', 
 
    ykeys: ['value'], 
 
    labels: ['Value'], 
 
    hideHover: "always", 
 
    pointSize: 0, 
 
    continuousLine: false, 
 
    goalStrokeWidth: 3, 
 
    axes: true, 
 
    grid: true, 
 
    numLines: 6, 
 
    eventLineColors: [ "red" ], 
 
    smooth: true 
 
}); 
 

 
// Inserting some values 
 
var values = [101] 
 
for(i = 1; i <= 100; i += 1) { 
 
    var x = 100/(Math.pow((i-50), 2)+4); 
 
    values.push({ position: i, value: x }); 
 
} 
 
chart.setData(values); 
 

 
// Create slider 
 
$('#slider').slider({ 
 
    tooltip: 'never', 
 
    tooltip_position:'left', 
 
    height: 300, 
 
    length: 300, 
 
}); 
 

 
// If the slider moves, I want to set its value as an event-line 
 
$("#slider").on("slideStop", function(slideEvt) { 
 
    chart.options.events = [ slideEvt.value ]; 
 

 
    // Check inserting-data VS chart.redraw() 
 
    // Both should work... chart.redraw() isnt. 
 
    if(document.getElementById('insert').checked) 
 
     chart.setData(chart.options.data); 
 
    else if(document.getElementById('redraw').checked) { 
 
     chart.events = [ slideEvt.value ]; 
 
     chart.redraw(); 
 
    } else if(document.getElementById('quickerRedraw').checked) { 
 
     chart.events = [ slideEvt.value ]; 
 
     chart.quickRedraw(); 
 
    } 
 
}); 
 

 
chart.quickRedraw = function() { 
 
     this.raphael.clear(); 
 
     //this._calc(); 
 
     this.drawGrid(); 
 
     //this.drawGoals(); 
 
     this.drawEvents(); 
 
     this.draw(); 
 
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script> 
 
<script src="http://cdn.oesmith.co.uk/morris-0.5.1.min.js"></script> 
 
<link href="http://cdn.oesmith.co.uk/morris-0.5.1.css" rel="stylesheet"/> 
 

 
<!-- Bootstrap slider --> 
 
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/9.7.2/bootstrap-slider.min.js"></script> 
 
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/9.7.2/css/bootstrap-slider.min.css"> 
 

 
<div id="chart" style="height: 150px;width:500px;"></div> 
 
<form action=""> 
 
    <input checked="true" id="insert" type="radio" name="refreshMethod"> Insert (working)<br> 
 
    <input id="redraw" type="radio" name="refreshMethod"> Redraw (working)<br> 
 
    <input id="quickerRedraw" type="radio" name="refreshMethod"> Quicker Redraw<br> 
 
</form> 
 
<input id="slider" type="text" data-slider-min="0" data-slider-max="100" data-slider-step="1" data-slider-value="50"/>

+0

我已經更新了答案,通過刪除一些不必要的'redraw'代碼來包含替代更快的重繪功能。有關詳細信息,請參閱編輯 –