Charts

Sample Project that displays sensor data in visual charts

See the full list of sample projects.

This sample generates real-time charts for viewing the sensor output from the following APIs:


/* global SmoothieChart, TimeSeries, MotionStack */
var orientationChart = new SmoothieChart();
var tsPitch = new TimeSeries();
var tsRoll = new TimeSeries();
var tsYaw = new TimeSeries();

var accelerometerChart = new SmoothieChart();
var tsX = new TimeSeries();
var tsY = new TimeSeries();
var tsZ = new TimeSeries();

var relHeadingChart = new SmoothieChart();
var tsRelHeading = new TimeSeries();

var relPitchChart = new SmoothieChart();
var tsRelPitch = new TimeSeries();

var gravityChart = new SmoothieChart();
var tsGravityX = new TimeSeries();
var tsGravityY = new TimeSeries();
var tsGravityZ = new TimeSeries();

var magnetometerChart = new SmoothieChart();
var tsMagnetX = new TimeSeries();
var tsMagnetY = new TimeSeries();
var tsMagnetZ = new TimeSeries();

var gyroChart = new SmoothieChart();
var tsGyroAlpha = new TimeSeries();
var tsGyroBeta = new TimeSeries();
var tsGyroGamma = new TimeSeries();

var tiltChart = new SmoothieChart();
var tsTilt = new TimeSeries();



function startSmoothie(){
  orientationChart.streamTo(document.getElementById("orientation"), 1/15);
  orientationChart.addTimeSeries(tsPitch, { strokeStyle: "rgb(255, 0, 0)", lineWidth: 3 });
  orientationChart.addTimeSeries(tsRoll, { strokeStyle: "rgb(0, 255, 0)", lineWidth: 3 });
  orientationChart.addTimeSeries(tsYaw, { strokeStyle: "rgb(0, 0, 255)", lineWidth: 3 });

  accelerometerChart.streamTo(document.getElementById("accelerometer"), 1/15);
  accelerometerChart.addTimeSeries(tsX, { strokeStyle: "rgb(255, 0, 0)", lineWidth: 3 });
  accelerometerChart.addTimeSeries(tsY, { strokeStyle: "rgb(0, 255, 0)", lineWidth: 3 });
  accelerometerChart.addTimeSeries(tsZ, { strokeStyle: "rgb(0, 0, 255)", lineWidth: 3 });

  relHeadingChart.streamTo(document.getElementById("relativeheading"), 1/15);
  relHeadingChart.addTimeSeries(tsRelHeading, { strokeStyle: "rgb(0, 0, 255)", lineWidth: 3 });

  relPitchChart.streamTo(document.getElementById("relativepitch"), 1/15);
  relPitchChart.addTimeSeries(tsRelPitch, { strokeStyle: "rgb(0, 0, 255)", lineWidth: 3 });

  gravityChart.streamTo(document.getElementById("gravity"), 1/15);
  gravityChart.addTimeSeries(tsGravityX, { strokeStyle: "rgb(255, 0, 0)", lineWidth: 3 });
  gravityChart.addTimeSeries(tsGravityY, { strokeStyle: "rgb(0, 255, 0)", lineWidth: 3 });
  gravityChart.addTimeSeries(tsGravityZ, { strokeStyle: "rgb(0, 0, 255)", lineWidth: 3 });

  magnetometerChart.streamTo(document.getElementById("magnetometer"), 1/15);
  magnetometerChart.addTimeSeries(tsMagnetX, { strokeStyle: "rgb(255, 0, 0)", lineWidth: 3 });
  magnetometerChart.addTimeSeries(tsMagnetY, { strokeStyle: "rgb(0, 255, 0)", lineWidth: 3 });
  magnetometerChart.addTimeSeries(tsMagnetZ, { strokeStyle: "rgb(0, 0, 255)", lineWidth: 3 });

  gyroChart.streamTo(document.getElementById("gyroscope"), 1/15);
  gyroChart.addTimeSeries(tsGyroBeta, { strokeStyle: "rgb(255, 0, 0)", lineWidth: 3 });
  gyroChart.addTimeSeries(tsGyroGamma, { strokeStyle: "rgb(0, 255, 0)", lineWidth: 3 });
  gyroChart.addTimeSeries(tsGyroAlpha, { strokeStyle: "rgb(0, 0, 255)", lineWidth: 3 });

  tiltChart.streamTo(document.getElementById("tilt"), 1/15);
  tiltChart.addTimeSeries(tsTilt, { strokeStyle: "rgb(255, 0, 0)", lineWidth: 3 });
}

