Chartjs条形图显示悬停时的旧数据

问题描述 投票:17回答:6

我有一个使用chart.js创建的条形图。在页面加载时一切正常,但是当我使用daterangepicker更改时间范围时,会出现毛刺。新数据被引入,但当我将鼠标悬停在它上面时,会显示旧数据。我是javascript的新手,所以我希望得到一些帮助。看起来我需要合并.destroy();不知何故,但我不知道如何。我的代码片段如下:

function loadFTPRChart(startdate, enddate){
var BCData = {
labels: [],
datasets: [
 {
  label: "Pass %",
  backgroundColor: "#536A7F",
  data: [],
  stack: 1
},
{
  label: "Fail %",
  backgroundColor: "#e6e6e6",
  data: [],
  stack: 1
},
{
  label: "Auto %",
  backgroundColor: "#286090",
  data: [],
  stack: 2
},
{
  label: "Manual %",
  backgroundColor: "#f0f0f0",
  data: [],
  stack: 2
}
 ]
};
  $.getJSON( "content/FTPR_AM_Graph_ajax.php", {
    startdate: startdate,
    enddate: enddate,
    location: "M"
})
.done(function( data ) {
    console.log("data", data);
    $.each( data.aaData, function( key, val ) {
      if(val == ""){return true}
      BCData.labels.push("Coater " + val[0]);
      BCData.datasets[0].data.push(parseFloat(val[2]));
      BCData.datasets[1].data.push(parseFloat(100-val[2]));
      BCData.datasets[2].data.push(parseFloat(val[1]));
      BCData.datasets[3].data.push(parseFloat(100-val[1]));
    });

    var option = {   
     responsive:true,
};
console.log("BCData", BCData);


//console.log("PrevData", data);
var ctx = document.getElementById("mybarChart2").getContext("2d");
new Chart(ctx, {
  type: 'groupableBar',
  data: BCData,
  options: {
    scales: {
      yAxes: [{
        ticks: {
          max: 100,
        },
        stacked: true,
      }]
    }
  }
});
});

}


loadFTPRChart($('#reportrange').data().daterangepicker.startDate.format('MM/DD/YYYY'), $('#reportrange').data().daterangepicker.endDate.format('MM/DD/YYYY'));

破坏原始数据的最佳方法是什么,以便在我更改日期范围并将鼠标悬停在新图表上时,旧数据不再闪烁?

谢谢

javascript jquery chart.js
6个回答
33
投票

使用您正在采用的方法(例如,每次日期范围更改时创建一个新的Chart对象),然后必须首先销毁先前的图表,然后创建新的图表。

您可以使用.destroy()原型方法来执行此操作。这正是API所声明的内容。

使用此命令可以销毁所创建的任何图表实例。这将清除Chart.js中存储到图表对象的任何引用,以及Chart.js附加的任何关联事件侦听器。必须在将画布重新用于新图表之前调用此方法。

因此,您的代码看起来像这样(注意我们销毁并重新创建)。

// define a variable to store the chart instance (this must be outside of your function)
var myChart;

function loadFTPRChart(startdate, enddate) {
  var BCData = {
    labels: [],
    datasets: [{
      label: "Pass %",
      backgroundColor: "#536A7F",
      data: [],
      stack: 1
    }, {
      label: "Fail %",
      backgroundColor: "#e6e6e6",
      data: [],
      stack: 1
    }, {
      label: "Auto %",
      backgroundColor: "#286090",
      data: [],
      stack: 2
    }, {
      label: "Manual %",
      backgroundColor: "#f0f0f0",
      data: [],
      stack: 2
    }]
  };

  $.getJSON("content/FTPR_AM_Graph_ajax.php", {
      startdate: startdate,
      enddate: enddate,
      location: "M"
    })
    .done(function(data) {
      console.log("data", data);
      $.each(data.aaData, function(key, val) {
        if (val == "") {
          return true
        }
        BCData.labels.push("Coater " + val[0]);
        BCData.datasets[0].data.push(parseFloat(val[2]));
        BCData.datasets[1].data.push(parseFloat(100 - val[2]));
        BCData.datasets[2].data.push(parseFloat(val[1]));
        BCData.datasets[3].data.push(parseFloat(100 - val[1]));
      });

      var option = {
        responsive: true,
      };
      console.log("BCData", BCData);

      // if the chart is not undefined (e.g. it has been created)
      // then destory the old one so we can create a new one later
      if (myChart) {
        myChart.destroy();
      }

      var ctx = document.getElementById("mybarChart2").getContext("2d");
      myChart = new Chart(ctx, {
        type: 'groupableBar',
        data: BCData,
        options: {
          scales: {
            yAxes: [{
              ticks: {
                max: 100,
              },
              stacked: true,
            }]
          }
        }
      });
    });
}

有了这个说,一遍又一遍地破坏/创造是昂贵的,实际上甚至没有必要。还有另一种名为.update()的原型方法,如果您更改了它的基础数据或标签对象,您可以使用它重新渲染图表。

这是一个jsfiddle,显示了更改基础数据和标签,然后重新渲染图表的示例。我强烈建议你改用这种方法。

以下是您的代码如何采用这种更好的方法。

