block by danharr e80684642c7aadb188ba

Radian | Angular | d3

Full Screen

app.js

'use strict';

function EgCtrl(plotLib, $http, $scope, $location) {
  plotLib.midMonths = function(ms, y) {
    return ms.map(function(m) { return new Date(y, m, 15); });
  };

  // Turn a vector of [[x1,y1], [x2,y2], ..., [xn,yn]] into a vector
  // of y-values interpolated to [f, ..., t].
  plotLib.fillIn = function(d, f, t) {
    var ft = t - f + 1;
    var ys = new Array(ft);
    var x1 = d[0][0], xn = d[d.length-1][0];
    var y1 = d[0][1], yn = d[d.length-1][1];
    if (d.length == 1)
      for (var i = 0; i < ft; ++i) ys[i] = y1;
    else {
      var i = 0;
      if (f < x1) {
        var delta = (d[1][1] - y1) / (d[1][0] - x1);
        var yf = y1 - delta * (x1 - f);
        for (; i < x1-f; ++i) ys[i] = yf + delta * i;
      }
      ys[i] = y1;
      var j = 1;
      while (j < d.length) {
        var ym = d[j-1][1], yp = d[j][1], xm = d[j-1][0], xp = d[j][0];
        var delta = (yp - ym) / (xp - xm);
        for (; x1+i < d[j][0]; ++i) ys[i] = ym + delta * (x1+i - xm);
        if (i < ft) ys[i++] = d[j++][1];
      }
      if (i < ft) {
        var delta = (yn - d[d.length-2][1]) / (xn - d[d.length-2][0]);
        for (var i0 = i; i < ft; ++i) ys[i] = yn + delta * (i-i0+1);
      }
    }
    return ys;
  };

  $scope.loadStockData = function() {
    $http.get('/data/stocks/' + $scope.dset + '.csv').
      success(function(data) {
        $scope.datavalues = data;
      });
  };
  $scope.stockInit = function() {
    $scope.dset = 'CSCO';
    $scope.loadStockData($scope.dset);
  };

  $scope.$watch('$location.hash', function() {
    var url = "http://" + location.host + "/eg/" +
      location.hash.slice(2) + ".html";
    $http.get(url).success(function(res) {
      res = res.replace(/<h3>(.|\n)*<\/h3>\n\n/m, "");
      $('div.container pre.include-source').remove();
      var ctr = $('div.container');
      ctr.append('<pre class="include-source">' +
                 '<code class="html"></code></pre>');
      var code = $($(ctr.children()[ctr.children().length-1]).children()[0]);
      code.text(res);
      code.highlight();
    });
  });
}
EgCtrl.$inject = ['plotLib', '$http', '$scope', '$location'];

var negs = 85;