(function(){
  // set initial canvas width and unhide them.
  resize(null, true);
  startSmoothie();
  window.addEventListener("resize", resize);

  // Helps hiding unwanted blocks
  Array.prototype.forEach.call(document.querySelectorAll(".title"), function(elem) {
    elem.addEventListener("click", function(event) {
      var canvas = event.target.parentNode.parentNode.querySelector("canvas");
      canvas.classList.toggle("hide");
    });
  });

  var accelerometer = new MotionStack.Accelerometer();
  accelerometer.start(function (e) {
    if ( e.polyfillAcceleration===false ){
      tsX.append(new Date().getTime(), e.x);
      tsY.append(new Date().getTime(), e.y);
      tsZ.append(new Date().getTime(), e.z);
    } else {
      tsX.append(new Date().getTime(), e.gravity.x);
      tsY.append(new Date().getTime(), e.gravity.y);
      tsZ.append(new Date().getTime(), e.gravity.z);
    }
  });

  var msOrientation = new MotionStack.Orientation();
  msOrientation.start(function (e) {
    tsPitch.append(new Date().getTime(), e.pitch);
    tsRoll.append(new Date().getTime(), e.roll);
    tsYaw.append(new Date().getTime(), e.yaw);
  });

  var gyroscope = new MotionStack.Gyroscope();
  gyroscope.start(function (e) {
    tsGyroBeta.append(new Date().getTime(), e.beta);
    tsGyroGamma.append(new Date().getTime(), e.gamma);
    tsGyroAlpha.append(new Date().getTime(), e.alpha);
  });

  var relativeheading = new MotionStack.RelativeHeading({continuous: true});
  relativeheading.start(function (e) {
    tsRelHeading.append(new Date().getTime(), e.angle);
  });

  var relativepitch = new MotionStack.RelativePitch({continuous: true});
  relativepitch.start(function (e) {
    tsRelPitch.append(new Date().getTime(), e.angle);
  });

  var gravity = new MotionStack.Gravity();
  gravity.start(function (e) {
    tsGravityX.append(new Date().getTime(), e.x);
    tsGravityY.append(new Date().getTime(), e.y);
    tsGravityZ.append(new Date().getTime(), e.z);
  });

  var magnetometer = new MotionStack.Magnetometer({noDrift: false});
  magnetometer.start(function (e) {
    tsMagnetX.append(new Date().getTime(), e.x);
    tsMagnetY.append(new Date().getTime(), e.y);
    tsMagnetZ.append(new Date().getTime(), e.z);
  });

  var tilt = new MotionStack.Tilt();
  tilt.start(function (e) {
    tsTilt.append(new Date().getTime()-1, 0);
    if (e.direction === tilt.DIRECTION_UP  ||  e.direction === tilt.DIRECTION_LEFT ) {
      tsTilt.append(new Date().getTime(), 1);
    } else if ( e.direction === tilt.DIRECTION_DOWN  ||  e.direction === tilt.DIRECTION_RIGHT ) {
      tsTilt.append(new Date().getTime(), -1);
    }
    tsTilt.append(new Date().getTime()+1, 0);
  });

})();

// Sets the width of the canvas to 80% of the viewport to keep a more responsive view.
function resize(e, init){
  var clientWidth = document.documentElement.clientWidth;
  Array.prototype.forEach.call(document.querySelectorAll("canvas"), function (canvas) {
    // If you don't want the canvas to resize, just comment out the next line of code:
    canvas.width = clientWidth * 0.8;
    if(init) canvas.classList.remove("hide");
  });
}