rickshaw-rails 1.4.6 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +12 -1
  4. data/.travis.yml +5 -0
  5. data/Gemfile +11 -1
  6. data/README.md +3 -1
  7. data/Rakefile +16 -1
  8. data/bower.json +3 -3
  9. data/lib/rickshaw_rails/engine.rb +3 -4
  10. data/lib/rickshaw_rails/version.rb +2 -2
  11. data/rickshaw-rails.gemspec +19 -17
  12. data/test/dummy/README.rdoc +28 -0
  13. data/test/dummy/Rakefile +6 -0
  14. data/test/dummy/app/assets/images/.keep +0 -0
  15. data/test/dummy/app/assets/javascripts/application.js +14 -0
  16. data/test/dummy/app/assets/javascripts/welcome.js +2 -0
  17. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  18. data/test/dummy/app/assets/stylesheets/welcome.css +4 -0
  19. data/test/dummy/app/controllers/application_controller.rb +5 -0
  20. data/test/dummy/app/controllers/concerns/.keep +0 -0
  21. data/test/dummy/app/controllers/welcome_controller.rb +4 -0
  22. data/test/dummy/app/helpers/application_helper.rb +2 -0
  23. data/test/dummy/app/helpers/welcome_helper.rb +2 -0
  24. data/test/dummy/app/mailers/.keep +0 -0
  25. data/test/dummy/app/models/.keep +0 -0
  26. data/test/dummy/app/models/concerns/.keep +0 -0
  27. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  28. data/test/dummy/app/views/welcome/index.html.erb +2 -0
  29. data/test/dummy/bin/bundle +3 -0
  30. data/test/dummy/bin/rails +4 -0
  31. data/test/dummy/bin/rake +4 -0
  32. data/test/dummy/config.ru +4 -0
  33. data/test/dummy/config/application.rb +22 -0
  34. data/test/dummy/config/boot.rb +5 -0
  35. data/test/dummy/config/database.yml +25 -0
  36. data/test/dummy/config/environment.rb +5 -0
  37. data/test/dummy/config/environments/development.rb +37 -0
  38. data/test/dummy/config/environments/production.rb +82 -0
  39. data/test/dummy/config/environments/test.rb +39 -0
  40. data/test/dummy/config/initializers/assets.rb +8 -0
  41. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  42. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  43. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  44. data/test/dummy/config/initializers/inflections.rb +16 -0
  45. data/test/dummy/config/initializers/mime_types.rb +4 -0
  46. data/test/dummy/config/initializers/session_store.rb +3 -0
  47. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  48. data/test/dummy/config/locales/en.yml +23 -0
  49. data/test/dummy/config/routes.rb +58 -0
  50. data/test/dummy/config/secrets.yml +22 -0
  51. data/test/dummy/lib/assets/.keep +0 -0
  52. data/test/dummy/log/.keep +0 -0
  53. data/test/dummy/public/404.html +67 -0
  54. data/test/dummy/public/422.html +67 -0
  55. data/test/dummy/public/500.html +66 -0
  56. data/test/dummy/public/favicon.ico +0 -0
  57. data/test/dummy/test/controllers/welcome_controller_test.rb +9 -0
  58. data/test/dummy/test/helpers/welcome_helper_test.rb +4 -0
  59. data/test/rickshaw_rails/engine_test.rb +15 -0
  60. data/test/rickshaw_rails/version_test.rb +17 -0
  61. data/test/rickshaw_rails_test.rb +9 -0
  62. data/test/test_helper.rb +21 -0
  63. data/vendor/assets/rickshaw-rails/rickshaw/rickshaw.css +5 -3
  64. data/vendor/assets/rickshaw-rails/rickshaw/rickshaw.js +169 -96
  65. metadata +239 -12
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+
3
+ require 'test_helper'
4
+
5
+ module RickshawRails
6
+ class EngineTest < ActiveSupport::TestCase
7
+ test 'Engine is a class' do
8
+ assert_kind_of Class, Engine
9
+ end
10
+
11
+ test 'Engine is inherited from Rails::Engine' do
12
+ assert Engine < ::Rails::Engine
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ require 'test_helper'
4
+
5
+ module RickshawRails
6
+ class VersionTest < ActiveSupport::TestCase
7
+ test 'constants is defined' do
8
+ assert RickshawRails.const_defined?(:VERSION)
9
+
10
+ assert Version.const_defined?(:STRING)
11
+ assert Version.const_defined?(:MAJOR)
12
+ assert Version.const_defined?(:MINOR)
13
+ assert Version.const_defined?(:TINY)
14
+ assert Version.const_defined?(:PRE)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+
3
+ require 'test_helper'
4
+
5
+ class RickshawRailsTest < ActiveSupport::TestCase
6
+ test 'RickshawRails is a module' do
7
+ assert_kind_of Module, RickshawRails
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ require 'coveralls'
4
+ Coveralls.wear!
5
+
6
+ # Configure Rails Environment
7
+ ENV['RAILS_ENV'] = 'test'
8
+
9
+ require File.expand_path('../dummy/config/environment.rb', __FILE__)
10
+ require 'rails/test_help'
11
+ require 'minitest/pride'
12
+
13
+ Rails.backtrace_cleaner.remove_silencers!
14
+
15
+ # Load support files
16
+ Dir['#{File.dirname(__FILE__)}/support/**/*.rb'].each { |f| require f }
17
+
18
+ # Load fixtures from the engine
19
+ if ActiveSupport::TestCase.method_defined?(:fixture_path=)
20
+ ActiveSupport::TestCase.fixture_path = File.expand_path('../fixtures', __FILE__)
21
+ end
@@ -87,11 +87,13 @@
87
87
  .rickshaw_graph .detail .dot {
88
88
  width: 4px;
89
89
  height: 4px;
90
- margin-left: -2px;
91
- margin-top: -2px;
90
+ margin-left: -3px;
91
+ margin-top: -3.5px;
92
92
  border-radius: 5px;
93
93
  position: absolute;
94
94
  box-shadow: 0 0 2px rgba(0, 0, 0, 0.6);
95
+ box-sizing: content-box;
96
+ -moz-box-sizing: content-box;
95
97
  background: white;
96
98
  border-width: 2px;
97
99
  border-style: solid;
@@ -217,7 +219,7 @@
217
219
  .rickshaw_graph .x_axis_d3 {
218
220
  fill: none;
219
221
  }
220
- .rickshaw_graph .y_ticks .tick,
222
+ .rickshaw_graph .y_ticks .tick line,
221
223
  .rickshaw_graph .x_ticks_d3 .tick {
222
224
  stroke: rgba(0, 0, 0, 0.16);
223
225
  stroke-width: 2px;
@@ -1,3 +1,14 @@
1
+ (function (root, factory) {
2
+ if (typeof define === 'function' && define.amd) {
3
+ define(['d3'], function (d3) {
4
+ return (root.Rickshaw = factory(d3));
5
+ });
6
+ } else if (typeof exports === 'object') {
7
+ module.exports = factory(require('d3'));
8
+ } else {
9
+ root.Rickshaw = factory(d3);
10
+ }
11
+ }(this, function (d3) {
1
12
  /* jshint -W079 */
2
13
 
3
14
  var Rickshaw = {
@@ -34,12 +45,6 @@ var Rickshaw = {
34
45
  return JSON.parse(JSON.stringify(obj));
35
46
  }
36
47
  };
37
-
38
- if (typeof module !== 'undefined' && module.exports) {
39
- var d3 = require('d3');
40
- module.exports = Rickshaw;
41
- }
42
-
43
48
  /* Adapted from https://github.com/Jakobo/PTClass */
44
49
 
45
50
  /*
@@ -404,7 +409,8 @@ Rickshaw.Graph = function(args) {
404
409
  max: undefined,
405
410
  preserve: false,
406
411
  xScale: undefined,
407
- yScale: undefined
412
+ yScale: undefined,
413
+ stack: true
408
414
  };
409
415
 
410
416
  this._loadRenderers();
@@ -453,13 +459,15 @@ Rickshaw.Graph = function(args) {
453
459
  if (!Array.isArray(s.data)) {
454
460
  throw "series data is not an array: " + JSON.stringify(s.data);
455
461
  }
462
+
463
+ if (s.data.length > 0) {
464
+ var x = s.data[0].x;
465
+ var y = s.data[0].y;
456
466
 
457
- var x = s.data[0].x;
458
- var y = s.data[0].y;
459
-
460
- if (typeof x != 'number' || ( typeof y != 'number' && y !== null ) ) {
461
- throw "x and y properties of points should be numbers instead of " +
462
- (typeof x) + " and " + (typeof y);
467
+ if (typeof x != 'number' || ( typeof y != 'number' && y !== null ) ) {
468
+ throw "x and y properties of points should be numbers instead of " +
469
+ (typeof x) + " and " + (typeof y);
470
+ }
463
471
  }
464
472
 
465
473
  if (s.data.length >= 3) {
@@ -486,8 +494,17 @@ Rickshaw.Graph = function(args) {
486
494
 
487
495
  var domain = this.renderer.domain();
488
496
 
489
- this.x = (this.xScale || d3.scale.linear()).domain(domain.x).range([0, this.width]);
490
- this.y = (this.yScale || d3.scale.linear()).domain(domain.y).range([this.height, 0]);
497
+ // this.*Scale is coming from the configuration dictionary
498
+ // which may be referenced by the Graph creator, or shared
499
+ // with other Graphs. We need to ensure we copy the scale
500
+ // so that our mutations do not change the object given to us.
501
+ // Hence the .copy()
502
+ this.x = (this.xScale || d3.scale.linear()).copy().domain(domain.x).range([0, this.width]);
503
+ this.y = (this.yScale || d3.scale.linear()).copy().domain(domain.y).range([this.height, 0]);
504
+
505
+ this.x.magnitude = d3.scale.linear()
506
+ .domain([domain.x[0] - domain.x[0], domain.x[1] - domain.x[0]])
507
+ .range([0, this.width]);
491
508
 
492
509
  this.y.magnitude = d3.scale.linear()
493
510
  .domain([domain.y[0] - domain.y[0], domain.y[1] - domain.y[0]])
@@ -643,6 +660,8 @@ Rickshaw.Graph = function(args) {
643
660
  this[k] = this.config[k];
644
661
  }, this );
645
662
 
663
+ if ('stack' in args) args.unstack = !args.stack;
664
+
646
665
  var renderer = args.renderer || (this.renderer && this.renderer.name) || 'stack';
647
666
  this.setRenderer(renderer, args);
648
667
 
@@ -1222,7 +1241,7 @@ Rickshaw.Graph.Ajax = Rickshaw.Class.create( {
1222
1241
 
1223
1242
  request: function() {
1224
1243
 
1225
- $.ajax( {
1244
+ jQuery.ajax( {
1226
1245
  url: this.dataURL,
1227
1246
  dataType: 'json',
1228
1247
  success: this.success.bind(this),
@@ -1851,21 +1870,21 @@ Rickshaw.Graph.Behavior.Series.Order = function(args) {
1851
1870
 
1852
1871
  var self = this;
1853
1872
 
1854
- if (typeof window.$ == 'undefined') {
1855
- throw "couldn't find jQuery at window.$";
1873
+ if (typeof window.jQuery == 'undefined') {
1874
+ throw "couldn't find jQuery at window.jQuery";
1856
1875
  }
1857
1876
 
1858
- if (typeof window.$.ui == 'undefined') {
1859
- throw "couldn't find jQuery UI at window.$.ui";
1877
+ if (typeof window.jQuery.ui == 'undefined') {
1878
+ throw "couldn't find jQuery UI at window.jQuery.ui";
1860
1879
  }
1861
1880
 
1862
- $(function() {
1863
- $(self.legend.list).sortable( {
1881
+ jQuery(function() {
1882
+ jQuery(self.legend.list).sortable( {
1864
1883
  containment: 'parent',
1865
1884
  tolerance: 'pointer',
1866
1885
  update: function( event, ui ) {
1867
1886
  var series = [];
1868
- $(self.legend.list).find('li').each( function(index, item) {
1887
+ jQuery(self.legend.list).find('li').each( function(index, item) {
1869
1888
  if (!item.series) return;
1870
1889
  series.push(item.series);
1871
1890
  } );
@@ -1877,7 +1896,7 @@ Rickshaw.Graph.Behavior.Series.Order = function(args) {
1877
1896
  self.graph.update();
1878
1897
  }
1879
1898
  } );
1880
- $(self.legend.list).disableSelection();
1899
+ jQuery(self.legend.list).disableSelection();
1881
1900
  });
1882
1901
 
1883
1902
  //hack to make jquery-ui sortable behave
@@ -1896,6 +1915,7 @@ Rickshaw.Graph.Behavior.Series.Toggle = function(args) {
1896
1915
  var self = this;
1897
1916
 
1898
1917
  this.addAnchor = function(line) {
1918
+
1899
1919
  var anchor = document.createElement('a');
1900
1920
  anchor.innerHTML = '&#10004;';
1901
1921
  anchor.classList.add('action');
@@ -1962,6 +1982,7 @@ Rickshaw.Graph.Behavior.Series.Toggle = function(args) {
1962
1982
 
1963
1983
  if (this.legend) {
1964
1984
 
1985
+ var $ = jQuery;
1965
1986
  if (typeof $ != 'undefined' && $(this.legend.list).sortable) {
1966
1987
 
1967
1988
  $(this.legend.list).sortable( {
@@ -2293,7 +2314,7 @@ Rickshaw.Graph.JSONP = Rickshaw.Class.create( Rickshaw.Graph.Ajax, {
2293
2314
 
2294
2315
  request: function() {
2295
2316
 
2296
- $.ajax( {
2317
+ jQuery.ajax( {
2297
2318
  url: this.dataURL,
2298
2319
  dataType: 'jsonp',
2299
2320
  success: this.success.bind(this),
@@ -2397,6 +2418,8 @@ Rickshaw.Graph.RangeSlider = Rickshaw.Class.create({
2397
2418
  var element = this.element = args.element;
2398
2419
  var graph = this.graph = args.graph;
2399
2420
 
2421
+ this.slideCallbacks = [];
2422
+
2400
2423
  this.build();
2401
2424
 
2402
2425
  graph.onUpdate( function() { this.update() }.bind(this) );
@@ -2406,8 +2429,10 @@ Rickshaw.Graph.RangeSlider = Rickshaw.Class.create({
2406
2429
 
2407
2430
  var element = this.element;
2408
2431
  var graph = this.graph;
2432
+ var $ = jQuery;
2409
2433
 
2410
2434
  var domain = graph.dataDomain();
2435
+ var self = this;
2411
2436
 
2412
2437
  $( function() {
2413
2438
  $(element).slider( {
@@ -2432,9 +2457,14 @@ Rickshaw.Graph.RangeSlider = Rickshaw.Class.create({
2432
2457
  if (domain[0] == ui.values[0]) {
2433
2458
  graph.window.xMin = undefined;
2434
2459
  }
2460
+
2435
2461
  if (domain[1] == ui.values[1]) {
2436
2462
  graph.window.xMax = undefined;
2437
2463
  }
2464
+
2465
+ self.slideCallbacks.forEach(function(callback) {
2466
+ callback(graph, graph.window.xMin, graph.window.xMax);
2467
+ });
2438
2468
  }
2439
2469
  } );
2440
2470
  } );
@@ -2447,6 +2477,7 @@ Rickshaw.Graph.RangeSlider = Rickshaw.Class.create({
2447
2477
 
2448
2478
  var element = this.element;
2449
2479
  var graph = this.graph;
2480
+ var $ = jQuery;
2450
2481
 
2451
2482
  var values = $(element).slider('option', 'values');
2452
2483
 
@@ -2463,6 +2494,10 @@ Rickshaw.Graph.RangeSlider = Rickshaw.Class.create({
2463
2494
  }
2464
2495
 
2465
2496
  $(element).slider('option', 'values', values);
2497
+ },
2498
+
2499
+ onSlide: function(callback) {
2500
+ this.slideCallbacks.push(callback);
2466
2501
  }
2467
2502
  });
2468
2503
 
@@ -2476,6 +2511,8 @@ Rickshaw.Graph.RangeSlider.Preview = Rickshaw.Class.create({
2476
2511
  if (!args.graph && !args.graphs) throw "Rickshaw.Graph.RangeSlider.Preview needs a reference to an graph or an array of graphs";
2477
2512
 
2478
2513
  this.element = args.element;
2514
+ this.element.style.position = 'relative';
2515
+
2479
2516
  this.graphs = args.graph ? [ args.graph ] : args.graphs;
2480
2517
 
2481
2518
  this.defaults = {
@@ -2486,28 +2523,45 @@ Rickshaw.Graph.RangeSlider.Preview = Rickshaw.Class.create({
2486
2523
  frameHandleThickness: 10,
2487
2524
  frameColor: "#d4d4d4",
2488
2525
  frameOpacity: 1,
2489
- minimumFrameWidth: 0
2526
+ minimumFrameWidth: 0,
2527
+ heightRatio: 0.2
2490
2528
  };
2491
2529
 
2530
+ this.heightRatio = args.heightRatio || this.defaults.heightRatio;
2492
2531
  this.defaults.gripperColor = d3.rgb(this.defaults.frameColor).darker().toString();
2493
2532
 
2494
2533
  this.configureCallbacks = [];
2534
+ this.slideCallbacks = [];
2535
+
2495
2536
  this.previews = [];
2496
2537
 
2538
+ if (!args.width) this.widthFromGraph = true;
2539
+ if (!args.height) this.heightFromGraph = true;
2540
+
2541
+ if (this.widthFromGraph || this.heightFromGraph) {
2542
+ this.graphs[0].onConfigure(function () {
2543
+ this.configure(args); this.render();
2544
+ }.bind(this));
2545
+ }
2546
+
2497
2547
  args.width = args.width || this.graphs[0].width || this.defaults.width;
2498
- args.height = args.height || this.graphs[0].height / 5 || this.defaults.height;
2548
+ args.height = args.height || this.graphs[0].height * this.heightRatio || this.defaults.height;
2499
2549
 
2500
2550
  this.configure(args);
2501
2551
  this.render();
2502
2552
  },
2503
2553
 
2554
+ onSlide: function(callback) {
2555
+ this.slideCallbacks.push(callback);
2556
+ },
2557
+
2504
2558
  onConfigure: function(callback) {
2505
2559
  this.configureCallbacks.push(callback);
2506
2560
  },
2507
2561
 
2508
2562
  configure: function(args) {
2509
2563
 
2510
- this.config = {};
2564
+ this.config = this.config || {};
2511
2565
 
2512
2566
  this.configureCallbacks.forEach(function(callback) {
2513
2567
  callback(args);
@@ -2519,17 +2573,29 @@ Rickshaw.Graph.RangeSlider.Preview = Rickshaw.Class.create({
2519
2573
  : this.defaults[k];
2520
2574
  }, this);
2521
2575
 
2522
- if (args.width) {
2523
- this.previews.forEach(function(preview) {
2524
- var width = args.width - this.config.frameHandleThickness * 2;
2525
- preview.setSize({ width: width });
2526
- }, this);
2527
- }
2576
+ if ('width' in args || 'height' in args) {
2577
+
2578
+ if (this.widthFromGraph) {
2579
+ this.config.width = this.graphs[0].width;
2580
+ }
2581
+
2582
+ if (this.heightFromGraph) {
2583
+ this.config.height = this.graphs[0].height * this.heightRatio;
2584
+ this.previewHeight = this.config.height;
2585
+ }
2528
2586
 
2529
- if (args.height) {
2530
2587
  this.previews.forEach(function(preview) {
2531
- var height = this.previewHeight / this.graphs.length;
2532
- preview.setSize({ height: height });
2588
+
2589
+ var height = this.previewHeight / this.graphs.length - this.config.frameTopThickness * 2;
2590
+ var width = this.config.width - this.config.frameHandleThickness * 2;
2591
+ preview.setSize({ width: width, height: height });
2592
+
2593
+ if (this.svg) {
2594
+ var svgHeight = height + this.config.frameHandleThickness * 2;
2595
+ var svgWidth = width + this.config.frameHandleThickness * 2;
2596
+ this.svg.style("width", svgWidth + "px");
2597
+ this.svg.style("height", svgHeight + "px");
2598
+ }
2533
2599
  }, this);
2534
2600
  }
2535
2601
  },
@@ -2551,12 +2617,14 @@ Rickshaw.Graph.RangeSlider.Preview = Rickshaw.Class.create({
2551
2617
 
2552
2618
  var graphArgs = Rickshaw.extend({}, parent.config);
2553
2619
  var height = self.previewHeight / self.graphs.length;
2620
+ var renderer = parent.renderer.name;
2554
2621
 
2555
2622
  Rickshaw.extend(graphArgs, {
2556
2623
  element: this.appendChild(document.createElement("div")),
2557
2624
  height: height,
2558
2625
  width: self.previewWidth,
2559
- series: parent.series
2626
+ series: parent.series,
2627
+ renderer: renderer
2560
2628
  });
2561
2629
 
2562
2630
  var graph = new Rickshaw.Graph(graphArgs);
@@ -2567,6 +2635,7 @@ Rickshaw.Graph.RangeSlider.Preview = Rickshaw.Class.create({
2567
2635
  parent.onConfigure(function(args) {
2568
2636
  // don't propagate height
2569
2637
  delete args.height;
2638
+ args.width = args.width - self.config.frameHandleThickness * 2;
2570
2639
  graph.configure(args);
2571
2640
  graph.render();
2572
2641
  });
@@ -2620,8 +2689,8 @@ Rickshaw.Graph.RangeSlider.Preview = Rickshaw.Class.create({
2620
2689
  .classed("rickshaw_range_slider_preview", true)
2621
2690
  .style("height", this.config.height + "px")
2622
2691
  .style("width", this.config.width + "px")
2623
- .style("position", "relative")
2624
- .style("top", -this.previewHeight + "px");
2692
+ .style("position", "absolute")
2693
+ .style("top", 0);
2625
2694
 
2626
2695
  this._renderDimming();
2627
2696
  this._renderFrame();
@@ -2721,12 +2790,13 @@ Rickshaw.Graph.RangeSlider.Preview = Rickshaw.Class.create({
2721
2790
  leftHandle.enter()
2722
2791
  .append("rect")
2723
2792
  .attr('width', this.config.frameHandleThickness)
2724
- .attr('height', this.config.height)
2725
2793
  .style("cursor", "ew-resize")
2726
2794
  .style("fill-opacity", "0")
2727
2795
  .classed("left_handle", true);
2728
2796
 
2729
- leftHandle.attr('x', this.currentFrame[0]);
2797
+ leftHandle
2798
+ .attr('x', this.currentFrame[0])
2799
+ .attr('height', this.config.height);
2730
2800
 
2731
2801
  var rightHandle = this.svg.selectAll("rect.right_handle")
2732
2802
  .data([null]);
@@ -2734,12 +2804,13 @@ Rickshaw.Graph.RangeSlider.Preview = Rickshaw.Class.create({
2734
2804
  rightHandle.enter()
2735
2805
  .append("rect")
2736
2806
  .attr('width', this.config.frameHandleThickness)
2737
- .attr('height', this.config.height)
2738
2807
  .style("cursor", "ew-resize")
2739
2808
  .style("fill-opacity", "0")
2740
2809
  .classed("right_handle", true);
2741
2810
 
2742
- rightHandle.attr('x', this.currentFrame[1] + this.config.frameHandleThickness);
2811
+ rightHandle
2812
+ .attr('x', this.currentFrame[1] + this.config.frameHandleThickness)
2813
+ .attr('height', this.config.height);
2743
2814
  },
2744
2815
 
2745
2816
  _renderMiddle: function() {
@@ -2749,14 +2820,14 @@ Rickshaw.Graph.RangeSlider.Preview = Rickshaw.Class.create({
2749
2820
 
2750
2821
  middleHandle.enter()
2751
2822
  .append("rect")
2752
- .attr('height', this.config.height)
2753
2823
  .style("cursor", "move")
2754
2824
  .style("fill-opacity", "0")
2755
2825
  .classed("middle_handle", true);
2756
2826
 
2757
2827
  middleHandle
2758
2828
  .attr('width', Math.max(0, this.currentFrame[1] - this.currentFrame[0]))
2759
- .attr('x', this.currentFrame[0] + this.config.frameHandleThickness);
2829
+ .attr('x', this.currentFrame[0] + this.config.frameHandleThickness)
2830
+ .attr('height', this.config.height);
2760
2831
  },
2761
2832
 
2762
2833
  _registerMouseEvents: function() {
@@ -2814,7 +2885,7 @@ Rickshaw.Graph.RangeSlider.Preview = Rickshaw.Class.create({
2814
2885
  self.graphs.forEach(function(graph) {
2815
2886
 
2816
2887
  var domainScale = d3.scale.linear()
2817
- .interpolate(d3.interpolateRound)
2888
+ .interpolate(d3.interpolateNumber)
2818
2889
  .domain([0, self.previewWidth])
2819
2890
  .range(graph.dataDomain());
2820
2891
 
@@ -2823,6 +2894,10 @@ Rickshaw.Graph.RangeSlider.Preview = Rickshaw.Class.create({
2823
2894
  domainScale(frameAfterDrag[1])
2824
2895
  ];
2825
2896
 
2897
+ self.slideCallbacks.forEach(function(callback) {
2898
+ callback(graph, windowAfterDrag[0], windowAfterDrag[1]);
2899
+ });
2900
+
2826
2901
  if (frameAfterDrag[0] === 0) {
2827
2902
  windowAfterDrag[0] = undefined;
2828
2903
  }
@@ -2831,7 +2906,7 @@ Rickshaw.Graph.RangeSlider.Preview = Rickshaw.Class.create({
2831
2906
  }
2832
2907
  graph.window.xMin = windowAfterDrag[0];
2833
2908
  graph.window.xMax = windowAfterDrag[1];
2834
-
2909
+
2835
2910
  graph.update();
2836
2911
  });
2837
2912
  }
@@ -2936,19 +3011,14 @@ Rickshaw.Graph.Renderer = Rickshaw.Class.create( {
2936
3011
  },
2937
3012
 
2938
3013
  domain: function(data) {
2939
-
3014
+ // Requires that at least one series contains some data
2940
3015
  var stackedData = data || this.graph.stackedData || this.graph.stackData();
2941
- var firstPoint = stackedData[0][0];
2942
-
2943
- if (firstPoint === undefined) {
2944
- return { x: [null, null], y: [null, null] };
2945
- }
2946
3016
 
2947
- var xMin = firstPoint.x;
2948
- var xMax = firstPoint.x;
3017
+ var xMin = +Infinity;
3018
+ var xMax = -Infinity;
2949
3019
 
2950
- var yMin = firstPoint.y + firstPoint.y0;
2951
- var yMax = firstPoint.y + firstPoint.y0;
3020
+ var yMin = +Infinity;
3021
+ var yMax = -Infinity;
2952
3022
 
2953
3023
  stackedData.forEach( function(series) {
2954
3024
 
@@ -3181,7 +3251,7 @@ Rickshaw.Graph.Renderer.Bar = Rickshaw.Class.create( Rickshaw.Graph.Renderer, {
3181
3251
  barWidth: function(series) {
3182
3252
 
3183
3253
  var frequentInterval = this._frequentInterval(series.stack);
3184
- var barWidth = this.graph.x(series.stack[0].x + frequentInterval.magnitude * (1 - this.gapSize));
3254
+ var barWidth = this.graph.x.magnitude(frequentInterval.magnitude) * (1 - this.gapSize);
3185
3255
 
3186
3256
  return barWidth;
3187
3257
  },
@@ -3456,8 +3526,14 @@ Rickshaw.Graph.Renderer.Multi = Rickshaw.Class.create( Rickshaw.Graph.Renderer,
3456
3526
  .map( function(s) { return s.stack });
3457
3527
 
3458
3528
  if (!data.length) return;
3459
-
3460
- var domain = $super(data);
3529
+
3530
+ var domain = null;
3531
+ if (group.renderer && group.renderer.domain) {
3532
+ domain = group.renderer.domain(data);
3533
+ }
3534
+ else {
3535
+ domain = $super(data);
3536
+ }
3461
3537
  domains.push(domain);
3462
3538
  });
3463
3539
 
@@ -3586,10 +3662,6 @@ Rickshaw.Graph.Renderer.LinePlot = Rickshaw.Class.create( Rickshaw.Graph.Rendere
3586
3662
  } );
3587
3663
  },
3588
3664
 
3589
- initialize: function($super, args) {
3590
- $super(args);
3591
- },
3592
-
3593
3665
  seriesPathFactory: function() {
3594
3666
 
3595
3667
  var graph = this.graph;
@@ -3603,20 +3675,45 @@ Rickshaw.Graph.Renderer.LinePlot = Rickshaw.Class.create( Rickshaw.Graph.Rendere
3603
3675
  return factory;
3604
3676
  },
3605
3677
 
3606
- _renderDots: function() {
3678
+ render: function(args) {
3679
+
3680
+ args = args || {};
3607
3681
 
3608
3682
  var graph = this.graph;
3609
3683
 
3610
- graph.series.forEach(function(series) {
3684
+ var series = args.series || graph.series;
3685
+ var vis = args.vis || graph.vis;
3686
+
3687
+ var dotSize = this.dotSize;
3688
+
3689
+ vis.selectAll('*').remove();
3690
+
3691
+ var data = series
3692
+ .filter(function(s) { return !s.disabled })
3693
+ .map(function(s) { return s.stack });
3694
+
3695
+ var nodes = vis.selectAll("path")
3696
+ .data(data)
3697
+ .enter().append("svg:path")
3698
+ .attr("d", this.seriesPathFactory());
3699
+
3700
+ var i = 0;
3701
+ series.forEach(function(series) {
3702
+ if (series.disabled) return;
3703
+ series.path = nodes[0][i++];
3704
+ this._styleSeries(series);
3705
+ }, this);
3706
+
3707
+ series.forEach(function(series) {
3611
3708
 
3612
3709
  if (series.disabled) return;
3613
3710
 
3614
- var nodes = graph.vis.selectAll("x")
3711
+ var nodes = vis.selectAll("x")
3615
3712
  .data(series.stack.filter( function(d) { return d.y !== null } ))
3616
3713
  .enter().append("svg:circle")
3617
3714
  .attr("cx", function(d) { return graph.x(d.x) })
3618
3715
  .attr("cy", function(d) { return graph.y(d.y) })
3619
- .attr("r", function(d) { return ("r" in d) ? d.r : graph.renderer.dotSize});
3716
+ .attr("r", function(d) { return ("r" in d) ? d.r : dotSize});
3620
3717
 
3621
3718
  Array.prototype.forEach.call(nodes[0], function(n) {
3622
3719
  if (!n) return;
@@ -3628,33 +3725,6 @@ Rickshaw.Graph.Renderer.LinePlot = Rickshaw.Class.create( Rickshaw.Graph.Rendere
3628
3725
  }.bind(this));
3629
3726
 
3630
3727
  }, this);
3631
- },
3632
-
3633
- _renderLines: function() {
3634
-
3635
- var graph = this.graph;
3636
-
3637
- var nodes = graph.vis.selectAll("path")
3638
- .data(this.graph.stackedData)
3639
- .enter().append("svg:path")
3640
- .attr("d", this.seriesPathFactory());
3641
-
3642
- var i = 0;
3643
- graph.series.forEach(function(series) {
3644
- if (series.disabled) return;
3645
- series.path = nodes[0][i++];
3646
- this._styleSeries(series);
3647
- }, this);
3648
- },
3649
-
3650
- render: function() {
3651
-
3652
- var graph = this.graph;
3653
-
3654
- graph.vis.selectAll('*').remove();
3655
-
3656
- this._renderLines();
3657
- this._renderDots();
3658
3728
  }
3659
3729
  } );
3660
3730
 
@@ -3680,6 +3750,7 @@ Rickshaw.Graph.Smoother = Rickshaw.Class.create({
3680
3750
  build: function() {
3681
3751
 
3682
3752
  var self = this;
3753
+ var $ = jQuery;
3683
3754
 
3684
3755
  if (this.element) {
3685
3756
  $( function() {
@@ -3992,3 +4063,5 @@ Rickshaw.Series.FixedDuration = Rickshaw.Class.create(Rickshaw.Series, {
3992
4063
  }
3993
4064
  } );
3994
4065
 
4066
+ return Rickshaw;
4067
+ }));