var eggrps = [ { title: "Plot types",
                 items: [["Basic plot; CSV data",   1],
                         ["Basic plot; JSON data",  2],
                         ["Bar charts",            11],
                         ["Func. plots",           12],
                         ["Func. plots",           13],
                         ["Basic points plot",     17],
                         ["Textual points plot",   81],
                         ["Range attributes",      18],
                         ["Log axes",              19],
                         ["Second axes",           20],
                         ["Bar chart",             21],
                         ["Bar chart (px width)",  51],
                         ["Test",                  22],
                         ["Histogram #1",          32],
                         ["Histogram #2",          53],
                         ["Histogram #3",          54],
                         ["Histogram #4",          74],
                         ["Simple area plot",      35],
                         ["Rug plots",             73],
                         ["Simple heatmap",        52]] },

               { title: "UI examples",
                 items: [["Int. legend; fading",    3],
                         ["X-axis zoom",            4],
                         ["Stroke fade UI",         5],
                         ["Stroke colour UI",       6],
                         ["X/Y variable UI",        7],
                         ["UI in layout #1",       69],
                         ["UI in layout #2",       70],
                         ["UI in layout #3",       71],
                         ["Axis transformations",  76]] },

               { title: "Data access",
                 items: [["Date handling",            9],
                         ["JSON date handling",      65],
                         ["Hierarchical JSON data",  66],
                         ["Data aggr. funcs.",       10],
                         ["Vectorisation",           14],
                         ["Data binding",            15],
                         ["Integer pluck",           23],
                         ["Pluck expr. test",        40],
                         ["Data via URL",            34],
                         ["Data via URL (binding)",  67],
                         ["Data via URL (ng-model)", 68],
                         ["Missing data",            79]] },

               { title: "Layout",
                 items: [["Layout #1",             42],
                         ["Layout #2",             43],
                         ["Layout #3",             44],
                         ["Layout #4",             45],
                         ["Layout #5",             46],
                         ["Layout #6",             47],
                         ["Simple plot stack",      8],
                         ["Complex plot stack",    63],
                         ["Nested plot stacks",    64]] },

               { title: "Palettes",
                 items: [["Norm. palette",         25],
                         ["Disc. palette",         26],
                         ["Disc. pal. (mark)",     27],
                         ["Func. + pal.",          28],
                         ["Func. + abs. pal.",     29],
                         ["Abs. pal. terrain",     30],
                         ["Banded pal.",           33],
                         ["Comp. pal. #1",         36],
                         ["Comp. pal. #2",         37],
                         ["Gradient pal.",         38],
                         ["Categorical palettes",  50]] },

               { title: "Discrete data",
                 items: [["Categorical points",    59],
                         ["Categorical bars #1",   60],
                         ["Categorical bars #2",   61],
                         ["Categorical bars #3",   62],
                         ["Categorical lines",     82]] },

               { title: "Formatting",
                 items: [["<plot-options>",        16],
                         ["Plot titles #1",        41],
                         ["Font selection #1",     49],
                         ["Font selection #2",     72],
                         ["Scientific notation",   55],
                         ["Date axis formatting",  56],
                         ["Explicit ticks",        57],
                         ["Tick sizes/padding",    58],
                         ["Legends",               77],
                         ["Legends #2",            78],
                         ["Legends #3 (metadata)", 83]] },

               { title: "Bigger examples",
                 items: [["Health & wealth",       39]] },

               { title: "Bugs",
                 items: [["Tom's data example",    24],
                         ["Test",                  22],
                         ["plot-options bug",      31],
                         ["Palettes & ng-repeat",  48],
                         ["Histogram nonsense",    75],
                         ["Tom's area plots",      80],
                         ["JSON dates & metadata", 84],
                         ["Beat's date problem",   85]] } ];


angular.module('myApp', ['radian']).
  config(['$routeProvider', function($routeProvider) {
    for (var eg = 1; eg <= negs; ++eg) {
      var n = (eg < 10 ? '0' : '') + eg;
      $routeProvider.when('/' + n, { templateUrl: 'eg/' + n + '.html',
                                     controller: EgCtrl });
    }
    $routeProvider.otherwise({ redirectTo: '/01' });
  }]).
  controller('BaseController',
  ['$rootScope', function($rootScope) {
    $rootScope.egs = [];
    for (var grp = 0; grp < eggrps.length; ++grp) {
      var grpitems = [];
      for (var i = 0; i < eggrps[grp].items.length; ++i) {
        var egtitle = eggrps[grp].items[i][0];
        var eg = eggrps[grp].items[i][1];
        var n = (eg < 10 ? '0' : '') + eg;
        grpitems.push({ title: egtitle, link: "#/" + n });
      }
      $rootScope.egs.push({ title: eggrps[grp].title, items: grpitems,
                            id: "grp" + grp, idhash: "#grp" + grp });
    }

    $rootScope.pals = { bgr: '0 blue; 0.5 grey; 1 red',
                        gyo: '0 green; 0.5 yellow; 1 orange' };
  }]);

radian.css

/* SVG CSS */


.radian svg {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  /* Trying to get SVG to act like a greedy block in all browsers */
  display: block;
  width:100%;
  height:100%;
}

.radian svg .no-data text { font-size: 24px; font-weight: bold; }

.radian .background {
  fill: white;
  fill-opacity: 0;
  /*
  pointer-events: none;
  */
}

div.radian { position: relative; }
div.radian div.radian { position: absolute; }
div.radian-ui {
    background-color: transparent;
    position: absolute;
    top: 0px;
    left: 0px; }
