Angular/D3

This page is a work in progress and is only, maybe, 10% finished.

It's only presented to show code examples using Angular and D3.

Template Offset
///////////////////////////////////////////
// Section 1: Factory to form template array
// Section 2: Factory to plot d3 data
// Section 3: Controller
///////////////////////////////////////////


///////////////////////////////////////////
// Factory to form template Arr
///////////////////////////////////////////


angular.module("flareTemplate", [])
  .factory("graphCalc", function() {

    var fnComp = function(value, index, arr) {  // components of piecewise function;
      if ( typeof arr[index][0] !== "number" || typeof arr[index][1] !== "number") {
        alert("Error: Array values must be numbers.");
        throw new Error("Array values must be numbers.");
      }
      if (index < arr.length -1) {
        return {
          "slope": (arr[index + 1][1] - arr[index][1])/(arr[index + 1][0] - arr[index][0]), //slope, m, of section
          "const": arr[index][1] - (((arr[index + 1][1] - arr[index][1])/(arr[index + 1][0] - arr[index][0])) * arr[index][0]),  // constant c of f(x) = mx + c
          "midX": arr[index][0] + ((arr[index + 1][0] - arr[index][0]) / 2),    // since linear, midway between x sub 0 and x sub 1
          "midY": arr[index][1] + ((arr[index + 1][1] - arr[index][1]) / 2),    // since linear, midway between y sub 0 and y sub 1
          "theta": Math.atan((arr[index + 1][1] - arr[index][1])/(arr[index + 1][0] - arr[index][0])),  // slope in radain form
          "sinTheta": Math.sin(Math.atan((arr[index + 1][1] - arr[index][1])/(arr[index + 1][0] - arr[index][0]))),
          "cosTheta": Math.cos(Math.atan((arr[index + 1][1] - arr[index][1])/(arr[index + 1][0] - arr[index][0])))
        };
      } else {
        return;
      }
    };

    var formTemp = function(value, index, arr) {  // function to plot values normal to the curve
      if (index < arr.length -1) {
        return [
          arr[index].midX - this.zDistance * arr[index].sinTheta,
          arr[index].midY + this.zDistance * arr[index].cosTheta
        ];
      } else {
        return;
      }
    };

    var formFnComponents = function(arr) {
      return arr.map(fnComp);
    };

    var interpolate = function() {};

    return {
      "formFnComponents": formFnComponents,
      "formTemp": formTemp,
      "interpolate": interpolate
    };

});

///////////////////////////////////////////
// Factory to plot d3 data
///////////////////////////////////////////


angular.module("d3Data", [])
  .factory("dataPlot", function() {

    function _x2(i, arr) {  // helper function for drawGraph, returns next x variable
      if (i + 1 < arr.length) {
        return arr[i + 1][0];
      } else {
        return arr[i][0];
      }
    }

    function _y2(i, arr) {  // helper function for drawGraph, returns next y variable
      if (i + 1 < arr.length) {
        return arr[i + 1][1];
      } else {
        return arr[i][0];
      }
    }

    var drawGraph = function(obj, arr, svgh, lineColor, circleColor) {  // color string ex: "rgb(6,120,155)"
      obj.selectAll("circles.nodes")
          .data(arr)
          .enter()
          .append("svg:circle")
          .attr("cx", function(d) { return d[0]; })
          .attr("cy", function(d) { return svgh - d[1]; })
          .attr("r", "1px")
          .attr("fill", circleColor);

        obj.selectAll(".line")
           .data(arr)
           .enter()
           .append("line")
           .attr("x1", function(d,i) { return d[0] ;})
           .attr("y1", function(d,i) { return svgh - d[1] ;})
           .attr("x2", function(d,i) { if (i+1 < arr.length) {return _x2(i,arr);} else { return d[0]; } })
           .attr("y2", function(d,i) { if (i+1 < arr.length) {return svgh - _y2(i,arr);} else { return svgh - d[1]; } })
           .style("stroke", lineColor);
       };

       var removeGraph = function(obj, selectAll) {
           obj.remove(); // not what I want.
       };

       return {
         "drawGraph": drawGraph,
         "removeGraph": removeGraph
       };
  });


/////////////////////////////////////////
// Controller
/////////////////////////////////////////

  angular.module("hornCalc", ["flareTemplate","hornData", "d3Data"])
    .controller("HornCalculator", ["graphCalc","csvConverter", "dataPlot", function(graphCalc, csvConverter, dataPlot) {

      this.zDistance = 10;
      this.svgH = 500;
      this.svgW = 500;

      var that = this;
      var leCleach = csvConverter.csvConv;  // this curve is known as a le Cleach expansion
      var plot = d3.select("#graph").append("svg");


      function formArr(arr) {
        var hornArr = graphCalc.formFnComponents(arr);
        return hornArr.map(graphCalc.formTemp, that);
      }

      this.plotExp = function() {
        d3.select("#graph").append("svg");
        dataPlot.drawGraph(plot, leCleach, this.svgH , "black", "black");
      };

      this.form = function() {
        var hTemplate = formArr(leCleach).slice(0,leCleach.length -1);  // leave off the last elevement. Math requires a n+1 element,
        dataPlot.drawGraph(plot, hTemplate, this.svgH , "red", "red");
      };

      this.clearTemp = function() {
        dataPlot.removeGraph(plot);
      };

      plot.attr("width", this.svgW)
          .attr("height", this.svgH);


      dataPlot.drawGraph(plot, leCleach, this.svgH , "black", "black");  // default expansion

  }]);
Eric Williams