Home > OS >  Chartjs not working with d3 from csv source
Chartjs not working with d3 from csv source

Time:06-11

I'm attempting to load a csv file composed of two columns - time and temperature - from my raspberry pi and make a chart with chartjs. In some tutorial I found that I could do that with d3 but it seems that I'm doing something wrong with the promises.

var csv = `
21:34:03,17.25
21:35:04,17.18
21:36:03,17.18
21:37:03,17.18
21:38:03,17.18
21:39:03,17.18
21:40:03,17.18
21:41:03,17.12
21:42:03,17.18
21:43:03,17.12
21:44:03,17.12
21:46:03,17.12
21:47:02,17.12
21:48:03,17.12
21:49:02,17.12
21:50:03,17.06
21:51:03,17.06
21:52:03,17.06
21:53:03,17.06
21:54:03,17.06
21:55:04,17.06
21:56:03,17.06
21:57:02,17.06
21:58:03,17.06
22:00:04,17.00
22:01:02,17.00`;

//couldn't find a way to embed the csv into  the text function for the snippet

d3.text("temp.csv").then(makeChart);

function makeChart(temp) {
  var result = "x, y\n"   temp; //now you have the header
  var datos = d3.csvParse(result);
  var chart = new Chart('chart', {
    type: 'line',
    data: {
      labels: datos.x,
      datasets: [{
        data: datos.y
      }]
    }
  });
  console.log(this.chart.data);
  return this.chart;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.min.js"></script>
<canvas id="chart" width="400" height="400"></canvas>

Sample data (this is supposed to be temp.csv):

21:34:03,17.25
21:35:04,17.18
21:36:03,17.18
21:37:03,17.18
21:38:03,17.18
21:39:03,17.18
21:40:03,17.18
21:41:03,17.12
21:42:03,17.18
21:43:03,17.12
21:44:03,17.12
21:46:03,17.12
21:47:02,17.12
21:48:03,17.12
21:49:02,17.12
21:50:03,17.06
21:51:03,17.06
21:52:03,17.06
21:53:03,17.06
21:54:03,17.06
21:55:04,17.06
21:56:03,17.06
21:57:02,17.06
21:58:03,17.06
22:00:04,17.00
22:01:02,17.00

I don't know what else to add but the only workaround I found was to get rid of d3 altogether though I'd like to understand how to use its promises in this example.

CodePudding user response:

Your promise is OK (i.e. d3.text("temp.csv").then(makeChart);) but your logic in makeChart has a few issues:

  1. Remove the space between the , and y in the header you add - otherwise it's creating a object key like this " y" instead of just y
  2. The y values need to be converted to float because csvParse defaults to values as text without a conversion function
  3. datos.x and datos.y do not refer to anything as datos has no specific x and y keys - it is an array of objects, each of which has x and y keys. So, you can use map to extract the arrays of those keys

Working example below:

var url = "https://gist.githubusercontent.com/robinmackenzie/ff787ddb871cef050d7e6279991a0f07/raw/4ce35de3a9bef27363d83e7da2f3365ffa8d2345/data.csv";

d3.text(url)
  .then(csv => makeChart(csv))
  
function makeChart(temp) {
  // add the header (no space between , and y
  var result = "x,y\n"   temp; //now you have the header

  // csv parse - need to convert y values to float
  var datos = d3.csvParse(result, d => {
    return {
      x: d.x,
      y: parseFloat(d.y)
    }
  });

  // render chart
  var chart = new Chart('chart', {
    type: 'line',
    data: {
      labels: datos.map(d => d.x), // <-- just get x values
      datasets: [{
        data: datos.map(d => d.y) // <-- just get y values
      }]
    }
  });

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.min.js"></script>
<canvas id="chart" width="400" height="100"></canvas>

  • Related