div.radian-axis-switch { position: absolute; white-space: nowrap; }
div.radian-stroke-switch { position: absolute; white-space: nowrap; }
div.radian-histogram-switch { position: absolute; white-space: nowrap; }
div.radian-legend-switch { position: absolute; white-space: nowrap; }
div.radian-legend-switch input {
    position: absolute;
    display: block;
    margin: 0px;
}


/* Axes */

.radian .axis path {
  fill: none;
  stroke: #000;
  stroke-opacity: .75;
  shape-rendering: crispEdges;
}

.radian .axis line {
  fill: none;
  stroke: #000;
  stroke-opacity: .25;
  shape-rendering: crispEdges;
}

.radian .axis path.domain { stroke-opacity: .75; }
.radian .axis line.zero { stroke-opacity: .75; }

.radian .axis .axisMaxMin text { font-weight: bold; }



/* Brush */

.radian .brush .extent {
  stroke: #fff;
  fill-opacity: .125;
  shape-rendering: crispEdges;
}


.tab-content.radian-tabs { overflow: visible; }








/********************
 * HTML CSS
 */


/* .chartWrap { */
/*   margin: 0; */
/*   padding: 0; */
/*   overflow: hidden; */
/* } */


/********************
 * TOOLTIP CSS
 */

/* .nvtooltip { */
/*   position: absolute; */
/*   background-color: rgba(255,255,255,1); */
/*   padding: 10px; */
/*   border: 1px solid #ddd; */
/*   z-index: 10000; */

/*   font-family: Arial; */
/*   font-size: 13px; */

/*   transition: opacity 500ms linear; */
/*   -moz-transition: opacity 500ms linear; */
/*   -webkit-transition: opacity 500ms linear; */

/*   transition-delay: 500ms; */
/*   -moz-transition-delay: 500ms; */
/*   -webkit-transition-delay: 500ms; */

/*   -moz-box-shadow: 4px 4px 8px rgba(0,0,0,.5); */
/*   -webkit-box-shadow: 4px 4px 8px rgba(0,0,0,.5); */
/*   box-shadow: 4px 4px 8px rgba(0,0,0,.5); */

/*   -moz-border-radius: 10px; */
/*   border-radius: 10px; */

/*   pointer-events: none; */

/*   -webkit-touch-callout: none; */
/*   -webkit-user-select: none; */
/*   -khtml-user-select: none; */
/*   -moz-user-select: none; */
/*   -ms-user-select: none; */
/*   user-select: none; */
/* } */

/* .nvtooltip h3 { */
/*   margin: 0; */
/*   padding: 0; */
/*   text-align: center; */
/* } */

/* .nvtooltip p { */
/*   margin: 0; */
/*   padding: 0; */
/*   text-align: center; */
/* } */

/* .nvtooltip span { */
/*   display: inline-block; */
/*   margin: 2px 0; */
/* } */

/* .nvtooltip-pending-removal { */
/*   position: absolute; */
/*   pointer-events: none; */
/* } */


/**********
*  Legend
*/

/* .radian .nv-legend .nv-series { */
/*   cursor: pointer; */
/* } */

/* .radian .nv-legend .disabled circle { */
/*   fill-opacity: 0; */
/* } */






/**********
*  Brush
*/

/* .nv-brush .resize path { */
/*   fill: #eee; */
/*   stroke: #666; */
/* } */



/**********
*  Bars
*/

/* .radian .nv-bars .negative rect { */
/*     zfill: brown; */
/* } */

/* .radian .nv-bars rect { */
/*   zfill: steelblue; */
/*   fill-opacity: .75; */

/*   transition: fill-opacity 250ms linear; */
/*   -moz-transition: fill-opacity 250ms linear; */
/*   -webkit-transition: fill-opacity 250ms linear; */
/* } */

/* .radian .nv-bars rect:hover { */
/*   fill-opacity: 1; */
/* } */

/* .radian .nv-bars .hover rect { */
/*   fill: lightblue; */
/* } */

/* .radian .nv-bars text { */
/*   fill: rgba(0,0,0,0); */
/* } */

/* .radian .nv-bars .hover text { */
/*   fill: rgba(0,0,0,1); */
/* } */


/**********
*  Bars
*/

