<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" href="style.css">
  </head>

  <body>
    <h2>A Line Graph</h2>
    <svg>
      <path id="DemoPath"></path>
    </svg>
    
    <script src="bcc_01.js"></script>
  </body>

</html>
body {
  background-color: #046380;
  padding-left: 50px;
  padding-top: 30px;
}

h2 {
  color: white;
}

svg {
  width: 300px;
  height: 200px;
  border: 2px solid #002f2f;
  background-color: #efecca;
}

path {
  stroke: #444444;
  stroke-width: 3;
  fill: none;
}
// A hard-coded path

(function() {
  
  var path = "M10,130L100,60L190,160L280,10";
  
  document.getElementById('DemoPath').setAttribute('d',path);  
}());
var bcc = bcc || {};

// Returns an SVG path given an array of points in [x,y] form.

bcc.line = function line(data) {
  var path = '',
      ix,
      point;
  for (ix=0; ix<data.length; ++ix) {
    path += (ix===0) ? 'M' : 'L';
    point = data[ix];
    path += point[0]+','+point[1];
  }
  return path;
};

(function() {
  var data = [
        [10,130], 
        [100,60], 
        [190,160], 
        [280,10]
      ],
      path = bcc.line(data);
  
  document.getElementById('DemoPath').setAttribute('d',path);
}());
var bcc = bcc || {};

// WARNING: THIS CODE IS HORRIBLE.

// Returns an SVG path given an array of points in [x,y] form.

bcc.lineForArrays = function lineForArrays(data) {
  var path = '',
      ix,
      point;
  for (ix=0; ix<data.length; ++ix) {
    path += (ix===0) ? 'M' : 'L';
    point = data[ix];
    path += point[0]+','+point[1];
  }
  return path;  
};

// Now allow each point to be either an [x,y] pair or an object {x:12, y: 34}

bcc.lineForObjects = function lineForObjects(data) {
  var path = '',
      ix,
      point;
  for (ix=0; ix<data.length; ++ix) {
    path += (ix===0) ? 'M' : 'L';
    point = data[ix];
    path += point.x + ',' + point.y;
  }
  return path;    
};

bcc.line = function line(data) {
  if (data.length>0 && data[0].hasOwnProperty('x')) {
    return bcc.lineForObjects(data);
  } else {
    return bcc.lineForArrays(data);
  }
};

(function() {
  var data = [
        { x: 10, y: 130 },
        { x: 100, y: 60 },
        { x: 190, y: 160 },
        { x: 280, y: 10 }
      ],
      path = bcc.line(data);
  
  document.getElementById('DemoPath').setAttribute('d',path); 
}());
var bcc = bcc || {};

// WARNING: THIS CODE IS EVEN MORE HORRIBLE.

// Returns an SVG path given an array of points in [x,y] form.

bcc.lineForArrays = function lineForArrays(data) {
  var path = '',
      ix,
      point;
  for (ix=0; ix<data.length; ++ix) {
    path += (ix===0) ? 'M' : 'L';
    point = data[ix];
    path += point[0]+','+point[1];
  }
  return path;  
};

// Now allow each point to be either an [x,y] pair or an object {x:12, y: 34}

bcc.lineForObjects = function lineForObjects(data) {
  var path = '',
      ix,
      point;
  for (ix=0; ix<data.length; ++ix) {
    path += (ix===0) ? 'M' : 'L';
    point = data[ix];
    path += point.x + ',' + point.y;
  }
  return path;    
};

// Another variant, where the y value is obtained by calling a function.

bcc.lineForFunction = function lineForFunction(xValues, yFunc) {
  var path = '',
      ix,
      xValue;
  for (ix=0; ix<xValues.length; ++ix) {
    path += (ix===0) ? 'M' : 'L';
    xValue = xValues[ix];
    path += xValue + ',' + yFunc(xValue);
  }
  return path;    
};

bcc.line = function line(data, yFunc) {
  if (yFunc !== undefined) {
    return bcc.lineForFunction(data,yFunc);
  } else if (data.length>0 && data[0].hasOwnProperty('x')) {
    return bcc.lineForObjects(data);
  } else {
    return bcc.lineForArrays(data);
  }
};

(function() {
  
  function yFunc(x) {
    return 200 - 10 * Math.sqrt(x);
  }
  
  var xValues = [0, 50, 100, 150, 200, 250, 300],
      path = bcc.line(xValues,yFunc);
      
  document.getElementById('DemoPath').setAttribute('d',path); 
}());
// Create a namespace to avoid creating many global variables.
var bcc = bcc || {};

// Make a sub-namespace called svg.
bcc.svg = {};

// Put a line function in the bcc.svg namespace.
bcc.svg.line = function() {
  var getX = function(point) {
        return point[0];
      },
      getY = function(point) {
        return point[1];
      },
      interpolate = function(points) {
        return points.join("L");
      };
      
  function line(data) {
    var segments = [],
        points = [],
        i = -1,
        n = data.length,
        d;
        
    function segment() {
      segments.push("M",interpolate(points));
    }
        
    while (++i < n) {
      d = data[i];
      points.push([+getX.call(this,d,i), +getY.call(this,d,i)]);
    }
    
    if (points.length) {
      segment();
    }
    
    return segments.length ? segments.join("") : null;
  }
  
  line.x = function(funcToGetX) {
    if (!arguments.length) return getX;
    getX = funcToGetX;
    return line;
  };
  
  line.y = function(funcToGetY) {
    if (!arguments.length) return getY;
    getY = funcToGetY;
    return line;
  };
  
  return line;
};


// Demonstrates using the line-generator with an array of [x,y] pairs.
(function() {
  var data = [
        [10,130], 
        [100,60], 
        [190,160], 
        [280,10]
      ],
      lineGenerator = bcc.svg.line(),
      path = lineGenerator(data);
  
  document.getElementById('DemoPath').setAttribute('d',path);
}());

/*
// Demonstrates using the line generator with an array of objects
// that have x and y properties.
(function() {
  var data = [
        { x: 10, y: 130 },
        { x: 100, y: 60 },
        { x: 190, y: 160 },
        { x: 280, y: 10 }
      ],
      lineGenerator = bcc.svg.line()
        .x(function(d) { return d.x; })
        .y(function(d) { return d.y; }),
      path = lineGenerator(data);
  
  document.getElementById('DemoPath').setAttribute('d',path);
}());
*/

/*
// Demonstrates using the line generator with a function that
// returns the y-coordinate for each element in an array of x-coordinates
(function() {
  var lineGenerator = bcc.svg.line()
        .x(function(d) { return d; })
        .y(function(d) { return 200 - 10*Math.sqrt(d);}),
        
      xValues = [0, 50, 100, 150, 200, 250, 300],
      
      path = lineGenerator(xValues);
      
  document.getElementById('DemoPath').setAttribute('d',path); 
}());
*/