ChartJS 为什么我的图表更新功能doest似乎做什么?

q5lcpyga  于 2023-05-17  发布在  Chart.js
关注(0)|答案(1)|浏览(170)

我不知道为什么当destroy()正常工作时图表更新不工作。也许是因为它在函数中,后来导出为idk

let labelArr = [];
let dataArr = [];

let data = {
  labels: labelArr,
  datasets: [
    {
      data: dataArr,
      label: "# of Amount",
      borderWidth: 1,
      borderColor: "#01a001",
      backgroundColor: "#01a001",
    },
  ],
};

let config = {
  type: "line",
  data,
  options: {
    scales: {
      y: {
        beginAtZero: false,
      },
    },
  },
};

function initChart(currentAccount) {
  currentAccount.transactions.forEach((t) => {
    const dateReady = currentUser.dateCreator(t.date);
    labelArr.push(dateReady);
    dataArr.push(t.amount);
  });
}

let chartUI = new Chart(document.getElementById("chart"), config);

function destroy(chartUI) {
  chartUI.data.datasets[0].data = [];
  chartUI.data.labels = [];
  labelArr = [];
  dataArr = [];
  chartUI.destroy();
}

function render(currentAccount, chartUI) {
  chartUI = new Chart(document.getElementById("chart"), config);

  currentAccount.transactions.forEach((t) => {
    const dateReady = currentUser.dateCreator(t.date);
    labelArr.push(dateReady);
    dataArr.push(t.amount);

    chartUI.data.datasets[0].data = dataArr;
    chartUI.data.labels = labelArr;
  });
  chartUI.update();
}

我想在点击时更新它,就像这样:

export const initSettings = function (currentAccount) {
  initChart(currentAccount);
};

export const updateUI = function (currentAccount) {
  destroy(chartUI);
  render(currentAccount, chartUI);

};

我希望更新,但它不是我得到画布已经在使用中

Lorem ipsum dolor sit amet consectetur adipisicing elit. Ab eius esse repudiandae maxime, velit expedita id temporibus dicta consequatur eum.

我希望更新,但它不是我得到画布已经在使用中

0wi1tuuw

0wi1tuuw1#

代码中的错误是在函数render中。您将chartUI作为参数发送给函数,然后在函数内部为其分配new Chart。因此,函数中chartUI的值和函数外部的值是不同的(你可能假设赋值在函数的作用域之外可用,就像其他编程语言中的引用一样)。
然后,destroy函数总是在同一个chartUI对象上被调用,并且实际上不会破坏在render中创建的真实的的活动chartUI
您可以通过在destroy函数中记录chartUI.canvas来验证这一点-您将看到第一次从html中获取canvas元素,但第二次canvas是null-这是因为chartUI引用的对象与前一次调用相同,而不是new Chart创建的新对象。
因此,一个快速解决方案是在函数render的末尾添加一个return chartUI;

function render(currentAccount, chartUI) {
   chartUI = new Chart(document.getElementById("chart"), config);
//...................
   chartUI.update();
   return chartUI;
}

然后使用以下命令恢复新创建的图表对象:

chartUI = render(currentAccount, chartUI);

in updateUI ; jsFiddle
但是,整个销毁和重新创建模式对于您正在使用的数据类型并不是必需的(根据我的经验,实际上几乎不需要);它还导致不平滑的视觉过渡。
只需分配新数据并调用update就足够了,如以下代码片段所示:

let t0 = Date.now();
const currentAccountGen = ()=>{t0 += 2*24*1000*3600; return {
    transactions: Array.from({length: 10},
        (_, i)=>({date: t0+i*24*1000*3600, amount: 10+2*Math.random()+3*Math.cos(i/10*Math.PI)}))
}};

let labelArr = [];
let dataArr = [];

let data = {
    labels: labelArr,
    datasets: [
        {
            data: dataArr,
            label: "# of Amount",
            borderWidth: 1,
            borderColor: "#01a001",
            backgroundColor: "#01a001",
        },
    ],
};

let config = {
    type: "line",
    data,
    options: {
        scales: {
            x: {
                type: "time",
            },
            y: {
            //    beginAtZero: false, // default
            },
        },
    },
};

const chartUI = new Chart(document.getElementById("chart"), config);

function render(currentAccount, chartUI) {
    labelArr = [];
    dataArr = [];
    currentAccount.transactions.forEach((t) => {
        const dateReady = /*currentUser.dateCreator*/(t.date);
        labelArr.push(dateReady);
        dataArr.push(t.amount);
    });
    chartUI.data.datasets[0].data = dataArr;
    chartUI.data.labels = labelArr;
    chartUI.update();
}

render(currentAccountGen(), chartUI);
const hi = setInterval(function(){
    render(currentAccountGen(), chartUI);
}, 1000)

function stop(){
    clearInterval(hi);
    document.querySelector('#stopBut').disabled = true;
}
<button id='stopBut' onclick="stop()">Stop</button>
<div style="height:250px">
<canvas id="chart"></canvas>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.3.0/chart.umd.js" integrity="sha512-CMF3tQtjOoOJoOKlsS7/2loJlkyctwzSoDK/S40iAB+MqWSaf50uObGQSk5Ny/gfRhRCjNLvoxuCvdnERU4WGg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns@3.0.0/dist/chartjs-adapter-date-fns.bundle.min.js"></script>

相关问题