/* .radian .nv-multibar .nv-groups rect, */
/* .radian .nv-multibarHorizontal .nv-groups rect, */
/* .radian .nv-discretebar .nv-groups rect { */
/*   stroke-opacity: 0; */

/*   transition: fill-opacity 250ms linear; */
/*   -moz-transition: fill-opacity 250ms linear; */
/*   -webkit-transition: fill-opacity 250ms linear; */
/* } */

/* .radian .nv-multibar .nv-groups rect:hover, */
/* .radian .nv-multibarHorizontal .nv-groups rect:hover, */
/* .radian .nv-discretebar .nv-groups rect:hover { */
/*   fill-opacity: 1; */
/* } */

/* .radian .nv-discretebar .nv-groups text, */
/* .radian .nv-multibarHorizontal .nv-groups text { */
/*   font-weight: bold; */
/*   fill: rgba(0,0,0,1); */
/*   stroke: rgba(0,0,0,0); */
/* } */

/***********
*  Pie Chart
*/

/* .radian.nv-pie path { */
/*   stroke-opacity: 0; */

/*   transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear; */
/*   -moz-transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear; */
/*   -webkit-transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear; */

/* } */

/* .radian.nv-pie .nv-slice text { */
/*   stroke: #000; */
/*   stroke-width: 0; */
/* } */

/* .radian.nv-pie path { */
/*   stroke: #fff; */
/*   stroke-width: 1px; */
/*   stroke-opacity: 1; */
/* } */

/* .radian.nv-pie .hover path { */
/*   fill-opacity: .7; */
/* /\* */
/*   stroke-width: 6px; */
/*   stroke-opacity: 1; */
/* *\/ */
/* } */

/* .radian.nv-pie .nv-label rect { */
/*   fill-opacity: 0; */
/*   stroke-opacity: 0; */
/* } */

/**********
* Lines
*/

/* .radian .nv-groups path.nv-line { */
/*   fill: none; */
/*   stroke-width: 2.5px; */
/*   /\* */
/*   stroke-linecap: round; */
/*   shape-rendering: geometricPrecision; */

/*   transition: stroke-width 250ms linear; */
/*   -moz-transition: stroke-width 250ms linear; */
/*   -webkit-transition: stroke-width 250ms linear; */

/*   transition-delay: 250ms */
/*   -moz-transition-delay: 250ms; */
/*   -webkit-transition-delay: 250ms; */
/*   *\/ */
/* } */

/* .radian .nv-groups path.nv-line-multiple { */
/*   fill: none; */
/*   stroke-width: 1.5px; */
/* } */

/* .radian .nv-groups path.nv-line-vary { */
/*   fill: none; */
/*   stroke-width: 1.5px; */
/* } */

/* .radian .nv-groups path.nv-line-vary-multiple { */
/*   fill: none; */
/*   stroke-width: 1.5px; */
/* } */

/* .radian .nv-groups path.nv-area { */
/*   stroke: none; */
/*   /\* */
/*   stroke-linecap: round; */
/*   shape-rendering: geometricPrecision; */

/*   stroke-width: 2.5px; */
/*   transition: stroke-width 250ms linear; */
/*   -moz-transition: stroke-width 250ms linear; */
/*   -webkit-transition: stroke-width 250ms linear; */

/*   transition-delay: 250ms */
/*   -moz-transition-delay: 250ms; */
/*   -webkit-transition-delay: 250ms; */
/*   *\/ */
/* } */

/* .radian .nv-line.hover path { */
/*   stroke-width: 6px; */
/* } */

/* /\* */
/* .radian.scatter .groups .point { */
/*   fill-opacity: 0.1; */
/*   stroke-opacity: 0.1; */
/* } */
/*   *\/ */

/* .radian.nv-line .radian.nv-scatter .nv-groups .nv-point { */
/*   fill-opacity: 0; */
/*   stroke-opacity: 0; */
/* } */

/* .radian.nv-scatter.nv-single-point .nv-groups .nv-point { */
/*   fill-opacity: .5 !important; */
/*   stroke-opacity: .5 !important; */
/* } */


/* .radian .nv-groups .nv-point { */
/*   transition: stroke-width 250ms linear, stroke-opacity 250ms linear; */
/*   -moz-transition: stroke-width 250ms linear, stroke-opacity 250ms linear; */
/*   -webkit-transition: stroke-width 250ms linear, stroke-opacity 250ms linear; */
/* } */