// define a variable to store the chart instance (this must be outside of your function)
var myChart;

function loadFTPRChart(startdate, enddate) {
  var BCData = {
    labels: [],
    datasets: [{
      label: "Pass %",
      backgroundColor: "#536A7F",
      data: [],
      stack: 1
    }, {
      label: "Fail %",
      backgroundColor: "#e6e6e6",
      data: [],
      stack: 1
    }, {
      label: "Auto %",
      backgroundColor: "#286090",
      data: [],
      stack: 2
    }, {
      label: "Manual %",
      backgroundColor: "#f0f0f0",
      data: [],
      stack: 2
    }]
  };

  $.getJSON("content/FTPR_AM_Graph_ajax.php", {
      startdate: startdate,
      enddate: enddate,
      location: "M"
    })
    .done(function(data) {
      console.log("data", data);
      $.each(data.aaData, function(key, val) {
        if (val == "") {
          return true
        }
        BCData.labels.push("Coater " + val[0]);
        BCData.datasets[0].data.push(parseFloat(val[2]));
        BCData.datasets[1].data.push(parseFloat(100 - val[2]));
        BCData.datasets[2].data.push(parseFloat(val[1]));
        BCData.datasets[3].data.push(parseFloat(100 - val[1]));
      });

      var option = {
        responsive: true,
      };
      console.log("BCData", BCData);

      // if the chart is not undefined (e.g. it has been created)
      // then just update the underlying labels and data for each
      // dataset and re-render the chart
      if (myChart) {
        myChart.data.labels = BCData.labels;
        myChart.data.datasets[0].data = BCData.datasets[0].data;
        myChart.data.datasets[1].data = BCData.datasets[1].data;
        myChart.data.datasets[2].data = BCData.datasets[2].data;
        myChart.data.datasets[3].data = BCData.datasets[3].data;
        myChart.update();
      } else {
        // otherwise, this is the first time we are loading so create the chart
        var ctx = document.getElementById("mybarChart2").getContext("2d");
        myChart = new Chart(ctx, {
          type: 'groupableBar',
          data: BCData,
          options: {
            scales: {
              yAxes: [{
                ticks: {
                  max: 100,
                },
                stacked: true,
              }]
            }
          }
        });
      }
    });
}

6
投票

这是我发现的图表技巧

var ctxLine = document.getElementById("line-chart").getContext("2d");
if(window.bar != undefined) 
window.bar.destroy(); 
window.bar = new Chart(ctxLine, {});

https://therichpost.com/solved-hovering-chartjs-bar-chart-showing-old-data


4
投票

它会帮助你......

检查MyChart是否已经配置,如果存在则使用destroy();方法,并将新配置绑定到画布。

示例代码..

if (window.MyChart != undefined)
{
    window.MyChart.destroy();
}
window.MyChart = new Chart(ctx, MyChartconfig);

1
投票

我找到了问题,我的解决方案是首先从html中删除它们,然后加载新图表然后追加画布。

HTML

 $('#chart').empty();
    
$('#chart').html('<canvas id="survey_result"  width="400" height="200"></canvas>'); // then load chart.
    
var ctx = document.getElementById("survey_result");
    <div id="chart" class="display>
    </div>

1
投票

有一个简单的解决方案,可以在JS本身完成。

让我们说你的HTML有类似下面的内容

<div id="chartContainer">
 <canvas id="mybarChart2"></canvas>
</div>

然后在脚本中,您可以在更新数据之前添加以下代码行。

document.getElementById("chartContainer").innerHTML = '&nbsp;';
document.getElementById("chartContainer").innerHTML = '<canvas id="mybarChart2"></canvas>';
var ctx = document.getElementById("mybarChart2").getContext("2d");

这解决了我的问题。


0
投票

chartjs.org提供的样本代码表明它们不会破坏()图表并创建一个新图表。相反,他们从图表中弹出()现有数据并将新数据集推送()到图表,然后更新()图表。

此代码来自chartjs.org网站,该网站通过POP()从图表中删除数据集。

    document.getElementById('removeDataset').addEventListener('click', function() {
        horizontalBarChartData.datasets.pop();
        window.myHorizontalBar.update();
    });

此代码用于通过PUSH()将数据集添加到图表:

    document.getElementById('addDataset').addEventListener('click', function() {
        var colorName = colorNames[horizontalBarChartData.datasets.length % colorNames.length];
        var dsColor = window.chartColors[colorName];
        var newDataset = {
            label: 'Dataset ' + (horizontalBarChartData.datasets.length + 1),
            backgroundColor: color(dsColor).alpha(0.5).rgbString(),
            borderColor: dsColor,
            data: []
        };

        for (var index = 0; index < horizontalBarChartData.labels.length; ++index) {
            newDataset.data.push(randomScalingFactor());
        }

        horizontalBarChartData.datasets.push(newDataset);
        window.myHorizontalBar.update();
    });

这两个代码块的最后一步是更新图表。

一般来说,有必要弹出要从图表中删除的数据,然后推送新数据,最后更新图表。因此,悬停时不会显示以前的数据。

© www.soinside.com 2019 - 2024. All rights reserved.