JSFiddle - React, Tailwind, and code Playground

HTML

<script src="http://d3js.org/d3.v3.min.js"></script>
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
    <title>One Graph</title>
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.v2.js"></script>
    <script type="text/javascript" src="simple-graph.js"></script>
    <style type="text/css">
     
    </style>
  </head>
  <body>
    <div id="chart1" class="chart"></div>
    <script type="text/javascript">
      graph = new SimpleGraph("chart1", {
          "xmax": 60, "xmin": 0,
          "ymax": 40, "ymin": 0, 
          "title": "Simple Graph1",
          "xlabel": "X Axis",
          "ylabel": "Y Axis"  
        });
    </script>
  </body>
</html>

CSS

body { font: 13px sans-serif; }
      rect { fill: #fff; }
      ul {
        list-style-type: none;
        margin: 0.5em 0em 0.5em 0em;
        width: 100%; }
        ul li {
          display: table-cell;
          vertical-align: middle;
          margin: 0em;
          padding: 0em 1em; }
      .axis { font-size: 1.5em; }
      .chart {
        background-color: #F7F2C5;
        width: 960px;
        height: 500px; }
      circle, .line {
        fill: none;
        stroke: steelblue;
        stroke-width: 2px; }
      circle {
        fill: white;
        fill-opacity: 0.2;
        cursor: move; }
        circle.selected {
          fill: #ff7f0e;
          stroke: #ff7f0e; }
        circle:hover {
          fill: #ff7f0e;
          stroke: #707f0e; }
        circle.selected:hover {
          fill: #ff7f0e;
          stroke: #ff7f0e; }

JavaScript

registerKeyboardHandler = function(callback) {
  var callback = callback;
  d3.select(window).on("keydown", callback);  
};
 
SimpleGraph = function(elemid, options) {
  var self = this;
  this.chart = document.getElementById(elemid);
  this.cx = this.chart.clientWidth;
  this.cy = this.chart.clientHeight;
  this.options = options || {};
  this.options.xmax = options.xmax || 30;
  this.options.xmin = options.xmin || 0;
  this.options.ymax = options.ymax || 10;
  this.options.ymin = options.ymin || 0;
 
  this.padding = {
     "top":    this.options.title  ? 40 : 20,
     "right":                 30,
     "bottom": this.options.xlabel ? 60 : 10,
     "left":   this.options.ylabel ? 70 : 45
  };
 
  this.size = {
    "width":  this.cx - this.padding.left - this.padding.right,
    "height": this.cy - this.padding.top  - this.padding.bottom
  };
 
  // x-scale
  this.x = d3.scale.linear()
      .domain([this.options.xmin, this.options.xmax])
      .range([0, this.size.width]);
 
  // drag x-axis logic
  this.downx = Math.NaN;
 
  // y-scale (inverted domain)
  this.y = d3.scale.linear()
      .domain([this.options.ymax, this.options.ymin])
      .nice()
      .range([0, this.size.height])
      .nice();
 
  // drag y-axis logic
  this.downy = Math.NaN;
 
  this.dragged = this.selected = null;
 
  this.line = d3.svg.line()
      .x(function(d, i) { return this.x(this.points[i].x); })
      .y(function(d, i) { return this.y(this.points[i].y); });
 
  var xrange =  (this.options.xmax - this.options.xmin),
      yrange2 = (this.options.ymax - this.options.ymin) / 2,
      yrange4 = yrange2 / 2,
      datacount = this.size.width/30;
 
  this.points = d3.range(datacount).map(function(i) { 
    return { x: i * xrange / datacount, y: this.options.ymin + yrange4 + Math.random() * yrange2 }; 
  }, self);
 
  this.vis = d3.select(this.chart).append("svg")
      .attr("width",  this.cx)
      .attr("height", this.cy)
      .append("g")
        .attr("transform", "translate(" +...