/* .radian.nv-scatter .nv-groups .nv-point.hover, */
/* .radian .nv-groups .nv-point.hover { */
/*   stroke-width: 20px; */
/*   fill-opacity: .5 !important; */
/*   stroke-opacity: .5 !important; */
/* } */


/* .radian .nv-point-paths path { */
/*   stroke: #aaa; */
/*   stroke-opacity: 0; */
/*   fill: #eee; */
/*   fill-opacity: 0; */
/* } */



/* .radian .nv-indexLine { */
/*   cursor: ew-resize; */
/* } */


/**********
* Distribution
*/

/* .radian .nv-distribution { */
/*   pointer-events: none; */
/* } */



/**********
*  Scatter
*/

/* **Attempting to remove this for useVoronoi(false), need to see if it's required anywhere
.radian .nv-groups .nv-point {
  pointer-events: none;
}
*/

/* .radian .nv-groups .nv-point.hover { */
/*   stroke-width: 20px; */
/*   stroke-opacity: .5; */
/* } */

/* .radian .nv-scatter .nv-point.hover { */
/*   fill-opacity: 1; */
/* } */

/* /\* */
/* .nv-group.hover .nv-point { */
/*   fill-opacity: 1; */
/* } */
/* *\/ */


/**********
*  Stacked Area
*/

/* .radian.nv-stackedarea path.nv-area { */
/*   fill-opacity: .7; */
/*   /\* */
/*   stroke-opacity: .65; */
/*   fill-opacity: 1; */
/*   *\/ */
/*   stroke-opacity: 0; */

/*   transition: fill-opacity 250ms linear, stroke-opacity 250ms linear; */
/*   -moz-transition: fill-opacity 250ms linear, stroke-opacity 250ms linear; */
/*   -webkit-transition: fill-opacity 250ms linear, stroke-opacity 250ms linear; */

/*   /\* */
/*   transition-delay: 500ms; */
/*   -moz-transition-delay: 500ms; */
/*   -webkit-transition-delay: 500ms; */
/*   *\/ */

/* } */

/* .radian.nv-stackedarea path.nv-area.hover { */
/*   fill-opacity: .9; */
/*   /\* */
/*   stroke-opacity: .85; */
/*   *\/ */
/* } */
/* /\* */
/* .d3stackedarea .groups path { */
/*   stroke-opacity: 0; */
/* } */
/*   *\/ */



/* .radian.nv-stackedarea .nv-groups .nv-point { */
/*   stroke-opacity: 0; */
/*   fill-opacity: 0; */
/* } */

/* .radian.nv-stackedarea .nv-groups .nv-point.hover { */
/*   stroke-width: 20px; */
/*   stroke-opacity: .75; */
/*   fill-opacity: 1; */
/* } */



/**********
*  Line Plus Bar
*/

/* .radian.nv-linePlusBar .nv-bar rect { */
/*   fill-opacity: .75; */
/* } */

/* .radian.nv-linePlusBar .nv-bar rect:hover { */
/*   fill-opacity: 1; */
/* } */


/**********
*  Bullet
*/

/* .radian.nv-bullet { font: 10px sans-serif; } */
/* .radian.nv-bullet .nv-measure { fill-opacity: .8; } */
/* .radian.nv-bullet .nv-measure:hover { fill-opacity: 1; } */
/* .radian.nv-bullet .nv-marker { stroke: #000; stroke-width: 2px; } */
/* .radian.nv-bullet .nv-markerTriangle { stroke: #000; fill: #fff; stroke-width: 1.5px; } */
/* .radian.nv-bullet .nv-tick line { stroke: #666; stroke-width: .5px; } */
/* .radian.nv-bullet .nv-range.nv-s0 { fill: #eee; } */
/* .radian.nv-bullet .nv-range.nv-s1 { fill: #ddd; } */
/* .radian.nv-bullet .nv-range.nv-s2 { fill: #ccc; } */
/* .radian.nv-bullet .nv-title { font-size: 14px; font-weight: bold; } */
/* .radian.nv-bullet .nv-subtitle { fill: #999; } */


