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

Djo*_*s12 24 javascript jquery chart.js

我有一个使用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'));
Run Code Online (Sandbox Code Playgroud)

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

谢谢

jor*_*lis 39

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

您可以使用.destroy()prototype方法执行此操作.这正是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,
            }]
          }
        }
      });
    });
}
Run Code Online (Sandbox Code Playgroud)

有了这个说,一遍又一遍地破坏/创造是昂贵的,实际上甚至没有必要..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,
              }]
            }
          }
        });
      }
    });
}
Run Code Online (Sandbox Code Playgroud)


小智 11

它会帮助你...

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

示例代码..

if (window.MyChart != undefined)
{
    window.MyChart.destroy();
}
window.MyChart = new Chart(ctx, MyChartconfig);
Run Code Online (Sandbox Code Playgroud)


Raj*_*war 7

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

假设你的 html 有如下内容

<div id="chartContainer">
 <canvas id="mybarChart2"></canvas>
</div>
Run Code Online (Sandbox Code Playgroud)

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

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

这解决了我的问题。


小智 6

这是我发现的chartjs技巧

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

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