Sine Wave The Hard Way

by replicateur

HTML

<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<script type="text/javascript" src="https://www.amcharts.com/lib/3/amcharts.js"></script>
<script type="text/javascript" src="https://www.amcharts.com/lib/3/serial.js"></script>
<div class="growl"></div>
<div class="container">
  <div class="row">
    <div class="col-lg-12">
      <p>
        <button class="btn btn-default btn-add">Add Graph</button>
        <button class="btn btn-default btn-remove">Remove Graph</button>
        <button class="btn btn-default btn-show">Show/Hide Graph</button>
      </p>
      <div class="well">
        <div id="chartdiv" style="display:none"></div>
      </div>
    </div>
  </div>
</div>
</div>

CSS

#chartdiv {
  width: 100%;
  height: 450px;
  font-size: 11px;
}

* {
  font-size: 11px !important;
  line-height: 1.42857143;
}

#chartdiv {
  min-height: 445px;
}

.container {
  padding-top: 15px;
}

.well {
  margin: 0;
}


/* JUST FOR THE NOTIFICATIONS */

.growl {
  position: absolute;
  right: 15px;
  top: 15px;
  z-index: 1337;
}

.growl .alert {
  width: 250px;
  opacity: 0.8;
  cursor: pointer;
}

JavaScript

const REAL_TIME_FREQUENCY = 110;
const ANGULAR_FREQUENCY = REAL_TIME_FREQUENCY * 2 * Math.PI;

let audioContext = new AudioContext();
let myBuffer = audioContext.createBuffer(1, 88200, 44100);
let myArray = myBuffer.getChannelData(0);
for (let sampleNumber = 0 ; sampleNumber < 88200 ; sampleNumber++) {
  myArray[sampleNumber] = generateSample(sampleNumber);
}

function generateSample(sampleNumber) {
  let currentTime = sampleNumber / 44100;
  let currentAngle = currentTime * ANGULAR_FREQUENCY;
  return generateCurve(currentAngle);
}

function generateCurve(x) {
  return Math.sin(x**Math.tan(x));
}

let src = audioContext.createBufferSource();
src.buffer = myBuffer;
src.connect(audioContext.destination);
src.start();

// generate data
var chartData = [];

function generateChartData() {
  var firstDate = new Date();
  firstDate.setTime(firstDate.getTime() - 10 * 24 * 60 * 60 * 1000);

  for (var i = firstDate.getTime(); i < (firstDate.getTime() + 10 * 24 * 60 * 60 * 1000); i += 60 * 60 * 1000) {
    var newDate = new Date(i);

    if (i == firstDate.getTime()) {
      var value0 = Math.round(Math.random() * 10) + 1;
    } else {
      var value0 = Math.round(chartData[chartData.length - 1].value0 / 100 * (90 + Math.round(Math.random() * 20)) * 100) / 100;
    }

    if (newDate.getHours() == 12) {
      // we set daily data on 12th hour only
      var value1 = Math.round(Math.random() * 12) + 1;
      chartData.push({
        date: newDate,
        value0: value0,
        value1: value1
      });
    } else {
      chartData.push({
        date: newDate,
        value0: value0
      });
    }
  }
}
generateChartData();

// JUST SOME VISUAL FEEDBACK
function growl(type, msg) {
  var alert = jQuery("<div>").addClass("alert alert-" + type).on("click", function () {
    jQuery(this).remove();
  }).prependTo(".growl");
  jQuery("<p>").text(msg).appendTo(alert);
  jQuery(alert).animate({
    opacity: 0
  }, 3000, function () {
    jQuery(this).remove();
  });
}

var...