我试图使用Smoothie.js制作一些CPU使用情况图表(类似于server load example)。

我做了一个for()循环,为每个核心创建一个TimeSeriesSmoothieChart元素,然后一个小的updater函数向每个序列添加最新的加载数据(在下面的代码段中由random()函数代替) 。

但是,只有最后一个图表正确显示,其他图表留空。快速查看检查器,发现所有系列和图表均已创建并绑定,但是前三个系列的append功能不起作用(即使通过控制台手动添加数据也不起作用,内部data系列的数组不会更新)。

我不明白为什么基于函数的example起作用,但是基于循环的函数却不起作用。我的代码有问题吗?这是冰沙中的错误吗?

请参见下面的代码段:



const container = document.getElementById("charts_container");
const data = {
  cores: 4
}; // Retrieved through an NPM library
const cpus = [1, 2, 3, 4];


var series = [];
var charts = [];

// For each core...
for (var i = 0; i < data.cores; i++) {
  // Create some DOM
  container.innerHTML += `<div>
      <h1>CORE <em>#<span>${i}</span></em></h1>
      <canvas id="cpu_canvas_${i}" height="60"></canvas>
      </div>`;

  // Create a new TimeSeries
  series.push(new TimeSeries());

  // Create a new chart
  let serie = series[i];
  let chart = new SmoothieChart();

  chart.addTimeSeries(serie);
  chart.streamTo(document.getElementById(`cpu_canvas_${i}`), 500);

  charts.push(chart);
}

// Initialize the series updater
updateInfo();
var infoUpdater = setInterval(() => {
  updateInfo();
}, 500);


function updateInfo() {
  cpus.forEach((e, i) => {
    series[i].append(new Date().getTime(), Math.random() * 100); // Example data
  });
}

/* A bit of CSS so this snippet won't hurt your eyes too much */

#charts_container>div {
  display: flex;
  flex-direction: row;
  align-items: center;
  margin: 15px;
}

h1 {
  font-size: 1.2em;
  font-family: sans-serif;
  margin-right: 15px;
}

canvas {
  background-color: black;
}

<!-- Include Smoothie Charts for this example -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/smoothie/1.32.0/smoothie.min.js"></script>

<!-- Container element -->
<div id="charts_container">
</div>

最佳答案

原来DOM太慢了。

通过在异步函数中为每个核心图表创建DOM,然后初始化每个SmoothieChart和TimeSerie,我解决了该问题。请参见下面的代码。



const container = document.getElementById("charts_container");
const data = {
  cores: 4
}; // Retrieved through an NPM library
const cpus = [1, 2, 3, 4];


var series = [];
var charts = [];

let createCoresDOM = () => {
  return new Promise(resolve => {
    for (var i = 0; i < data.cores; i++) {
      // Create DOM for each core
      container.innerHTML += `<div>
            <h1>CORE #${i}</h1>
            <canvas id="cpu_canvas_${i}" height="60"></canvas>
            </div>`;

      if (i === data.cores - 1) {
        // When we reached the last core, resolve the promise
        resolve(true);
      }
    }
  });
};
async function waitForCoresDOM() {
  let result = createCoresDOM();
  return await result;
}

waitForCoresDOM().then(() => { // Note how this line is pretty self-explanatory :)
  for (var i = 0; i < data.cores; i++) {
    // For each core...

    // Create a new TimeSeries
    series.push(new TimeSeries());

    // Create a new chart
    let serie = series[i];
    let chart = new SmoothieChart();

    chart.addTimeSeries(serie);
    chart.streamTo(document.getElementById(`cpu_canvas_${i}`), 500);

    charts.push(chart);
  }

  // Initialize the series updater
  updateInfo();
  var infoUpdater = setInterval(() => {
    updateInfo();
  }, 500);
});

function updateInfo() {
  cpus.forEach((e, i) => {
    series[i].append(new Date().getTime(), Math.random() * 100); // Example data
  });
}

/* A bit of CSS so this snippet won't hurt your eyes too much */

#charts_container>div {
  display: flex;
  flex-direction: row;
  align-items: center;
  margin: 15px;
}

h1 {
  font-size: 1.2em;
  font-family: sans-serif;
  margin-right: 15px;
}

canvas {
  background-color: black;
}

<!-- Include Smoothie Charts for this example -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/smoothie/1.32.0/smoothie.min.js"></script>

<!-- Container element -->
<div id="charts_container">
</div>

关于javascript - 在for()循环中创建多个Smoothie.js图表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48026494/

10-12 07:39
查看更多