chart.redraw() не работает после установки строки события

Я использую диаграмму morris.js вместе со слайдером начальной загрузки.

Что я хочу сделать:
Если ползунок перемещен, я хочу вставить строку события в диаграмму в положении значения ползунков. Ничего особенного.

Эта проблема:
Диаграмма не перерисовывается после установки события. При вставке новых данных график будет перерисован автоматически. Поэтому я попытался обновить (чтобы проверить правильность синтаксиса), снова передав существующие данные в диаграмму, например так:

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,

1 ответ

Это не работает, потому что внутренне chart.events не устанавливается при звонке chart.redraw(), Это свойство установлено внутри 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"/>

Другие вопросы по тегам