/* .radian.nv-bullet .nv-range { */
/*   fill: #999; */
/*   fill-opacity: .4; */
/* } */
/* .radian.nv-bullet .nv-range:hover { */
/*   fill-opacity: .7; */
/* } */



/**********
* Sparkline
*/

/* .radian.nv-sparkline path { */
/*   fill: none; */
/* } */

/* .radian.nv-sparklineplus g.nv-hoverValue { */
/*   pointer-events: none; */
/* } */

/* .radian.nv-sparklineplus .nv-hoverValue line { */
/*   stroke: #333; */
/*   stroke-width: 1.5px; */
/*  } */

/* .radian.nv-sparklineplus, */
/* .radian.nv-sparklineplus g { */
/*   pointer-events: all; */
/* } */

/* .radian .nv-hoverArea { */
/*   fill-opacity: 0; */
/*   stroke-opacity: 0; */
/* } */

/* .radian.nv-sparklineplus .nv-xValue, */
/* .radian.nv-sparklineplus .nv-yValue { */
/*   /\* */
/*   stroke: #666; */
/*   *\/ */
/*   stroke-width: 0; */
/*   font-size: .9em; */
/*   font-weight: normal; */
/* } */

/* .radian.nv-sparklineplus .nv-yValue { */
/*   stroke: #f66; */
/* } */

/* .radian.nv-sparklineplus .nv-maxValue { */
/*   stroke: #2ca02c; */
/*   fill: #2ca02c; */
/* } */

/* .radian.nv-sparklineplus .nv-minValue { */
/*   stroke: #d62728; */
/*   fill: #d62728; */
/* } */

/* .radian.nv-sparklineplus .nv-currentValue { */
/*   /\* */
/*   stroke: #444; */
/*   fill: #000; */
/*   *\/ */
/*   font-weight: bold; */
/*   font-size: 1.1em; */
/* } */

/**********
* historical stock
*/

/* .radian.nv-ohlcBar .nv-ticks .nv-tick { */
/*   stroke-width: 2px; */
/* } */

/* .radian.nv-ohlcBar .nv-ticks .nv-tick.hover { */
/*   stroke-width: 4px; */
/* } */

/* .radian.nv-ohlcBar .nv-ticks .nv-tick.positive { */
/*  stroke: #2ca02c; */
/* } */

/* .radian.nv-ohlcBar .nv-ticks .nv-tick.negative { */
/*  stroke: #d62728; */
/* } */

/* .radian.nv-historicalStockChart .nv-axis .nv-axislabel { */
/*   font-weight: bold; */
/* } */

/* .radian.nv-historicalStockChart .nv-dragTarget { */
/*   fill-opacity: 0; */
/*   stroke: none; */
/*   cursor: move; */
/* } */

/* .radian .nv-brush .extent { */
/*   /\* */
/*   cursor: ew-resize !important; */
/*   *\/ */
/*   fill-opacity: 0 !important; */
/* } */

/* .radian .nv-brushBackground rect { */
/*   stroke: #000; */
/*   stroke-width: .4; */
/*   fill: #fff; */
/*   fill-opacity: .7; */
/* } */



/**********
* Indented Tree
*/


/**
 * TODO: the following 3 selectors are based on classes used in the example.  I should either make them standard and leave them here, or move to a CSS file not included in the library
 */
/* .radian.nv-indentedtree .name { */
/*   margin-left: 5px; */
/* } */

/* .radian.nv-indentedtree .clickable { */
/*   color: #08C; */
/*   cursor: pointer; */
/* } */

/* .radian.nv-indentedtree span.clickable:hover { */
/*   color: #005580; */
/*   text-decoration: underline; */
/* } */


/* .radian.nv-indentedtree .nv-childrenCount { */
/*   display: inline-block; */
/*   margin-left: 5px; */
/* } */

/* .radian.nv-indentedtree .nv-treeicon { */
/*   cursor: pointer; */
/*   /\* */
/*   cursor: n-resize; */
/*   *\/ */
/* } */

/* .radian.nv-indentedtree .nv-treeicon.nv-folded { */
/*   cursor: pointer; */
/*   /\* */
/*   cursor: s-resize; */
/*   *\/ */
/* } */