blacklight_range_limit 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
 - data/Gemfile +5 -0
 - data/README.rdoc +44 -20
 - data/VERSION +1 -1
 - data/app/assets/javascripts/blacklight_range_limit.js +0 -1
 - data/blacklight_range_limit.gemspec +7 -0
 - data/lib/blacklight_range_limit/controller_override.rb +1 -1
 - data/lib/blacklight_range_limit/engine.rb +6 -0
 - data/lib/generators/blacklight_range_limit/assets_generator.rb +3 -2
 - data/spec/acceptance/blacklight_range_limit_spec.rb +36 -0
 - data/spec/integration/blacklight_stub_spec.rb +10 -0
 - data/spec/internal/app/controllers/application_controller.rb +4 -0
 - data/spec/internal/app/models/solr_document.rb +3 -0
 - data/spec/internal/config/database.yml +3 -0
 - data/spec/internal/config/routes.rb +6 -0
 - data/spec/internal/config/solr.yml +18 -0
 - data/spec/internal/db/combustion_test.sqlite +0 -0
 - data/spec/internal/db/schema.rb +53 -0
 - data/spec/internal/log/.gitignore +1 -0
 - data/spec/internal/public/favicon.ico +0 -0
 - data/spec/spec_helper.rb +25 -0
 - data/{app → vendor}/assets/javascripts/flot/excanvas.min.js +0 -0
 - data/{app → vendor}/assets/javascripts/flot/jquery.flot.js +276 -190
 - data/{app → vendor}/assets/javascripts/flot/jquery.flot.selection.js +31 -15
 - metadata +102 -11
 
    
        data/.gitignore
    CHANGED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/README.rdoc
    CHANGED
    
    | 
         @@ -23,13 +23,19 @@ The pre Solr 1.4 now deprecated sint or slong types should work fine too. 
     | 
|
| 
       23 
23 
     | 
    
         | 
| 
       24 
24 
     | 
    
         
             
            = Installation
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
      
 26 
     | 
    
         
            +
            Recent versions of this plugin require Blacklight versions 3.2 or later, which requires Rails 3.1 or later and the Rails asset pipeline. 
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
28 
     | 
    
         
             
            Add
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
       29 
30 
     | 
    
         
             
               gem "blacklight_range_limit"
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
       30 
32 
     | 
    
         
             
            to your Gemfile. Run "bundle install". 
         
     | 
| 
       31 
33 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
            Then run  
     | 
| 
      
 34 
     | 
    
         
            +
            Then run 
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                rails generate blacklight_range_limit 
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            This will install some asset references in your application.js and application.css.
         
     | 
| 
       33 
39 
     | 
    
         | 
| 
       34 
40 
     | 
    
         
             
            = Configuration
         
     | 
| 
       35 
41 
     | 
    
         | 
| 
         @@ -39,7 +45,6 @@ You have at least one solr field you want to display as a range limit, that's wh 
     | 
|
| 
       39 
45 
     | 
    
         | 
| 
       40 
46 
     | 
    
         
             
            You should now get range limit display. More complicated configuration is available if desired, see Range Facet Configuration below. 
         
     | 
| 
       41 
47 
     | 
    
         | 
| 
       42 
     | 
    
         
            -
            Note that the plugin will be default inject links to the Flot JQuery plugin, and a couple dependencies. The weird way it has to do this may fail in weird configurations.  You can turn this off and instead include Flot and its dependencies manually in your application, see Injection below. 
         
     | 
| 
       43 
48 
     | 
    
         | 
| 
       44 
49 
     | 
    
         
             
            You can also configure the look and feel of the Flot chart using the jQuery .data() method. On the `.facet_limit` container you want to configure, add a Flot options associative array (documented at http://people.iola.dk/olau/flot/API.txt) as the `plot-config` key. The `plot-config` key to set the `plot-config` key on the appropriate `.facet_limit` container. In order to customize the plot colors, for example, you could use this code:
         
     | 
| 
       45 
50 
     | 
    
         | 
| 
         @@ -52,6 +57,7 @@ You can also configure the look and feel of the Flot chart using the jQuery .dat 
     | 
|
| 
       52 
57 
     | 
    
         | 
| 
       53 
58 
     | 
    
         
             
            You can add this configuration in app/assets/javascript/application.js, or anywhere else loaded before the blacklight range limit javascript.
         
     | 
| 
       54 
59 
     | 
    
         | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
       55 
61 
     | 
    
         
             
            == A note on AJAX use
         
     | 
| 
       56 
62 
     | 
    
         | 
| 
       57 
63 
     | 
    
         
             
            In order to calculate distribution segment ranges, we need to first know the min and max boundaries. But we don't really know that until we've fetched the result set (we use the Solr Stats component to get min and max with a result set). 
         
     | 
| 
         @@ -69,24 +75,33 @@ Note that a drill-down will never require the second request, because boundaries 
     | 
|
| 
       69 
75 
     | 
    
         | 
| 
       70 
76 
     | 
    
         
             
            Instead of simply passing "true", you can pass a hash with additional configuration. Here's an example with all the available keys, you don't need to use them all, just the ones you want to set to non-default values. 
         
     | 
| 
       71 
77 
     | 
    
         | 
| 
       72 
     | 
    
         
            -
            config.add_facet_field 'pub_date', :label => 'Publication Year', :range => {
         
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
                 
     | 
| 
       77 
     | 
    
         
            -
                :segments => false    
         
     | 
| 
       78 
     | 
    
         
            -
              }
         
     | 
| 
      
 78 
     | 
    
         
            +
                config.add_facet_field 'pub_date', :label => 'Publication Year', :range => {
         
     | 
| 
      
 79 
     | 
    
         
            +
                  :num_segments => 6,
         
     | 
| 
      
 80 
     | 
    
         
            +
                  :assumed_boundaries => [1100, Time.now.year + 2],
         
     | 
| 
      
 81 
     | 
    
         
            +
                  :segments => false    
         
     | 
| 
      
 82 
     | 
    
         
            +
                }
         
     | 
| 
       79 
83 
     | 
    
         | 
| 
       80 
84 
     | 
    
         
             
            [num_segments]
         
     | 
| 
       81 
85 
     | 
    
         
             
               Default 10. Approximately how many segments to divide the range into for segment facets, which become segments on the chart. Actual segments are calculated to be 'nice' values, so may not exactly match your setting.  
         
     | 
| 
       82 
86 
     | 
    
         
             
            [assumed_boundaries]
         
     | 
| 
       83 
87 
     | 
    
         
             
               Default null. For a result set that has not yet been limited, instead of taking boundaries from results and making a second AJAX request to fetch segments, just assume these given boundaries. If you'd like to avoid this second AJAX Solr call, you can set :assumed_boundaries to a two-element array of integers instead, and the assumed boundaries will always be used. Note this is live ruby code, you can put calculations in there like Time.now.year + 2. 
         
     | 
| 
       84 
     | 
    
         
            -
            [:slider_js]
         
     | 
| 
       85 
     | 
    
         
            -
               Default true. If set to false, then the slider javascript behavior will not be loaded.  Without this behavior, you will see a div with textual min and max values. You can hide that with CSS if you like. 
         
     | 
| 
       86 
     | 
    
         
            -
            [:chart_js]
         
     | 
| 
       87 
     | 
    
         
            -
               Default true. If set to false, then the Flot area-chart is not loaded. You will instead get textual facet values for each of the segment ranges. Note that this still often will result in a second AJAX request to fetch ranges, you haven't disabled AJAX by setting :chart_js=>true.  If you'd like to turn off segment ranges altogether, see :segments.  If you'd like to prevent the ajax but keep segments, see :assumed_boundaries. 
         
     | 
| 
       88 
88 
     | 
    
         
             
            [:segments]
         
     | 
| 
       89 
89 
     | 
    
         
             
               Default true. If set to false, then distribution segment facets will not be loaded at all.  
         
     | 
| 
      
 90 
     | 
    
         
            +
               
         
     | 
| 
      
 91 
     | 
    
         
            +
            == Javascript dependencies
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
            The selectable histograms/barcharts are done with Javascript, using Flot[http://code.google.com/p/flot/]. Flot requires JQuery, as well as support for the HTML5 canvas element. In IE previous to IE9, canvas element support is added with excanvas[http://excanvas.sourceforge.net/]. 
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            A `require 'blacklight_range_limit'` in a Rails asset pipeline manifest file will automatically include all of these things. The blacklight_range_limit adds just this line to your `app/assets/application.js`. 
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
            There is a copy of flot vendored in this gem for this purpose. jquery is obtained from the jquery-rails gem, which this gem depends on. 
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
            Note this means a copy of jquery, from the jquery-rails gem, will be included in your assets by blacklight_range_limit even if you didn't include it yourself explicitly in application.js. Flot will also be included.
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
            If you don't want any of this gem's JS, you can simply remove the `require 'blacklight_range_limit'` line from your application.js, and hack something else together yourself. 
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
            The excanvas inclusion for IE is handled a bit differently. Coudln't get conditional inclusion of excanvas in pure JS to work, it does need an actual seperate script line in the HTML document surrounded by IE conditional comments; this gem adds that line using Blacklight's `extra_head_content` feature allowing dependencies to inject content in HTML head; requires your layout to follow BL conventions, or just add excanvas yourself manually. This gem's attempt to inject the excanvas script line can be turned off in configuration, see Injection below. 
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
       90 
105 
     | 
    
         | 
| 
       91 
106 
     | 
    
         
             
            == Injection
         
     | 
| 
       92 
107 
     | 
    
         | 
| 
         @@ -103,20 +118,29 @@ to turn off all injection. The plugin will be completely non-functional if you d 
     | 
|
| 
       103 
118 
     | 
    
         
             
            You can also turn off injection of individual components, which could be more useful:
         
     | 
| 
       104 
119 
     | 
    
         | 
| 
       105 
120 
     | 
    
         
             
              BlacklightRangeLimit.omit_inject = {
         
     | 
| 
       106 
     | 
    
         
            -
                :excanvas => false,
         
     | 
| 
       107 
121 
     | 
    
         
             
                :view_helpers => false,
         
     | 
| 
       108 
     | 
    
         
            -
                :controller_mixin => false
         
     | 
| 
      
 122 
     | 
    
         
            +
                :controller_mixin => false,
         
     | 
| 
      
 123 
     | 
    
         
            +
                :routes => false,
         
     | 
| 
      
 124 
     | 
    
         
            +
                :excanvas => false
         
     | 
| 
       109 
125 
     | 
    
         
             
              }
         
     | 
| 
       110 
     | 
    
         
            -
            [:excanvas]
         
     | 
| 
       111 
     | 
    
         
            -
              Set to false to disable loading the IE 'excanvas' compatibility layer
         
     | 
| 
       112 
126 
     | 
    
         
             
            [:view_helpers]
         
     | 
| 
       113 
127 
     | 
    
         
             
              Set to false and the plugin will not insert it's own rails view helpers into the app. It will raise lots of errors if you do this, you probably don't want to. 
         
     | 
| 
       114 
128 
     | 
    
         
             
            [:controller_mixin]
         
     | 
| 
       115 
     | 
    
         
            -
              The plugin mixes some methods into CatalogController, both over-riding Blacklight methods, and providing a new action of it's own. Set to false, and the plugin won't. You've basically disabled the plugin if you do this. 
     | 
| 
      
 129 
     | 
    
         
            +
              The plugin mixes some methods into CatalogController, both over-riding Blacklight methods, and providing a new action of it's own. Set to false, and the plugin won't. You've basically disabled the plugin if you do this.  
         
     | 
| 
      
 130 
     | 
    
         
            +
            [:routes]
         
     | 
| 
      
 131 
     | 
    
         
            +
              Disable automatic routes loading
         
     | 
| 
      
 132 
     | 
    
         
            +
            [:excanvas]
         
     | 
| 
      
 133 
     | 
    
         
            +
              Disables injection of a conditionally-commented script tag to load the excanvas library for supporting 'canvas' on IE.  blacklight_range_limit does this in the controller mixin, using Blacklight's "extra_head_content" feature to add actual conditional script tag for IE in html <head>. 
         
     | 
| 
      
 134 
     | 
    
         
            +
              
         
     | 
| 
      
 135 
     | 
    
         
            +
            See Javascript Dependencies above for disabling injection of gem's js.   
         
     | 
| 
       116 
136 
     | 
    
         | 
| 
       117 
137 
     | 
    
         
             
            = Tests
         
     | 
| 
       118 
138 
     | 
    
         | 
| 
       119 
     | 
    
         
            -
             
     | 
| 
      
 139 
     | 
    
         
            +
            Start the Blacklight demo jetty server (on port 8983)
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
            Run the rspec tests by running:
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
              rspec
         
     | 
| 
       120 
144 
     | 
    
         | 
| 
       121 
145 
     | 
    
         
             
            = Possible future To Do
         
     | 
| 
       122 
146 
     | 
    
         
             
            * StatsComponent replacement. We use StatsComponent to get min/max of result set, as well as missing count. StatsComponent is included on every non-drilldown request, so ranges and slider can be displayed. However, StatsComponent really can slow down the solr response with a large result set. So replace StatsComponent with other strategies. No ideal ones, we can use facet.missing to get missing count instead, but RSolr makes it harder than it should be to grab this info. We can use seperate solr queries to get min/max (sort on our field, asc and desc), but this is more complicated, more solr queries, and possibly requires redesign of AJAXy stuff, so even a lone slider can have min/max. 
         
     | 
    
        data/VERSION
    CHANGED
    
    | 
         @@ -1 +1 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            1.2. 
     | 
| 
      
 1 
     | 
    
         
            +
            1.2.1
         
     | 
| 
         @@ -19,5 +19,12 @@ Gem::Specification.new do |s| 
     | 
|
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
              s.add_dependency "rails", "~> 3.0"
         
     | 
| 
      
 22 
     | 
    
         
            +
              s.add_dependency "jquery-rails" # our JS needs jquery_rails
         
     | 
| 
       22 
23 
     | 
    
         
             
              s.add_dependency "blacklight", "~> 3.2"
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              s.add_development_dependency "rspec"
         
     | 
| 
      
 26 
     | 
    
         
            +
              s.add_development_dependency "rspec-rails"
         
     | 
| 
      
 27 
     | 
    
         
            +
              s.add_development_dependency "capybara"
         
     | 
| 
      
 28 
     | 
    
         
            +
              s.add_development_dependency "sqlite3"
         
     | 
| 
      
 29 
     | 
    
         
            +
              s.add_development_dependency 'launchy'
         
     | 
| 
       23 
30 
     | 
    
         
             
            end
         
     | 
| 
         @@ -24,7 +24,7 @@ module BlacklightRangeLimit 
     | 
|
| 
       24 
24 
     | 
    
         
             
                      # canvas for IE. Need to inject it like this even with asset pipeline
         
     | 
| 
       25 
25 
     | 
    
         
             
                      # cause it needs IE conditional include. view_context hacky way
         
     | 
| 
       26 
26 
     | 
    
         
             
                      # to get asset url helpers. 
         
     | 
| 
       27 
     | 
    
         
            -
                      controller.extra_head_content << ('<!--[if IE]>' + view_context.javascript_include_tag("flot/excanvas.min.js") + '<![endif]-->').html_safe
         
     | 
| 
      
 27 
     | 
    
         
            +
                      controller.extra_head_content << ('<!--[if lt IE 9]>' + view_context.javascript_include_tag("flot/excanvas.min.js") + ' <![endif]-->').html_safe
         
     | 
| 
       28 
28 
     | 
    
         
             
                    end
         
     | 
| 
       29 
29 
     | 
    
         
             
                  end
         
     | 
| 
       30 
30 
     | 
    
         
             
                end
         
     | 
| 
         @@ -5,6 +5,12 @@ require 'rails' 
     | 
|
| 
       5 
5 
     | 
    
         
             
            module BlacklightRangeLimit
         
     | 
| 
       6 
6 
     | 
    
         
             
              class Engine < Rails::Engine
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
      
 8 
     | 
    
         
            +
                # Need to tell asset pipeline to precompile the excanvas
         
     | 
| 
      
 9 
     | 
    
         
            +
                # we use for IE. 
         
     | 
| 
      
 10 
     | 
    
         
            +
                initializer "blacklight_range_limit.assets", :after => "assets" do
         
     | 
| 
      
 11 
     | 
    
         
            +
                  Rails.application.config.assets.precompile += %w( flot/excanvas.min.js )
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
                
         
     | 
| 
       8 
14 
     | 
    
         
             
                # Do these things in a to_prepare block, to try and make them work
         
     | 
| 
       9 
15 
     | 
    
         
             
                # in development mode with class-reloading. The trick is we can't
         
     | 
| 
       10 
16 
     | 
    
         
             
                # be sure if the controllers we're modifying are being reloaded in
         
     | 
| 
         @@ -25,10 +25,11 @@ module BlacklightRangeLimit 
     | 
|
| 
       25 
25 
     | 
    
         
             
            }
         
     | 
| 
       26 
26 
     | 
    
         
             
                  end
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
                  insert_into_file "app/assets/javascripts/application.js", :after => "//= require jquery 
     | 
| 
      
 28 
     | 
    
         
            +
                  insert_into_file "app/assets/javascripts/application.js", :after => "//= require jquery\n" do
         
     | 
| 
       29 
29 
     | 
    
         
             
            %q{
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
       31 
     | 
    
         
            -
            //  
     | 
| 
      
 31 
     | 
    
         
            +
            // For blacklight_range_limit built-in JS, if you don't want it you don't need
         
     | 
| 
      
 32 
     | 
    
         
            +
            // this:
         
     | 
| 
       32 
33 
     | 
    
         
             
            //= require 'blacklight_range_limit'
         
     | 
| 
       33 
34 
     | 
    
         | 
| 
       34 
35 
     | 
    
         
             
            }          
         
     | 
| 
         @@ -0,0 +1,36 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe "Blacklight Range Limit" do
         
     | 
| 
      
 4 
     | 
    
         
            +
              before do
         
     | 
| 
      
 5 
     | 
    
         
            +
                CatalogController.blacklight_config = Blacklight::Configuration.new
         
     | 
| 
      
 6 
     | 
    
         
            +
                CatalogController.configure_blacklight do |config|
         
     | 
| 
      
 7 
     | 
    
         
            +
                  config.add_facet_field 'pub_date_sort', :range => true
         
     | 
| 
      
 8 
     | 
    
         
            +
                  config.default_solr_params[:'facet.field'] = config.facet_fields.keys
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              it "should show the range limit facet" do
         
     | 
| 
      
 14 
     | 
    
         
            +
                visit '/catalog?q='
         
     | 
| 
      
 15 
     | 
    
         
            +
                page.should have_selector 'input.range_begin'
         
     | 
| 
      
 16 
     | 
    
         
            +
                page.should have_selector 'input.range_end'
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              it "should provide distribution information" do
         
     | 
| 
      
 20 
     | 
    
         
            +
                visit '/catalog?q='
         
     | 
| 
      
 21 
     | 
    
         
            +
                click_link 'View distribution'
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                page.should have_content("1941 to 1944 (1)")
         
     | 
| 
      
 24 
     | 
    
         
            +
                page.should have_content("2005 to 2008 (7)")
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
              it "should limit appropriately" do
         
     | 
| 
      
 28 
     | 
    
         
            +
                visit '/catalog?q='
         
     | 
| 
      
 29 
     | 
    
         
            +
                click_link 'View distribution'
         
     | 
| 
      
 30 
     | 
    
         
            +
                click_link '1941 to 1944'
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                save_and_open_page
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                page.should have_content "1941 to 1944 (1) [remove]"
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,10 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe 'Blacklight Test Application' do
         
     | 
| 
      
 4 
     | 
    
         
            +
              it "should have a Blacklight module" do
         
     | 
| 
      
 5 
     | 
    
         
            +
                Blacklight.should be_a_kind_of(Module)
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
              it "should have a Catalog controller" do
         
     | 
| 
      
 8 
     | 
    
         
            +
                CatalogController.blacklight_config.should be_a_kind_of(Blacklight::Configuration)
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # = jetty_path key
         
     | 
| 
      
 2 
     | 
    
         
            +
            # each environment can have a jetty_path with absolute or relative
         
     | 
| 
      
 3 
     | 
    
         
            +
            # (to app root) path to a jetty/solr install. This is used
         
     | 
| 
      
 4 
     | 
    
         
            +
            # by the rake tasks that start up solr automatically for testing
         
     | 
| 
      
 5 
     | 
    
         
            +
            # and by rake solr:marc:index.  
         
     | 
| 
      
 6 
     | 
    
         
            +
            #
         
     | 
| 
      
 7 
     | 
    
         
            +
            # jetty_path is not used by a running Blacklight application
         
     | 
| 
      
 8 
     | 
    
         
            +
            # at all. In general you do NOT need to deploy solr in Jetty, you can deploy it
         
     | 
| 
      
 9 
     | 
    
         
            +
            # however you want.  
         
     | 
| 
      
 10 
     | 
    
         
            +
            # jetty_path is only required for rake tasks that need to know
         
     | 
| 
      
 11 
     | 
    
         
            +
            # how to start up solr, generally for automated testing. 
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            development:
         
     | 
| 
      
 14 
     | 
    
         
            +
              url: http://127.0.0.1:8983/solr
         
     | 
| 
      
 15 
     | 
    
         
            +
            test: &test
         
     | 
| 
      
 16 
     | 
    
         
            +
              url: http://127.0.0.1:8983/solr
         
     | 
| 
      
 17 
     | 
    
         
            +
            cucumber:
         
     | 
| 
      
 18 
     | 
    
         
            +
              <<: *test
         
     | 
| 
         Binary file 
     | 
| 
         @@ -0,0 +1,53 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: UTF-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            # This file is auto-generated from the current state of the database. Instead
         
     | 
| 
      
 3 
     | 
    
         
            +
            # of editing this file, please use the migrations feature of Active Record to
         
     | 
| 
      
 4 
     | 
    
         
            +
            # incrementally modify your database, and then regenerate this schema definition.
         
     | 
| 
      
 5 
     | 
    
         
            +
            #
         
     | 
| 
      
 6 
     | 
    
         
            +
            # Note that this schema.rb definition is the authoritative source for your
         
     | 
| 
      
 7 
     | 
    
         
            +
            # database schema. If you need to create the application database on another
         
     | 
| 
      
 8 
     | 
    
         
            +
            # system, you should be using db:schema:load, not running all the migrations
         
     | 
| 
      
 9 
     | 
    
         
            +
            # from scratch. The latter is a flawed and unsustainable approach (the more migrations
         
     | 
| 
      
 10 
     | 
    
         
            +
            # you'll amass, the slower it'll run and the greater likelihood for issues).
         
     | 
| 
      
 11 
     | 
    
         
            +
            #
         
     | 
| 
      
 12 
     | 
    
         
            +
            # It's strongly recommended to check this file into your version control system.
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            ActiveRecord::Schema.define(:version => 20111123152341) do
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              create_table "bookmarks", :force => true do |t|
         
     | 
| 
      
 17 
     | 
    
         
            +
                t.integer  "user_id",     :null => false
         
     | 
| 
      
 18 
     | 
    
         
            +
                t.string   "document_id"
         
     | 
| 
      
 19 
     | 
    
         
            +
                t.string   "title"
         
     | 
| 
      
 20 
     | 
    
         
            +
                t.datetime "created_at"
         
     | 
| 
      
 21 
     | 
    
         
            +
                t.datetime "updated_at"
         
     | 
| 
      
 22 
     | 
    
         
            +
                t.string   "user_type"
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              create_table "searches", :force => true do |t|
         
     | 
| 
      
 26 
     | 
    
         
            +
                t.text     "query_params"
         
     | 
| 
      
 27 
     | 
    
         
            +
                t.integer  "user_id"
         
     | 
| 
      
 28 
     | 
    
         
            +
                t.datetime "created_at"
         
     | 
| 
      
 29 
     | 
    
         
            +
                t.datetime "updated_at"
         
     | 
| 
      
 30 
     | 
    
         
            +
                t.string   "user_type"
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              add_index "searches", ["user_id"], :name => "index_searches_on_user_id"
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              create_table "users", :force => true do |t|
         
     | 
| 
      
 36 
     | 
    
         
            +
                t.string   "email",                                 :default => "", :null => false
         
     | 
| 
      
 37 
     | 
    
         
            +
                t.string   "encrypted_password",     :limit => 128, :default => "", :null => false
         
     | 
| 
      
 38 
     | 
    
         
            +
                t.string   "reset_password_token"
         
     | 
| 
      
 39 
     | 
    
         
            +
                t.datetime "reset_password_sent_at"
         
     | 
| 
      
 40 
     | 
    
         
            +
                t.datetime "remember_created_at"
         
     | 
| 
      
 41 
     | 
    
         
            +
                t.integer  "sign_in_count",                         :default => 0
         
     | 
| 
      
 42 
     | 
    
         
            +
                t.datetime "current_sign_in_at"
         
     | 
| 
      
 43 
     | 
    
         
            +
                t.datetime "last_sign_in_at"
         
     | 
| 
      
 44 
     | 
    
         
            +
                t.string   "current_sign_in_ip"
         
     | 
| 
      
 45 
     | 
    
         
            +
                t.string   "last_sign_in_ip"
         
     | 
| 
      
 46 
     | 
    
         
            +
                t.datetime "created_at"
         
     | 
| 
      
 47 
     | 
    
         
            +
                t.datetime "updated_at"
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
              add_index "users", ["email"], :name => "index_users_on_email", :unique => true
         
     | 
| 
      
 51 
     | 
    
         
            +
              add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            *.log
         
     | 
| 
         
            File without changes
         
     | 
    
        data/spec/spec_helper.rb
    ADDED
    
    | 
         @@ -0,0 +1,25 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'bundler'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            Bundler.require :default, :development
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            require 'blacklight/engine'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'rsolr'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require 'rsolr-ext'
         
     | 
| 
      
 9 
     | 
    
         
            +
            require 'capybara/rspec'
         
     | 
| 
      
 10 
     | 
    
         
            +
            Combustion.initialize!
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            Blacklight.solr_config = { :url => 'http://127.0.0.1:8983/solr' }
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            class SolrDocument
         
     | 
| 
      
 15 
     | 
    
         
            +
              include Blacklight::Solr::Document
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            require 'rspec/rails'
         
     | 
| 
      
 19 
     | 
    
         
            +
            require 'capybara/rails'
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            RSpec.configure do |config|
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
         
            File without changes
         
     | 
| 
         @@ -1,4 +1,4 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
      
 1 
     | 
    
         
            +
            /*! Javascript plotting library for jQuery, v. 0.7.
         
     | 
| 
       2 
2 
     | 
    
         
             
             *
         
     | 
| 
       3 
3 
     | 
    
         
             
             * Released under the MIT license by IOLA, December 2007.
         
     | 
| 
       4 
4 
     | 
    
         
             
             *
         
     | 
| 
         @@ -9,7 +9,7 @@ 
     | 
|
| 
       9 
9 
     | 
    
         | 
| 
       10 
10 
     | 
    
         
             
            /* Plugin for jQuery for working with colors.
         
     | 
| 
       11 
11 
     | 
    
         
             
             * 
         
     | 
| 
       12 
     | 
    
         
            -
             * Version 1. 
     | 
| 
      
 12 
     | 
    
         
            +
             * Version 1.1.
         
     | 
| 
       13 
13 
     | 
    
         
             
             * 
         
     | 
| 
       14 
14 
     | 
    
         
             
             * Inspiration from jQuery color animation plugin by John Resig.
         
     | 
| 
       15 
15 
     | 
    
         
             
             *
         
     | 
| 
         @@ -22,10 +22,13 @@ 
     | 
|
| 
       22 
22 
     | 
    
         
             
             *   console.log(c.r, c.g, c.b, c.a);
         
     | 
| 
       23 
23 
     | 
    
         
             
             *   $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)"
         
     | 
| 
       24 
24 
     | 
    
         
             
             *
         
     | 
| 
       25 
     | 
    
         
            -
             * Note that .scale() and .add()  
     | 
| 
       26 
     | 
    
         
            -
             * new  
     | 
| 
      
 25 
     | 
    
         
            +
             * Note that .scale() and .add() return the same modified object
         
     | 
| 
      
 26 
     | 
    
         
            +
             * instead of making a new one.
         
     | 
| 
      
 27 
     | 
    
         
            +
             *
         
     | 
| 
      
 28 
     | 
    
         
            +
             * V. 1.1: Fix error handling so e.g. parsing an empty string does
         
     | 
| 
      
 29 
     | 
    
         
            +
             * produce a color rather than just crashing.
         
     | 
| 
       27 
30 
     | 
    
         
             
             */ 
         
     | 
| 
       28 
     | 
    
         
            -
            (function(){ 
     | 
| 
      
 31 
     | 
    
         
            +
            (function(B){B.color={};B.color.make=function(F,E,C,D){var G={};G.r=F||0;G.g=E||0;G.b=C||0;G.a=D!=null?D:1;G.add=function(J,I){for(var H=0;H<J.length;++H){G[J.charAt(H)]+=I}return G.normalize()};G.scale=function(J,I){for(var H=0;H<J.length;++H){G[J.charAt(H)]*=I}return G.normalize()};G.toString=function(){if(G.a>=1){return"rgb("+[G.r,G.g,G.b].join(",")+")"}else{return"rgba("+[G.r,G.g,G.b,G.a].join(",")+")"}};G.normalize=function(){function H(J,K,I){return K<J?J:(K>I?I:K)}G.r=H(0,parseInt(G.r),255);G.g=H(0,parseInt(G.g),255);G.b=H(0,parseInt(G.b),255);G.a=H(0,G.a,1);return G};G.clone=function(){return B.color.make(G.r,G.b,G.g,G.a)};return G.normalize()};B.color.extract=function(D,C){var E;do{E=D.css(C).toLowerCase();if(E!=""&&E!="transparent"){break}D=D.parent()}while(!B.nodeName(D.get(0),"body"));if(E=="rgba(0, 0, 0, 0)"){E="transparent"}return B.color.parse(E)};B.color.parse=function(F){var E,C=B.color.make;if(E=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10))}if(E=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10),parseFloat(E[4]))}if(E=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55)}if(E=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55,parseFloat(E[4]))}if(E=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(F)){return C(parseInt(E[1],16),parseInt(E[2],16),parseInt(E[3],16))}if(E=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(F)){return C(parseInt(E[1]+E[1],16),parseInt(E[2]+E[2],16),parseInt(E[3]+E[3],16))}var D=B.trim(F).toLowerCase();if(D=="transparent"){return C(255,255,255,0)}else{E=A[D]||[0,0,0];return C(E[0],E[1],E[2])}};var A={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery);
         
     | 
| 
       29 
32 
     | 
    
         | 
| 
       30 
33 
     | 
    
         
             
            // the actual Flot code
         
     | 
| 
       31 
34 
     | 
    
         
             
            (function($) {
         
     | 
| 
         @@ -51,6 +54,7 @@ 
     | 
|
| 
       51 
54 
     | 
    
         
             
                                backgroundOpacity: 0.85 // set to 0 to avoid background
         
     | 
| 
       52 
55 
     | 
    
         
             
                            },
         
     | 
| 
       53 
56 
     | 
    
         
             
                            xaxis: {
         
     | 
| 
      
 57 
     | 
    
         
            +
                                show: null, // null = auto-detect, true = always, false = never
         
     | 
| 
       54 
58 
     | 
    
         
             
                                position: "bottom", // or "top"
         
     | 
| 
       55 
59 
     | 
    
         
             
                                mode: null, // null or "time"
         
     | 
| 
       56 
60 
     | 
    
         
             
                                color: null, // base color, labels, ticks
         
     | 
| 
         @@ -64,6 +68,7 @@ 
     | 
|
| 
       64 
68 
     | 
    
         
             
                                tickFormatter: null, // fn: number -> string
         
     | 
| 
       65 
69 
     | 
    
         
             
                                labelWidth: null, // size of tick labels in pixels
         
     | 
| 
       66 
70 
     | 
    
         
             
                                labelHeight: null,
         
     | 
| 
      
 71 
     | 
    
         
            +
                                reserveSpace: null, // whether to reserve space even if axis isn't shown
         
     | 
| 
       67 
72 
     | 
    
         
             
                                tickLength: null, // size in pixels of ticks, or "full" for whole line
         
     | 
| 
       68 
73 
     | 
    
         
             
                                alignTicksWithAxis: null, // axis number or null for no sync
         
     | 
| 
       69 
74 
     | 
    
         | 
| 
         @@ -119,6 +124,7 @@ 
     | 
|
| 
       119 
124 
     | 
    
         
             
                                labelMargin: 5, // in pixels
         
     | 
| 
       120 
125 
     | 
    
         
             
                                axisMargin: 8, // in pixels
         
     | 
| 
       121 
126 
     | 
    
         
             
                                borderWidth: 2, // in pixels
         
     | 
| 
      
 127 
     | 
    
         
            +
                                minBorderMargin: null, // in pixels, null means taken from points radius
         
     | 
| 
       122 
128 
     | 
    
         
             
                                markings: null, // array of ranges or fn: axes -> array of ranges
         
     | 
| 
       123 
129 
     | 
    
         
             
                                markingsColor: "#f4f4f4",
         
     | 
| 
       124 
130 
     | 
    
         
             
                                markingsLineWidth: 2,
         
     | 
| 
         @@ -145,7 +151,8 @@ 
     | 
|
| 
       145 
151 
     | 
    
         
             
                        drawSeries: [],
         
     | 
| 
       146 
152 
     | 
    
         
             
                        draw: [],
         
     | 
| 
       147 
153 
     | 
    
         
             
                        bindEvents: [],
         
     | 
| 
       148 
     | 
    
         
            -
                        drawOverlay: []
         
     | 
| 
      
 154 
     | 
    
         
            +
                        drawOverlay: [],
         
     | 
| 
      
 155 
     | 
    
         
            +
                        shutdown: []
         
     | 
| 
       149 
156 
     | 
    
         
             
                    },
         
     | 
| 
       150 
157 
     | 
    
         
             
                    plot = this;
         
     | 
| 
       151 
158 
     | 
    
         | 
| 
         @@ -165,30 +172,16 @@ 
     | 
|
| 
       165 
172 
     | 
    
         
             
                        return o;
         
     | 
| 
       166 
173 
     | 
    
         
             
                    };
         
     | 
| 
       167 
174 
     | 
    
         
             
                    plot.getData = function () { return series; };
         
     | 
| 
       168 
     | 
    
         
            -
                    plot.getAxis = function (dir, number) {
         
     | 
| 
       169 
     | 
    
         
            -
                        var a = (dir == x ? xaxes : yaxes)[number - 1];
         
     | 
| 
       170 
     | 
    
         
            -
                        if (a && !a.used)
         
     | 
| 
       171 
     | 
    
         
            -
                            a = null;
         
     | 
| 
       172 
     | 
    
         
            -
                        return a;
         
     | 
| 
       173 
     | 
    
         
            -
                    };
         
     | 
| 
       174 
175 
     | 
    
         
             
                    plot.getAxes = function () {
         
     | 
| 
       175 
176 
     | 
    
         
             
                        var res = {}, i;
         
     | 
| 
       176 
     | 
    
         
            -
                         
     | 
| 
       177 
     | 
    
         
            -
                             
     | 
| 
       178 
     | 
    
         
            -
             
     | 
| 
       179 
     | 
    
         
            -
             
     | 
| 
       180 
     | 
    
         
            -
             
     | 
| 
       181 
     | 
    
         
            -
                        // backwards compatibility - to be removed
         
     | 
| 
       182 
     | 
    
         
            -
                        if (!res.x2axis)
         
     | 
| 
       183 
     | 
    
         
            -
                            res.x2axis = { n: 2 };
         
     | 
| 
       184 
     | 
    
         
            -
                        if (!res.y2axis)
         
     | 
| 
       185 
     | 
    
         
            -
                            res.y2axis = { n: 2 };
         
     | 
| 
       186 
     | 
    
         
            -
                        
         
     | 
| 
      
 177 
     | 
    
         
            +
                        $.each(xaxes.concat(yaxes), function (_, axis) {
         
     | 
| 
      
 178 
     | 
    
         
            +
                            if (axis)
         
     | 
| 
      
 179 
     | 
    
         
            +
                                res[axis.direction + (axis.n != 1 ? axis.n : "") + "axis"] = axis;
         
     | 
| 
      
 180 
     | 
    
         
            +
                        });
         
     | 
| 
       187 
181 
     | 
    
         
             
                        return res;
         
     | 
| 
       188 
182 
     | 
    
         
             
                    };
         
     | 
| 
       189 
183 
     | 
    
         
             
                    plot.getXAxes = function () { return xaxes; };
         
     | 
| 
       190 
184 
     | 
    
         
             
                    plot.getYAxes = function () { return yaxes; };
         
     | 
| 
       191 
     | 
    
         
            -
                    plot.getUsedAxes = getUsedAxes; // return flat array with x and y axes that are in use
         
     | 
| 
       192 
185 
     | 
    
         
             
                    plot.c2p = canvasToAxisCoords;
         
     | 
| 
       193 
186 
     | 
    
         
             
                    plot.p2c = axisToCanvasCoords;
         
     | 
| 
       194 
187 
     | 
    
         
             
                    plot.getOptions = function () { return options; };
         
     | 
| 
         @@ -201,6 +194,12 @@ 
     | 
|
| 
       201 
194 
     | 
    
         
             
                            top: parseInt(yaxes[axisNumber(point, "y") - 1].p2c(+point.y) + plotOffset.top)
         
     | 
| 
       202 
195 
     | 
    
         
             
                        };
         
     | 
| 
       203 
196 
     | 
    
         
             
                    };
         
     | 
| 
      
 197 
     | 
    
         
            +
                    plot.shutdown = shutdown;
         
     | 
| 
      
 198 
     | 
    
         
            +
                    plot.resize = function () {
         
     | 
| 
      
 199 
     | 
    
         
            +
                        getCanvasDimensions();
         
     | 
| 
      
 200 
     | 
    
         
            +
                        resizeCanvas(canvas);
         
     | 
| 
      
 201 
     | 
    
         
            +
                        resizeCanvas(overlay);
         
     | 
| 
      
 202 
     | 
    
         
            +
                    };
         
     | 
| 
       204 
203 
     | 
    
         | 
| 
       205 
204 
     | 
    
         
             
                    // public attributes
         
     | 
| 
       206 
205 
     | 
    
         
             
                    plot.hooks = hooks;
         
     | 
| 
         @@ -208,7 +207,7 @@ 
     | 
|
| 
       208 
207 
     | 
    
         
             
                    // initialize
         
     | 
| 
       209 
208 
     | 
    
         
             
                    initPlugins(plot);
         
     | 
| 
       210 
209 
     | 
    
         
             
                    parseOptions(options_);
         
     | 
| 
       211 
     | 
    
         
            -
                     
     | 
| 
      
 210 
     | 
    
         
            +
                    setupCanvases();
         
     | 
| 
       212 
211 
     | 
    
         
             
                    setData(data_);
         
     | 
| 
       213 
212 
     | 
    
         
             
                    setupGrid();
         
     | 
| 
       214 
213 
     | 
    
         
             
                    draw();
         
     | 
| 
         @@ -256,20 +255,19 @@ 
     | 
|
| 
       256 
255 
     | 
    
         
             
                            options.xaxes[i] = $.extend(true, {}, options.xaxis, options.xaxes[i]);
         
     | 
| 
       257 
256 
     | 
    
         
             
                        for (i = 0; i < Math.max(1, options.yaxes.length); ++i)
         
     | 
| 
       258 
257 
     | 
    
         
             
                            options.yaxes[i] = $.extend(true, {}, options.yaxis, options.yaxes[i]);
         
     | 
| 
      
 258 
     | 
    
         
            +
             
     | 
| 
       259 
259 
     | 
    
         
             
                        // backwards compatibility, to be removed in future
         
     | 
| 
       260 
260 
     | 
    
         
             
                        if (options.xaxis.noTicks && options.xaxis.ticks == null)
         
     | 
| 
       261 
261 
     | 
    
         
             
                            options.xaxis.ticks = options.xaxis.noTicks;
         
     | 
| 
       262 
262 
     | 
    
         
             
                        if (options.yaxis.noTicks && options.yaxis.ticks == null)
         
     | 
| 
       263 
263 
     | 
    
         
             
                            options.yaxis.ticks = options.yaxis.noTicks;
         
     | 
| 
       264 
264 
     | 
    
         
             
                        if (options.x2axis) {
         
     | 
| 
       265 
     | 
    
         
            -
                            options. 
     | 
| 
       266 
     | 
    
         
            -
                            options.xaxes[1] =  
     | 
| 
      
 265 
     | 
    
         
            +
                            options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis);
         
     | 
| 
      
 266 
     | 
    
         
            +
                            options.xaxes[1].position = "top";
         
     | 
| 
       267 
267 
     | 
    
         
             
                        }
         
     | 
| 
       268 
268 
     | 
    
         
             
                        if (options.y2axis) {
         
     | 
| 
       269 
     | 
    
         
            -
                             
     | 
| 
       270 
     | 
    
         
            -
             
     | 
| 
       271 
     | 
    
         
            -
                            options.y2axis.position = "right";
         
     | 
| 
       272 
     | 
    
         
            -
                            options.yaxes[1] = options.y2axis;
         
     | 
| 
      
 269 
     | 
    
         
            +
                            options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis);
         
     | 
| 
      
 270 
     | 
    
         
            +
                            options.yaxes[1].position = "right";
         
     | 
| 
       273 
271 
     | 
    
         
             
                        }
         
     | 
| 
       274 
272 
     | 
    
         
             
                        if (options.grid.coloredAreas)
         
     | 
| 
       275 
273 
     | 
    
         
             
                            options.grid.markings = options.grid.coloredAreas;
         
     | 
| 
         @@ -281,9 +279,10 @@ 
     | 
|
| 
       281 
279 
     | 
    
         
             
                            $.extend(true, options.series.points, options.points);
         
     | 
| 
       282 
280 
     | 
    
         
             
                        if (options.bars)
         
     | 
| 
       283 
281 
     | 
    
         
             
                            $.extend(true, options.series.bars, options.bars);
         
     | 
| 
       284 
     | 
    
         
            -
                        if (options.shadowSize)
         
     | 
| 
      
 282 
     | 
    
         
            +
                        if (options.shadowSize != null)
         
     | 
| 
       285 
283 
     | 
    
         
             
                            options.series.shadowSize = options.shadowSize;
         
     | 
| 
       286 
284 
     | 
    
         | 
| 
      
 285 
     | 
    
         
            +
                        // save options on axes for future reference
         
     | 
| 
       287 
286 
     | 
    
         
             
                        for (i = 0; i < options.xaxes.length; ++i)
         
     | 
| 
       288 
287 
     | 
    
         
             
                            getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i];
         
     | 
| 
       289 
288 
     | 
    
         
             
                        for (i = 0; i < options.yaxes.length; ++i)
         
     | 
| 
         @@ -308,7 +307,7 @@ 
     | 
|
| 
       308 
307 
     | 
    
         
             
                        for (var i = 0; i < d.length; ++i) {
         
     | 
| 
       309 
308 
     | 
    
         
             
                            var s = $.extend(true, {}, options.series);
         
     | 
| 
       310 
309 
     | 
    
         | 
| 
       311 
     | 
    
         
            -
                            if (d[i].data) {
         
     | 
| 
      
 310 
     | 
    
         
            +
                            if (d[i].data != null) {
         
     | 
| 
       312 
311 
     | 
    
         
             
                                s.data = d[i].data; // move the data instead of deep-copy
         
     | 
| 
       313 
312 
     | 
    
         
             
                                delete d[i].data;
         
     | 
| 
       314 
313 
     | 
    
         | 
| 
         @@ -333,6 +332,11 @@ 
     | 
|
| 
       333 
332 
     | 
    
         
             
                        return a;
         
     | 
| 
       334 
333 
     | 
    
         
             
                    }
         
     | 
| 
       335 
334 
     | 
    
         | 
| 
      
 335 
     | 
    
         
            +
                    function allAxes() {
         
     | 
| 
      
 336 
     | 
    
         
            +
                        // return flat array without annoying null entries
         
     | 
| 
      
 337 
     | 
    
         
            +
                        return $.grep(xaxes.concat(yaxes), function (a) { return a; });
         
     | 
| 
      
 338 
     | 
    
         
            +
                    }
         
     | 
| 
      
 339 
     | 
    
         
            +
                    
         
     | 
| 
       336 
340 
     | 
    
         
             
                    function canvasToAxisCoords(pos) {
         
     | 
| 
       337 
341 
     | 
    
         
             
                        // return an object with x/y corresponding to all used axes 
         
     | 
| 
       338 
342 
     | 
    
         
             
                        var res = {}, i, axis;
         
     | 
| 
         @@ -367,7 +371,7 @@ 
     | 
|
| 
       367 
371 
     | 
    
         
             
                                if (pos[key] == null && axis.n == 1)
         
     | 
| 
       368 
372 
     | 
    
         
             
                                    key = "x";
         
     | 
| 
       369 
373 
     | 
    
         | 
| 
       370 
     | 
    
         
            -
                                if (pos[key]) {
         
     | 
| 
      
 374 
     | 
    
         
            +
                                if (pos[key] != null) {
         
     | 
| 
       371 
375 
     | 
    
         
             
                                    res.left = axis.p2c(pos[key]);
         
     | 
| 
       372 
376 
     | 
    
         
             
                                    break;
         
     | 
| 
       373 
377 
     | 
    
         
             
                                }
         
     | 
| 
         @@ -381,7 +385,7 @@ 
     | 
|
| 
       381 
385 
     | 
    
         
             
                                if (pos[key] == null && axis.n == 1)
         
     | 
| 
       382 
386 
     | 
    
         
             
                                    key = "y";
         
     | 
| 
       383 
387 
     | 
    
         | 
| 
       384 
     | 
    
         
            -
                                if (pos[key]) {
         
     | 
| 
      
 388 
     | 
    
         
            +
                                if (pos[key] != null) {
         
     | 
| 
       385 
389 
     | 
    
         
             
                                    res.top = axis.p2c(pos[key]);
         
     | 
| 
       386 
390 
     | 
    
         
             
                                    break;
         
     | 
| 
       387 
391 
     | 
    
         
             
                                }
         
     | 
| 
         @@ -391,21 +395,6 @@ 
     | 
|
| 
       391 
395 
     | 
    
         
             
                        return res;
         
     | 
| 
       392 
396 
     | 
    
         
             
                    }
         
     | 
| 
       393 
397 
     | 
    
         | 
| 
       394 
     | 
    
         
            -
                    function getUsedAxes() {
         
     | 
| 
       395 
     | 
    
         
            -
                        var res = [], i, axis;
         
     | 
| 
       396 
     | 
    
         
            -
                        for (i = 0; i < xaxes.length; ++i) {
         
     | 
| 
       397 
     | 
    
         
            -
                            axis = xaxes[i];
         
     | 
| 
       398 
     | 
    
         
            -
                            if (axis && axis.used)
         
     | 
| 
       399 
     | 
    
         
            -
                                res.push(axis);
         
     | 
| 
       400 
     | 
    
         
            -
                        }
         
     | 
| 
       401 
     | 
    
         
            -
                        for (i = 0; i < yaxes.length; ++i) {
         
     | 
| 
       402 
     | 
    
         
            -
                            axis = yaxes[i];
         
     | 
| 
       403 
     | 
    
         
            -
                            if (axis && axis.used)
         
     | 
| 
       404 
     | 
    
         
            -
                                res.push(axis);
         
     | 
| 
       405 
     | 
    
         
            -
                        }
         
     | 
| 
       406 
     | 
    
         
            -
                        return res;
         
     | 
| 
       407 
     | 
    
         
            -
                    }
         
     | 
| 
       408 
     | 
    
         
            -
             
     | 
| 
       409 
398 
     | 
    
         
             
                    function getOrCreateAxis(axes, number) {
         
     | 
| 
       410 
399 
     | 
    
         
             
                        if (!axes[number - 1])
         
     | 
| 
       411 
400 
     | 
    
         
             
                            axes[number - 1] = {
         
     | 
| 
         @@ -500,29 +489,23 @@ 
     | 
|
| 
       500 
489 
     | 
    
         
             
                    function processData() {
         
     | 
| 
       501 
490 
     | 
    
         
             
                        var topSentry = Number.POSITIVE_INFINITY,
         
     | 
| 
       502 
491 
     | 
    
         
             
                            bottomSentry = Number.NEGATIVE_INFINITY,
         
     | 
| 
      
 492 
     | 
    
         
            +
                            fakeInfinity = Number.MAX_VALUE,
         
     | 
| 
       503 
493 
     | 
    
         
             
                            i, j, k, m, length,
         
     | 
| 
       504 
494 
     | 
    
         
             
                            s, points, ps, x, y, axis, val, f, p;
         
     | 
| 
       505 
495 
     | 
    
         | 
| 
       506 
     | 
    
         
            -
                        function initAxis(axis, number) {
         
     | 
| 
       507 
     | 
    
         
            -
                            if (!axis)
         
     | 
| 
       508 
     | 
    
         
            -
                                return;
         
     | 
| 
       509 
     | 
    
         
            -
                            
         
     | 
| 
       510 
     | 
    
         
            -
                            axis.datamin = topSentry;
         
     | 
| 
       511 
     | 
    
         
            -
                            axis.datamax = bottomSentry;
         
     | 
| 
       512 
     | 
    
         
            -
                            axis.used = false;
         
     | 
| 
       513 
     | 
    
         
            -
                        }
         
     | 
| 
       514 
     | 
    
         
            -
             
     | 
| 
       515 
496 
     | 
    
         
             
                        function updateAxis(axis, min, max) {
         
     | 
| 
       516 
     | 
    
         
            -
                            if (min < axis.datamin)
         
     | 
| 
      
 497 
     | 
    
         
            +
                            if (min < axis.datamin && min != -fakeInfinity)
         
     | 
| 
       517 
498 
     | 
    
         
             
                                axis.datamin = min;
         
     | 
| 
       518 
     | 
    
         
            -
                            if (max > axis.datamax)
         
     | 
| 
      
 499 
     | 
    
         
            +
                            if (max > axis.datamax && max != fakeInfinity)
         
     | 
| 
       519 
500 
     | 
    
         
             
                                axis.datamax = max;
         
     | 
| 
       520 
501 
     | 
    
         
             
                        }
         
     | 
| 
       521 
502 
     | 
    
         | 
| 
       522 
     | 
    
         
            -
                         
     | 
| 
       523 
     | 
    
         
            -
                             
     | 
| 
       524 
     | 
    
         
            -
             
     | 
| 
       525 
     | 
    
         
            -
                             
     | 
| 
      
 503 
     | 
    
         
            +
                        $.each(allAxes(), function (_, axis) {
         
     | 
| 
      
 504 
     | 
    
         
            +
                            // init axis
         
     | 
| 
      
 505 
     | 
    
         
            +
                            axis.datamin = topSentry;
         
     | 
| 
      
 506 
     | 
    
         
            +
                            axis.datamax = bottomSentry;
         
     | 
| 
      
 507 
     | 
    
         
            +
                            axis.used = false;
         
     | 
| 
      
 508 
     | 
    
         
            +
                        });
         
     | 
| 
       526 
509 
     | 
    
         | 
| 
       527 
510 
     | 
    
         
             
                        for (i = 0; i < series.length; ++i) {
         
     | 
| 
       528 
511 
     | 
    
         
             
                            s = series[i];
         
     | 
| 
         @@ -579,6 +562,10 @@ 
     | 
|
| 
       579 
562 
     | 
    
         
             
                                                val = +val; // convert to number
         
     | 
| 
       580 
563 
     | 
    
         
             
                                                if (isNaN(val))
         
     | 
| 
       581 
564 
     | 
    
         
             
                                                    val = null;
         
     | 
| 
      
 565 
     | 
    
         
            +
                                                else if (val == Infinity)
         
     | 
| 
      
 566 
     | 
    
         
            +
                                                    val = fakeInfinity;
         
     | 
| 
      
 567 
     | 
    
         
            +
                                                else if (val == -Infinity)
         
     | 
| 
      
 568 
     | 
    
         
            +
                                                    val = -fakeInfinity;
         
     | 
| 
       582 
569 
     | 
    
         
             
                                            }
         
     | 
| 
       583 
570 
     | 
    
         | 
| 
       584 
571 
     | 
    
         
             
                                            if (val == null) {
         
     | 
| 
         @@ -653,7 +640,7 @@ 
     | 
|
| 
       653 
640 
     | 
    
         
             
                                for (m = 0; m < ps; ++m) {
         
     | 
| 
       654 
641 
     | 
    
         
             
                                    val = points[j + m];
         
     | 
| 
       655 
642 
     | 
    
         
             
                                    f = format[m];
         
     | 
| 
       656 
     | 
    
         
            -
                                    if (!f)
         
     | 
| 
      
 643 
     | 
    
         
            +
                                    if (!f || val == fakeInfinity || val == -fakeInfinity)
         
     | 
| 
       657 
644 
     | 
    
         
             
                                        continue;
         
     | 
| 
       658 
645 
     | 
    
         | 
| 
       659 
646 
     | 
    
         
             
                                    if (f.x) {
         
     | 
| 
         @@ -688,7 +675,7 @@ 
     | 
|
| 
       688 
675 
     | 
    
         
             
                            updateAxis(s.yaxis, ymin, ymax);
         
     | 
| 
       689 
676 
     | 
    
         
             
                        }
         
     | 
| 
       690 
677 
     | 
    
         | 
| 
       691 
     | 
    
         
            -
                        $.each( 
     | 
| 
      
 678 
     | 
    
         
            +
                        $.each(allAxes(), function (_, axis) {
         
     | 
| 
       692 
679 
     | 
    
         
             
                            if (axis.datamin == topSentry)
         
     | 
| 
       693 
680 
     | 
    
         
             
                                axis.datamin = null;
         
     | 
| 
       694 
681 
     | 
    
         
             
                            if (axis.datamax == bottomSentry)
         
     | 
| 
         @@ -696,46 +683,115 @@ 
     | 
|
| 
       696 
683 
     | 
    
         
             
                        });
         
     | 
| 
       697 
684 
     | 
    
         
             
                    }
         
     | 
| 
       698 
685 
     | 
    
         | 
| 
       699 
     | 
    
         
            -
                    function  
     | 
| 
       700 
     | 
    
         
            -
                         
     | 
| 
       701 
     | 
    
         
            -
             
     | 
| 
       702 
     | 
    
         
            -
             
     | 
| 
       703 
     | 
    
         
            -
             
     | 
| 
       704 
     | 
    
         
            -
             
     | 
| 
       705 
     | 
    
         
            -
             
     | 
| 
       706 
     | 
    
         
            -
                             
     | 
| 
       707 
     | 
    
         
            -
             
     | 
| 
      
 686 
     | 
    
         
            +
                    function makeCanvas(skipPositioning, cls) {
         
     | 
| 
      
 687 
     | 
    
         
            +
                        var c = document.createElement('canvas');
         
     | 
| 
      
 688 
     | 
    
         
            +
                        c.className = cls;
         
     | 
| 
      
 689 
     | 
    
         
            +
                        c.width = canvasWidth;
         
     | 
| 
      
 690 
     | 
    
         
            +
                        c.height = canvasHeight;
         
     | 
| 
      
 691 
     | 
    
         
            +
                                
         
     | 
| 
      
 692 
     | 
    
         
            +
                        if (!skipPositioning)
         
     | 
| 
      
 693 
     | 
    
         
            +
                            $(c).css({ position: 'absolute', left: 0, top: 0 });
         
     | 
| 
      
 694 
     | 
    
         
            +
                            
         
     | 
| 
      
 695 
     | 
    
         
            +
                        $(c).appendTo(placeholder);
         
     | 
| 
      
 696 
     | 
    
         
            +
                            
         
     | 
| 
      
 697 
     | 
    
         
            +
                        if (!c.getContext) // excanvas hack
         
     | 
| 
      
 698 
     | 
    
         
            +
                            c = window.G_vmlCanvasManager.initElement(c);
         
     | 
| 
      
 699 
     | 
    
         
            +
             
     | 
| 
      
 700 
     | 
    
         
            +
                        // used for resetting in case we get replotted
         
     | 
| 
      
 701 
     | 
    
         
            +
                        c.getContext("2d").save();
         
     | 
| 
       708 
702 
     | 
    
         | 
| 
      
 703 
     | 
    
         
            +
                        return c;
         
     | 
| 
      
 704 
     | 
    
         
            +
                    }
         
     | 
| 
      
 705 
     | 
    
         
            +
             
     | 
| 
      
 706 
     | 
    
         
            +
                    function getCanvasDimensions() {
         
     | 
| 
       709 
707 
     | 
    
         
             
                        canvasWidth = placeholder.width();
         
     | 
| 
       710 
708 
     | 
    
         
             
                        canvasHeight = placeholder.height();
         
     | 
| 
       711 
     | 
    
         
            -
                         
     | 
| 
       712 
     | 
    
         
            -
                        if (placeholder.css("position") == 'static')
         
     | 
| 
       713 
     | 
    
         
            -
                            placeholder.css("position", "relative"); // for positioning labels and overlay
         
     | 
| 
       714 
     | 
    
         
            -
             
     | 
| 
      
 709 
     | 
    
         
            +
                        
         
     | 
| 
       715 
710 
     | 
    
         
             
                        if (canvasWidth <= 0 || canvasHeight <= 0)
         
     | 
| 
       716 
711 
     | 
    
         
             
                            throw "Invalid dimensions for plot, width = " + canvasWidth + ", height = " + canvasHeight;
         
     | 
| 
      
 712 
     | 
    
         
            +
                    }
         
     | 
| 
      
 713 
     | 
    
         
            +
             
     | 
| 
      
 714 
     | 
    
         
            +
                    function resizeCanvas(c) {
         
     | 
| 
      
 715 
     | 
    
         
            +
                        // resizing should reset the state (excanvas seems to be
         
     | 
| 
      
 716 
     | 
    
         
            +
                        // buggy though)
         
     | 
| 
      
 717 
     | 
    
         
            +
                        if (c.width != canvasWidth)
         
     | 
| 
      
 718 
     | 
    
         
            +
                            c.width = canvasWidth;
         
     | 
| 
      
 719 
     | 
    
         
            +
             
     | 
| 
      
 720 
     | 
    
         
            +
                        if (c.height != canvasHeight)
         
     | 
| 
      
 721 
     | 
    
         
            +
                            c.height = canvasHeight;
         
     | 
| 
      
 722 
     | 
    
         
            +
             
     | 
| 
      
 723 
     | 
    
         
            +
                        // so try to get back to the initial state (even if it's
         
     | 
| 
      
 724 
     | 
    
         
            +
                        // gone now, this should be safe according to the spec)
         
     | 
| 
      
 725 
     | 
    
         
            +
                        var cctx = c.getContext("2d");
         
     | 
| 
      
 726 
     | 
    
         
            +
                        cctx.restore();
         
     | 
| 
       717 
727 
     | 
    
         | 
| 
       718 
     | 
    
         
            -
                         
     | 
| 
       719 
     | 
    
         
            -
             
     | 
| 
      
 728 
     | 
    
         
            +
                        // and save again
         
     | 
| 
      
 729 
     | 
    
         
            +
                        cctx.save();
         
     | 
| 
      
 730 
     | 
    
         
            +
                    }
         
     | 
| 
      
 731 
     | 
    
         
            +
                    
         
     | 
| 
      
 732 
     | 
    
         
            +
                    function setupCanvases() {
         
     | 
| 
      
 733 
     | 
    
         
            +
                        var reused,
         
     | 
| 
      
 734 
     | 
    
         
            +
                            existingCanvas = placeholder.children("canvas.base"),
         
     | 
| 
      
 735 
     | 
    
         
            +
                            existingOverlay = placeholder.children("canvas.overlay");
         
     | 
| 
      
 736 
     | 
    
         
            +
             
     | 
| 
      
 737 
     | 
    
         
            +
                        if (existingCanvas.length == 0 || existingOverlay == 0) {
         
     | 
| 
      
 738 
     | 
    
         
            +
                            // init everything
         
     | 
| 
      
 739 
     | 
    
         
            +
                            
         
     | 
| 
      
 740 
     | 
    
         
            +
                            placeholder.html(""); // make sure placeholder is clear
         
     | 
| 
       720 
741 
     | 
    
         | 
| 
       721 
     | 
    
         
            -
             
     | 
| 
       722 
     | 
    
         
            -
             
     | 
| 
       723 
     | 
    
         
            -
             
     | 
| 
      
 742 
     | 
    
         
            +
                            placeholder.css({ padding: 0 }); // padding messes up the positioning
         
     | 
| 
      
 743 
     | 
    
         
            +
                            
         
     | 
| 
      
 744 
     | 
    
         
            +
                            if (placeholder.css("position") == 'static')
         
     | 
| 
      
 745 
     | 
    
         
            +
                                placeholder.css("position", "relative"); // for positioning labels and overlay
         
     | 
| 
      
 746 
     | 
    
         
            +
             
     | 
| 
      
 747 
     | 
    
         
            +
                            getCanvasDimensions();
         
     | 
| 
      
 748 
     | 
    
         
            +
                            
         
     | 
| 
      
 749 
     | 
    
         
            +
                            canvas = makeCanvas(true, "base");
         
     | 
| 
      
 750 
     | 
    
         
            +
                            overlay = makeCanvas(false, "overlay"); // overlay canvas for interactive features
         
     | 
| 
       724 
751 
     | 
    
         | 
| 
       725 
     | 
    
         
            -
             
     | 
| 
       726 
     | 
    
         
            -
                         
     | 
| 
      
 752 
     | 
    
         
            +
                            reused = false;
         
     | 
| 
      
 753 
     | 
    
         
            +
                        }
         
     | 
| 
      
 754 
     | 
    
         
            +
                        else {
         
     | 
| 
      
 755 
     | 
    
         
            +
                            // reuse existing elements
         
     | 
| 
      
 756 
     | 
    
         
            +
             
     | 
| 
      
 757 
     | 
    
         
            +
                            canvas = existingCanvas.get(0);
         
     | 
| 
      
 758 
     | 
    
         
            +
                            overlay = existingOverlay.get(0);
         
     | 
| 
      
 759 
     | 
    
         
            +
             
     | 
| 
      
 760 
     | 
    
         
            +
                            reused = true;
         
     | 
| 
      
 761 
     | 
    
         
            +
                        }
         
     | 
| 
      
 762 
     | 
    
         
            +
             
     | 
| 
      
 763 
     | 
    
         
            +
                        ctx = canvas.getContext("2d");
         
     | 
| 
       727 
764 
     | 
    
         
             
                        octx = overlay.getContext("2d");
         
     | 
| 
       728 
     | 
    
         
            -
                        octx.stroke();
         
     | 
| 
       729 
     | 
    
         
            -
                    }
         
     | 
| 
       730 
765 
     | 
    
         | 
| 
       731 
     | 
    
         
            -
                    function bindEvents() {
         
     | 
| 
       732 
766 
     | 
    
         
             
                        // we include the canvas in the event holder too, because IE 7
         
     | 
| 
       733 
767 
     | 
    
         
             
                        // sometimes has trouble with the stacking order
         
     | 
| 
       734 
768 
     | 
    
         
             
                        eventHolder = $([overlay, canvas]);
         
     | 
| 
       735 
769 
     | 
    
         | 
| 
      
 770 
     | 
    
         
            +
                        if (reused) {
         
     | 
| 
      
 771 
     | 
    
         
            +
                            // run shutdown in the old plot object
         
     | 
| 
      
 772 
     | 
    
         
            +
                            placeholder.data("plot").shutdown();
         
     | 
| 
      
 773 
     | 
    
         
            +
             
     | 
| 
      
 774 
     | 
    
         
            +
                            // reset reused canvases
         
     | 
| 
      
 775 
     | 
    
         
            +
                            plot.resize();
         
     | 
| 
      
 776 
     | 
    
         
            +
                            
         
     | 
| 
      
 777 
     | 
    
         
            +
                            // make sure overlay pixels are cleared (canvas is cleared when we redraw)
         
     | 
| 
      
 778 
     | 
    
         
            +
                            octx.clearRect(0, 0, canvasWidth, canvasHeight);
         
     | 
| 
      
 779 
     | 
    
         
            +
                            
         
     | 
| 
      
 780 
     | 
    
         
            +
                            // then whack any remaining obvious garbage left
         
     | 
| 
      
 781 
     | 
    
         
            +
                            eventHolder.unbind();
         
     | 
| 
      
 782 
     | 
    
         
            +
                            placeholder.children().not([canvas, overlay]).remove();
         
     | 
| 
      
 783 
     | 
    
         
            +
                        }
         
     | 
| 
      
 784 
     | 
    
         
            +
             
     | 
| 
      
 785 
     | 
    
         
            +
                        // save in case we get replotted
         
     | 
| 
      
 786 
     | 
    
         
            +
                        placeholder.data("plot", plot);
         
     | 
| 
      
 787 
     | 
    
         
            +
                    }
         
     | 
| 
      
 788 
     | 
    
         
            +
             
     | 
| 
      
 789 
     | 
    
         
            +
                    function bindEvents() {
         
     | 
| 
       736 
790 
     | 
    
         
             
                        // bind events
         
     | 
| 
       737 
     | 
    
         
            -
                        if (options.grid.hoverable)
         
     | 
| 
      
 791 
     | 
    
         
            +
                        if (options.grid.hoverable) {
         
     | 
| 
       738 
792 
     | 
    
         
             
                            eventHolder.mousemove(onMouseMove);
         
     | 
| 
      
 793 
     | 
    
         
            +
                            eventHolder.mouseleave(onMouseLeave);
         
     | 
| 
      
 794 
     | 
    
         
            +
                        }
         
     | 
| 
       739 
795 
     | 
    
         | 
| 
       740 
796 
     | 
    
         
             
                        if (options.grid.clickable)
         
     | 
| 
       741 
797 
     | 
    
         
             
                            eventHolder.click(onClick);
         
     | 
| 
         @@ -743,6 +799,17 @@ 
     | 
|
| 
       743 
799 
     | 
    
         
             
                        executeHooks(hooks.bindEvents, [eventHolder]);
         
     | 
| 
       744 
800 
     | 
    
         
             
                    }
         
     | 
| 
       745 
801 
     | 
    
         | 
| 
      
 802 
     | 
    
         
            +
                    function shutdown() {
         
     | 
| 
      
 803 
     | 
    
         
            +
                        if (redrawTimeout)
         
     | 
| 
      
 804 
     | 
    
         
            +
                            clearTimeout(redrawTimeout);
         
     | 
| 
      
 805 
     | 
    
         
            +
                        
         
     | 
| 
      
 806 
     | 
    
         
            +
                        eventHolder.unbind("mousemove", onMouseMove);
         
     | 
| 
      
 807 
     | 
    
         
            +
                        eventHolder.unbind("mouseleave", onMouseLeave);
         
     | 
| 
      
 808 
     | 
    
         
            +
                        eventHolder.unbind("click", onClick);
         
     | 
| 
      
 809 
     | 
    
         
            +
                        
         
     | 
| 
      
 810 
     | 
    
         
            +
                        executeHooks(hooks.shutdown, [eventHolder]);
         
     | 
| 
      
 811 
     | 
    
         
            +
                    }
         
     | 
| 
      
 812 
     | 
    
         
            +
             
     | 
| 
       746 
813 
     | 
    
         
             
                    function setTransformationHelpers(axis) {
         
     | 
| 
       747 
814 
     | 
    
         
             
                        // set helper functions on the axis, assumes plot area
         
     | 
| 
       748 
815 
     | 
    
         
             
                        // has been computed already
         
     | 
| 
         @@ -752,42 +819,31 @@ 
     | 
|
| 
       752 
819 
     | 
    
         
             
                        var s, m, t = axis.options.transform || identity,
         
     | 
| 
       753 
820 
     | 
    
         
             
                            it = axis.options.inverseTransform;
         
     | 
| 
       754 
821 
     | 
    
         | 
| 
      
 822 
     | 
    
         
            +
                        // precompute how much the axis is scaling a point
         
     | 
| 
      
 823 
     | 
    
         
            +
                        // in canvas space
         
     | 
| 
       755 
824 
     | 
    
         
             
                        if (axis.direction == "x") {
         
     | 
| 
       756 
     | 
    
         
            -
                             
     | 
| 
       757 
     | 
    
         
            -
                             
     | 
| 
       758 
     | 
    
         
            -
                            s = axis.scale = plotWidth / (t(axis.max) - t(axis.min));
         
     | 
| 
       759 
     | 
    
         
            -
                            m = t(axis.min);
         
     | 
| 
       760 
     | 
    
         
            -
             
     | 
| 
       761 
     | 
    
         
            -
                            // data point to canvas coordinate
         
     | 
| 
       762 
     | 
    
         
            -
                            if (t == identity) // slight optimization
         
     | 
| 
       763 
     | 
    
         
            -
                                axis.p2c = function (p) { return (p - m) * s; };
         
     | 
| 
       764 
     | 
    
         
            -
                            else
         
     | 
| 
       765 
     | 
    
         
            -
                                axis.p2c = function (p) { return (t(p) - m) * s; };
         
     | 
| 
       766 
     | 
    
         
            -
                            // canvas coordinate to data point
         
     | 
| 
       767 
     | 
    
         
            -
                            if (!it)
         
     | 
| 
       768 
     | 
    
         
            -
                                axis.c2p = function (c) { return m + c / s; };
         
     | 
| 
       769 
     | 
    
         
            -
                            else
         
     | 
| 
       770 
     | 
    
         
            -
                                axis.c2p = function (c) { return it(m + c / s); };
         
     | 
| 
      
 825 
     | 
    
         
            +
                            s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min));
         
     | 
| 
      
 826 
     | 
    
         
            +
                            m = Math.min(t(axis.max), t(axis.min));
         
     | 
| 
       771 
827 
     | 
    
         
             
                        }
         
     | 
| 
       772 
828 
     | 
    
         
             
                        else {
         
     | 
| 
       773 
     | 
    
         
            -
                            s = axis.scale = plotHeight / (t(axis.max) - t(axis.min));
         
     | 
| 
       774 
     | 
    
         
            -
                             
     | 
| 
       775 
     | 
    
         
            -
                            
         
     | 
| 
       776 
     | 
    
         
            -
                            if (t == identity)
         
     | 
| 
       777 
     | 
    
         
            -
                                axis.p2c = function (p) { return (m - p) * s; };
         
     | 
| 
       778 
     | 
    
         
            -
                            else
         
     | 
| 
       779 
     | 
    
         
            -
                                axis.p2c = function (p) { return (m - t(p)) * s; };
         
     | 
| 
       780 
     | 
    
         
            -
                            if (!it)
         
     | 
| 
       781 
     | 
    
         
            -
                                axis.c2p = function (c) { return m - c / s; };
         
     | 
| 
       782 
     | 
    
         
            -
                            else
         
     | 
| 
       783 
     | 
    
         
            -
                                axis.c2p = function (c) { return it(m - c / s); };
         
     | 
| 
      
 829 
     | 
    
         
            +
                            s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min));
         
     | 
| 
      
 830 
     | 
    
         
            +
                            s = -s;
         
     | 
| 
      
 831 
     | 
    
         
            +
                            m = Math.max(t(axis.max), t(axis.min));
         
     | 
| 
       784 
832 
     | 
    
         
             
                        }
         
     | 
| 
      
 833 
     | 
    
         
            +
             
     | 
| 
      
 834 
     | 
    
         
            +
                        // data point to canvas coordinate
         
     | 
| 
      
 835 
     | 
    
         
            +
                        if (t == identity) // slight optimization
         
     | 
| 
      
 836 
     | 
    
         
            +
                            axis.p2c = function (p) { return (p - m) * s; };
         
     | 
| 
      
 837 
     | 
    
         
            +
                        else
         
     | 
| 
      
 838 
     | 
    
         
            +
                            axis.p2c = function (p) { return (t(p) - m) * s; };
         
     | 
| 
      
 839 
     | 
    
         
            +
                        // canvas coordinate to data point
         
     | 
| 
      
 840 
     | 
    
         
            +
                        if (!it)
         
     | 
| 
      
 841 
     | 
    
         
            +
                            axis.c2p = function (c) { return m + c / s; };
         
     | 
| 
      
 842 
     | 
    
         
            +
                        else
         
     | 
| 
      
 843 
     | 
    
         
            +
                            axis.c2p = function (c) { return it(m + c / s); };
         
     | 
| 
       785 
844 
     | 
    
         
             
                    }
         
     | 
| 
       786 
845 
     | 
    
         | 
| 
       787 
846 
     | 
    
         
             
                    function measureTickLabels(axis) {
         
     | 
| 
       788 
     | 
    
         
            -
                        if (!axis)
         
     | 
| 
       789 
     | 
    
         
            -
                            return;
         
     | 
| 
       790 
     | 
    
         
            -
                        
         
     | 
| 
       791 
847 
     | 
    
         
             
                        var opts = axis.options, i, ticks = axis.ticks || [], labels = [],
         
     | 
| 
       792 
848 
     | 
    
         
             
                            l, w = opts.labelWidth, h = opts.labelHeight, dummyDiv;
         
     | 
| 
       793 
849 
     | 
    
         | 
| 
         @@ -847,15 +903,12 @@ 
     | 
|
| 
       847 
903 
     | 
    
         
             
                            w = 0;
         
     | 
| 
       848 
904 
     | 
    
         
             
                        if (h == null)
         
     | 
| 
       849 
905 
     | 
    
         
             
                            h = 0;
         
     | 
| 
       850 
     | 
    
         
            -
             
     | 
| 
      
 906 
     | 
    
         
            +
             
     | 
| 
       851 
907 
     | 
    
         
             
                        axis.labelWidth = w;
         
     | 
| 
       852 
908 
     | 
    
         
             
                        axis.labelHeight = h;
         
     | 
| 
       853 
909 
     | 
    
         
             
                    }
         
     | 
| 
       854 
910 
     | 
    
         | 
| 
       855 
     | 
    
         
            -
                    function  
     | 
| 
       856 
     | 
    
         
            -
                        if (!axis || (!axis.used && !(axis.labelWidth || axis.labelHeight)))
         
     | 
| 
       857 
     | 
    
         
            -
                            return;
         
     | 
| 
       858 
     | 
    
         
            -
             
     | 
| 
      
 911 
     | 
    
         
            +
                    function allocateAxisBoxFirstPhase(axis) {
         
     | 
| 
       859 
912 
     | 
    
         
             
                        // find the bounding box of the axis by looking at label
         
     | 
| 
       860 
913 
     | 
    
         
             
                        // widths/heights and ticks, make room by diminishing the
         
     | 
| 
       861 
914 
     | 
    
         
             
                        // plotOffset
         
     | 
| 
         @@ -871,7 +924,7 @@ 
     | 
|
| 
       871 
924 
     | 
    
         | 
| 
       872 
925 
     | 
    
         
             
                        // determine axis margin
         
     | 
| 
       873 
926 
     | 
    
         
             
                        var samePosition = $.grep(all, function (a) {
         
     | 
| 
       874 
     | 
    
         
            -
                            return a && a.options.position == pos &&  
     | 
| 
      
 927 
     | 
    
         
            +
                            return a && a.options.position == pos && a.reserveSpace;
         
     | 
| 
       875 
928 
     | 
    
         
             
                        });
         
     | 
| 
       876 
929 
     | 
    
         
             
                        if ($.inArray(axis, samePosition) == samePosition.length - 1)
         
     | 
| 
       877 
930 
     | 
    
         
             
                            axismargin = 0; // outermost
         
     | 
| 
         @@ -881,7 +934,7 @@ 
     | 
|
| 
       881 
934 
     | 
    
         
             
                            tickLength = "full";
         
     | 
| 
       882 
935 
     | 
    
         | 
| 
       883 
936 
     | 
    
         
             
                        var sameDirection = $.grep(all, function (a) {
         
     | 
| 
       884 
     | 
    
         
            -
                            return a &&  
     | 
| 
      
 937 
     | 
    
         
            +
                            return a && a.reserveSpace;
         
     | 
| 
       885 
938 
     | 
    
         
             
                        });
         
     | 
| 
       886 
939 
     | 
    
         | 
| 
       887 
940 
     | 
    
         
             
                        var innermost = $.inArray(axis, sameDirection) == 0;
         
     | 
| 
         @@ -924,7 +977,7 @@ 
     | 
|
| 
       924 
977 
     | 
    
         
             
                        axis.innermost = innermost;
         
     | 
| 
       925 
978 
     | 
    
         
             
                    }
         
     | 
| 
       926 
979 
     | 
    
         | 
| 
       927 
     | 
    
         
            -
                    function  
     | 
| 
      
 980 
     | 
    
         
            +
                    function allocateAxisBoxSecondPhase(axis) {
         
     | 
| 
       928 
981 
     | 
    
         
             
                        // set remaining bounding box coordinates
         
     | 
| 
       929 
982 
     | 
    
         
             
                        if (axis.direction == "x") {
         
     | 
| 
       930 
983 
     | 
    
         
             
                            axis.box.left = plotOffset.left;
         
     | 
| 
         @@ -937,59 +990,67 @@ 
     | 
|
| 
       937 
990 
     | 
    
         
             
                    }
         
     | 
| 
       938 
991 
     | 
    
         | 
| 
       939 
992 
     | 
    
         
             
                    function setupGrid() {
         
     | 
| 
       940 
     | 
    
         
            -
                        var axes =  
     | 
| 
      
 993 
     | 
    
         
            +
                        var i, axes = allAxes();
         
     | 
| 
       941 
994 
     | 
    
         | 
| 
       942 
     | 
    
         
            -
                        //  
     | 
| 
       943 
     | 
    
         
            -
             
     | 
| 
       944 
     | 
    
         
            -
             
     | 
| 
      
 995 
     | 
    
         
            +
                        // first calculate the plot and axis box dimensions
         
     | 
| 
      
 996 
     | 
    
         
            +
             
     | 
| 
      
 997 
     | 
    
         
            +
                        $.each(axes, function (_, axis) {
         
     | 
| 
      
 998 
     | 
    
         
            +
                            axis.show = axis.options.show;
         
     | 
| 
      
 999 
     | 
    
         
            +
                            if (axis.show == null)
         
     | 
| 
      
 1000 
     | 
    
         
            +
                                axis.show = axis.used; // by default an axis is visible if it's got data
         
     | 
| 
      
 1001 
     | 
    
         
            +
                            
         
     | 
| 
      
 1002 
     | 
    
         
            +
                            axis.reserveSpace = axis.show || axis.options.reserveSpace;
         
     | 
| 
      
 1003 
     | 
    
         
            +
             
     | 
| 
      
 1004 
     | 
    
         
            +
                            setRange(axis);
         
     | 
| 
      
 1005 
     | 
    
         
            +
                        });
         
     | 
| 
      
 1006 
     | 
    
         
            +
             
     | 
| 
      
 1007 
     | 
    
         
            +
                        allocatedAxes = $.grep(axes, function (axis) { return axis.reserveSpace; });
         
     | 
| 
       945 
1008 
     | 
    
         | 
| 
       946 
     | 
    
         
            -
                        
         
     | 
| 
       947 
1009 
     | 
    
         
             
                        plotOffset.left = plotOffset.right = plotOffset.top = plotOffset.bottom = 0;
         
     | 
| 
       948 
1010 
     | 
    
         
             
                        if (options.grid.show) {
         
     | 
| 
       949 
     | 
    
         
            -
                             
     | 
| 
       950 
     | 
    
         
            -
             
     | 
| 
       951 
     | 
    
         
            -
                                setupTickGeneration( 
     | 
| 
       952 
     | 
    
         
            -
                                setTicks( 
     | 
| 
       953 
     | 
    
         
            -
                                snapRangeToTicks( 
     | 
| 
       954 
     | 
    
         
            -
                            }
         
     | 
| 
      
 1011 
     | 
    
         
            +
                            $.each(allocatedAxes, function (_, axis) {
         
     | 
| 
      
 1012 
     | 
    
         
            +
                                // make the ticks
         
     | 
| 
      
 1013 
     | 
    
         
            +
                                setupTickGeneration(axis);
         
     | 
| 
      
 1014 
     | 
    
         
            +
                                setTicks(axis);
         
     | 
| 
      
 1015 
     | 
    
         
            +
                                snapRangeToTicks(axis, axis.ticks);
         
     | 
| 
       955 
1016 
     | 
    
         | 
| 
       956 
     | 
    
         
            -
             
     | 
| 
       957 
     | 
    
         
            -
             
     | 
| 
       958 
     | 
    
         
            -
                             
     | 
| 
       959 
     | 
    
         
            -
             
     | 
| 
       960 
     | 
    
         
            -
             
     | 
| 
       961 
     | 
    
         
            -
                             
     | 
| 
       962 
     | 
    
         
            -
             
     | 
| 
       963 
     | 
    
         
            -
                                
         
     | 
| 
       964 
     | 
    
         
            -
                            // compute the axis boxes, start from the outside (reverse order)
         
     | 
| 
       965 
     | 
    
         
            -
                            for (j = xaxes.length - 1; j >= 0; --j)
         
     | 
| 
       966 
     | 
    
         
            -
                                computeAxisBox(xaxes[j]);
         
     | 
| 
       967 
     | 
    
         
            -
                            for (j = yaxes.length - 1; j >= 0; --j)
         
     | 
| 
       968 
     | 
    
         
            -
                                computeAxisBox(yaxes[j]);
         
     | 
| 
      
 1017 
     | 
    
         
            +
                                // find labelWidth/Height for axis
         
     | 
| 
      
 1018 
     | 
    
         
            +
                                measureTickLabels(axis);
         
     | 
| 
      
 1019 
     | 
    
         
            +
                            });
         
     | 
| 
      
 1020 
     | 
    
         
            +
             
     | 
| 
      
 1021 
     | 
    
         
            +
                            // with all dimensions in house, we can compute the
         
     | 
| 
      
 1022 
     | 
    
         
            +
                            // axis boxes, start from the outside (reverse order)
         
     | 
| 
      
 1023 
     | 
    
         
            +
                            for (i = allocatedAxes.length - 1; i >= 0; --i)
         
     | 
| 
      
 1024 
     | 
    
         
            +
                                allocateAxisBoxFirstPhase(allocatedAxes[i]);
         
     | 
| 
       969 
1025 
     | 
    
         | 
| 
       970 
1026 
     | 
    
         
             
                            // make sure we've got enough space for things that
         
     | 
| 
       971 
1027 
     | 
    
         
             
                            // might stick out
         
     | 
| 
       972 
     | 
    
         
            -
                            var  
     | 
| 
       973 
     | 
    
         
            -
                             
     | 
| 
       974 
     | 
    
         
            -
                                 
     | 
| 
       975 
     | 
    
         
            -
             
     | 
| 
      
 1028 
     | 
    
         
            +
                            var minMargin = options.grid.minBorderMargin;
         
     | 
| 
      
 1029 
     | 
    
         
            +
                            if (minMargin == null) {
         
     | 
| 
      
 1030 
     | 
    
         
            +
                                minMargin = 0;
         
     | 
| 
      
 1031 
     | 
    
         
            +
                                for (i = 0; i < series.length; ++i)
         
     | 
| 
      
 1032 
     | 
    
         
            +
                                    minMargin = Math.max(minMargin, series[i].points.radius + series[i].points.lineWidth/2);
         
     | 
| 
      
 1033 
     | 
    
         
            +
                            }
         
     | 
| 
      
 1034 
     | 
    
         
            +
                                
         
     | 
| 
       976 
1035 
     | 
    
         
             
                            for (var a in plotOffset) {
         
     | 
| 
       977 
1036 
     | 
    
         
             
                                plotOffset[a] += options.grid.borderWidth;
         
     | 
| 
       978 
     | 
    
         
            -
                                plotOffset[a] = Math.max( 
     | 
| 
      
 1037 
     | 
    
         
            +
                                plotOffset[a] = Math.max(minMargin, plotOffset[a]);
         
     | 
| 
       979 
1038 
     | 
    
         
             
                            }
         
     | 
| 
       980 
1039 
     | 
    
         
             
                        }
         
     | 
| 
       981 
1040 
     | 
    
         | 
| 
       982 
1041 
     | 
    
         
             
                        plotWidth = canvasWidth - plotOffset.left - plotOffset.right;
         
     | 
| 
       983 
1042 
     | 
    
         
             
                        plotHeight = canvasHeight - plotOffset.bottom - plotOffset.top;
         
     | 
| 
       984 
     | 
    
         
            -
             
     | 
| 
      
 1043 
     | 
    
         
            +
             
     | 
| 
       985 
1044 
     | 
    
         
             
                        // now we got the proper plotWidth/Height, we can compute the scaling
         
     | 
| 
       986 
     | 
    
         
            -
                         
     | 
| 
       987 
     | 
    
         
            -
                            setTransformationHelpers( 
     | 
| 
      
 1045 
     | 
    
         
            +
                        $.each(axes, function (_, axis) {
         
     | 
| 
      
 1046 
     | 
    
         
            +
                            setTransformationHelpers(axis);
         
     | 
| 
      
 1047 
     | 
    
         
            +
                        });
         
     | 
| 
       988 
1048 
     | 
    
         | 
| 
       989 
1049 
     | 
    
         
             
                        if (options.grid.show) {
         
     | 
| 
       990 
     | 
    
         
            -
                             
     | 
| 
       991 
     | 
    
         
            -
                                 
     | 
| 
       992 
     | 
    
         
            -
                            
         
     | 
| 
      
 1050 
     | 
    
         
            +
                            $.each(allocatedAxes, function (_, axis) {
         
     | 
| 
      
 1051 
     | 
    
         
            +
                                allocateAxisBoxSecondPhase(axis);
         
     | 
| 
      
 1052 
     | 
    
         
            +
                            });
         
     | 
| 
      
 1053 
     | 
    
         
            +
             
     | 
| 
       993 
1054 
     | 
    
         
             
                            insertAxisLabels();
         
     | 
| 
       994 
1055 
     | 
    
         
             
                        }
         
     | 
| 
       995 
1056 
     | 
    
         | 
| 
         @@ -1008,7 +1069,7 @@ 
     | 
|
| 
       1008 
1069 
     | 
    
         | 
| 
       1009 
1070 
     | 
    
         
             
                            if (opts.min == null)
         
     | 
| 
       1010 
1071 
     | 
    
         
             
                                min -= widen;
         
     | 
| 
       1011 
     | 
    
         
            -
                            //  
     | 
| 
      
 1072 
     | 
    
         
            +
                            // always widen max if we couldn't widen min to ensure we
         
     | 
| 
       1012 
1073 
     | 
    
         
             
                            // don't fall into min == max which doesn't work
         
     | 
| 
       1013 
1074 
     | 
    
         
             
                            if (opts.max == null || opts.min != null)
         
     | 
| 
       1014 
1075 
     | 
    
         
             
                                max += widen;
         
     | 
| 
         @@ -1042,12 +1103,10 @@ 
     | 
|
| 
       1042 
1103 
     | 
    
         
             
                        var noTicks;
         
     | 
| 
       1043 
1104 
     | 
    
         
             
                        if (typeof opts.ticks == "number" && opts.ticks > 0)
         
     | 
| 
       1044 
1105 
     | 
    
         
             
                            noTicks = opts.ticks;
         
     | 
| 
       1045 
     | 
    
         
            -
                        else if (axis.direction == "x")
         
     | 
| 
       1046 
     | 
    
         
            -
                             // heuristic based on the model a*sqrt(x) fitted to
         
     | 
| 
       1047 
     | 
    
         
            -
                             // some reasonable data points
         
     | 
| 
       1048 
     | 
    
         
            -
                            noTicks = 0.3 * Math.sqrt(canvasWidth);
         
     | 
| 
       1049 
1106 
     | 
    
         
             
                        else
         
     | 
| 
       1050 
     | 
    
         
            -
                             
     | 
| 
      
 1107 
     | 
    
         
            +
                            // heuristic based on the model a*sqrt(x) fitted to
         
     | 
| 
      
 1108 
     | 
    
         
            +
                            // some data points that seemed reasonable
         
     | 
| 
      
 1109 
     | 
    
         
            +
                            noTicks = 0.3 * Math.sqrt(axis.direction == "x" ? canvasWidth : canvasHeight);
         
     | 
| 
       1051 
1110 
     | 
    
         | 
| 
       1052 
1111 
     | 
    
         
             
                        var delta = (axis.max - axis.min) / noTicks,
         
     | 
| 
       1053 
1112 
     | 
    
         
             
                            size, generator, unit, formatter, i, magn, norm;
         
     | 
| 
         @@ -1310,9 +1369,7 @@ 
     | 
|
| 
       1310 
1369 
     | 
    
         
             
                    }
         
     | 
| 
       1311 
1370 
     | 
    
         | 
| 
       1312 
1371 
     | 
    
         
             
                    function setTicks(axis) {
         
     | 
| 
       1313 
     | 
    
         
            -
                        axis.ticks = [];
         
     | 
| 
       1314 
     | 
    
         
            -
             
     | 
| 
       1315 
     | 
    
         
            -
                        var oticks = axis.options.ticks, ticks = null;
         
     | 
| 
      
 1372 
     | 
    
         
            +
                        var oticks = axis.options.ticks, ticks = [];
         
     | 
| 
       1316 
1373 
     | 
    
         
             
                        if (oticks == null || (typeof oticks == "number" && oticks > 0))
         
     | 
| 
       1317 
1374 
     | 
    
         
             
                            ticks = axis.tickGenerator(axis);
         
     | 
| 
       1318 
1375 
     | 
    
         
             
                        else if (oticks) {
         
     | 
| 
         @@ -1325,24 +1382,26 @@ 
     | 
|
| 
       1325 
1382 
     | 
    
         | 
| 
       1326 
1383 
     | 
    
         
             
                        // clean up/labelify the supplied ticks, copy them over
         
     | 
| 
       1327 
1384 
     | 
    
         
             
                        var i, v;
         
     | 
| 
      
 1385 
     | 
    
         
            +
                        axis.ticks = [];
         
     | 
| 
       1328 
1386 
     | 
    
         
             
                        for (i = 0; i < ticks.length; ++i) {
         
     | 
| 
       1329 
1387 
     | 
    
         
             
                            var label = null;
         
     | 
| 
       1330 
1388 
     | 
    
         
             
                            var t = ticks[i];
         
     | 
| 
       1331 
1389 
     | 
    
         
             
                            if (typeof t == "object") {
         
     | 
| 
       1332 
     | 
    
         
            -
                                v = t[0];
         
     | 
| 
      
 1390 
     | 
    
         
            +
                                v = +t[0];
         
     | 
| 
       1333 
1391 
     | 
    
         
             
                                if (t.length > 1)
         
     | 
| 
       1334 
1392 
     | 
    
         
             
                                    label = t[1];
         
     | 
| 
       1335 
1393 
     | 
    
         
             
                            }
         
     | 
| 
       1336 
1394 
     | 
    
         
             
                            else
         
     | 
| 
       1337 
     | 
    
         
            -
                                v = t;
         
     | 
| 
      
 1395 
     | 
    
         
            +
                                v = +t;
         
     | 
| 
       1338 
1396 
     | 
    
         
             
                            if (label == null)
         
     | 
| 
       1339 
1397 
     | 
    
         
             
                                label = axis.tickFormatter(v, axis);
         
     | 
| 
       1340 
     | 
    
         
            -
                             
     | 
| 
      
 1398 
     | 
    
         
            +
                            if (!isNaN(v))
         
     | 
| 
      
 1399 
     | 
    
         
            +
                                axis.ticks.push({ v: v, label: label });
         
     | 
| 
       1341 
1400 
     | 
    
         
             
                        }
         
     | 
| 
       1342 
1401 
     | 
    
         
             
                    }
         
     | 
| 
       1343 
1402 
     | 
    
         | 
| 
       1344 
1403 
     | 
    
         
             
                    function snapRangeToTicks(axis, ticks) {
         
     | 
| 
       1345 
     | 
    
         
            -
                        if (axis.options.autoscaleMargin  
     | 
| 
      
 1404 
     | 
    
         
            +
                        if (axis.options.autoscaleMargin && ticks.length > 0) {
         
     | 
| 
       1346 
1405 
     | 
    
         
             
                            // snap to ticks
         
     | 
| 
       1347 
1406 
     | 
    
         
             
                            if (axis.options.min == null)
         
     | 
| 
       1348 
1407 
     | 
    
         
             
                                axis.min = Math.min(axis.min, ticks[0].v);
         
     | 
| 
         @@ -1355,6 +1414,10 @@ 
     | 
|
| 
       1355 
1414 
     | 
    
         
             
                        ctx.clearRect(0, 0, canvasWidth, canvasHeight);
         
     | 
| 
       1356 
1415 
     | 
    
         | 
| 
       1357 
1416 
     | 
    
         
             
                        var grid = options.grid;
         
     | 
| 
      
 1417 
     | 
    
         
            +
             
     | 
| 
      
 1418 
     | 
    
         
            +
                        // draw background, if any
         
     | 
| 
      
 1419 
     | 
    
         
            +
                        if (grid.show && grid.backgroundColor)
         
     | 
| 
      
 1420 
     | 
    
         
            +
                            drawBackground();
         
     | 
| 
       1358 
1421 
     | 
    
         | 
| 
       1359 
1422 
     | 
    
         
             
                        if (grid.show && !grid.aboveData)
         
     | 
| 
       1360 
1423 
     | 
    
         
             
                            drawGrid();
         
     | 
| 
         @@ -1371,9 +1434,8 @@ 
     | 
|
| 
       1371 
1434 
     | 
    
         
             
                    }
         
     | 
| 
       1372 
1435 
     | 
    
         | 
| 
       1373 
1436 
     | 
    
         
             
                    function extractRange(ranges, coord) {
         
     | 
| 
       1374 
     | 
    
         
            -
                        var axis, from, to,  
     | 
| 
      
 1437 
     | 
    
         
            +
                        var axis, from, to, key, axes = allAxes();
         
     | 
| 
       1375 
1438 
     | 
    
         | 
| 
       1376 
     | 
    
         
            -
                        axes = getUsedAxes();
         
     | 
| 
       1377 
1439 
     | 
    
         
             
                        for (i = 0; i < axes.length; ++i) {
         
     | 
| 
       1378 
1440 
     | 
    
         
             
                            axis = axes[i];
         
     | 
| 
       1379 
1441 
     | 
    
         
             
                            if (axis.direction == coord) {
         
     | 
| 
         @@ -1405,18 +1467,21 @@ 
     | 
|
| 
       1405 
1467 
     | 
    
         
             
                        return { from: from, to: to, axis: axis };
         
     | 
| 
       1406 
1468 
     | 
    
         
             
                    }
         
     | 
| 
       1407 
1469 
     | 
    
         | 
| 
      
 1470 
     | 
    
         
            +
                    function drawBackground() {
         
     | 
| 
      
 1471 
     | 
    
         
            +
                        ctx.save();
         
     | 
| 
      
 1472 
     | 
    
         
            +
                        ctx.translate(plotOffset.left, plotOffset.top);
         
     | 
| 
      
 1473 
     | 
    
         
            +
             
     | 
| 
      
 1474 
     | 
    
         
            +
                        ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)");
         
     | 
| 
      
 1475 
     | 
    
         
            +
                        ctx.fillRect(0, 0, plotWidth, plotHeight);
         
     | 
| 
      
 1476 
     | 
    
         
            +
                        ctx.restore();
         
     | 
| 
      
 1477 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1478 
     | 
    
         
            +
             
     | 
| 
       1408 
1479 
     | 
    
         
             
                    function drawGrid() {
         
     | 
| 
       1409 
1480 
     | 
    
         
             
                        var i;
         
     | 
| 
       1410 
1481 
     | 
    
         | 
| 
       1411 
1482 
     | 
    
         
             
                        ctx.save();
         
     | 
| 
       1412 
1483 
     | 
    
         
             
                        ctx.translate(plotOffset.left, plotOffset.top);
         
     | 
| 
       1413 
1484 
     | 
    
         | 
| 
       1414 
     | 
    
         
            -
                        // draw background, if any
         
     | 
| 
       1415 
     | 
    
         
            -
                        if (options.grid.backgroundColor) {
         
     | 
| 
       1416 
     | 
    
         
            -
                            ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)");
         
     | 
| 
       1417 
     | 
    
         
            -
                            ctx.fillRect(0, 0, plotWidth, plotHeight);
         
     | 
| 
       1418 
     | 
    
         
            -
                        }
         
     | 
| 
       1419 
     | 
    
         
            -
             
     | 
| 
       1420 
1485 
     | 
    
         
             
                        // draw markings
         
     | 
| 
       1421 
1486 
     | 
    
         
             
                        var markings = options.grid.markings;
         
     | 
| 
       1422 
1487 
     | 
    
         
             
                        if (markings) {
         
     | 
| 
         @@ -1486,15 +1551,17 @@ 
     | 
|
| 
       1486 
1551 
     | 
    
         
             
                        }
         
     | 
| 
       1487 
1552 
     | 
    
         | 
| 
       1488 
1553 
     | 
    
         
             
                        // draw the ticks
         
     | 
| 
       1489 
     | 
    
         
            -
                        var axes =  
     | 
| 
      
 1554 
     | 
    
         
            +
                        var axes = allAxes(), bw = options.grid.borderWidth;
         
     | 
| 
       1490 
1555 
     | 
    
         | 
| 
       1491 
1556 
     | 
    
         
             
                        for (var j = 0; j < axes.length; ++j) {
         
     | 
| 
       1492 
1557 
     | 
    
         
             
                            var axis = axes[j], box = axis.box,
         
     | 
| 
       1493 
1558 
     | 
    
         
             
                                t = axis.tickLength, x, y, xoff, yoff;
         
     | 
| 
       1494 
     | 
    
         
            -
             
     | 
| 
      
 1559 
     | 
    
         
            +
                            if (!axis.show || axis.ticks.length == 0)
         
     | 
| 
      
 1560 
     | 
    
         
            +
                                continue
         
     | 
| 
      
 1561 
     | 
    
         
            +
                            
         
     | 
| 
       1495 
1562 
     | 
    
         
             
                            ctx.strokeStyle = axis.options.tickColor || $.color.parse(axis.options.color).scale('a', 0.22).toString();
         
     | 
| 
       1496 
1563 
     | 
    
         
             
                            ctx.lineWidth = 1;
         
     | 
| 
       1497 
     | 
    
         
            -
             
     | 
| 
      
 1564 
     | 
    
         
            +
             
     | 
| 
       1498 
1565 
     | 
    
         
             
                            // find the edges
         
     | 
| 
       1499 
1566 
     | 
    
         
             
                            if (axis.direction == "x") {
         
     | 
| 
       1500 
1567 
     | 
    
         
             
                                x = 0;
         
     | 
| 
         @@ -1588,9 +1655,11 @@ 
     | 
|
| 
       1588 
1655 
     | 
    
         | 
| 
       1589 
1656 
     | 
    
         
             
                        var html = ['<div class="tickLabels" style="font-size:smaller">'];
         
     | 
| 
       1590 
1657 
     | 
    
         | 
| 
       1591 
     | 
    
         
            -
                        var axes =  
     | 
| 
      
 1658 
     | 
    
         
            +
                        var axes = allAxes();
         
     | 
| 
       1592 
1659 
     | 
    
         
             
                        for (var j = 0; j < axes.length; ++j) {
         
     | 
| 
       1593 
1660 
     | 
    
         
             
                            var axis = axes[j], box = axis.box;
         
     | 
| 
      
 1661 
     | 
    
         
            +
                            if (!axis.show)
         
     | 
| 
      
 1662 
     | 
    
         
            +
                                continue;
         
     | 
| 
       1594 
1663 
     | 
    
         
             
                            //debug: html.push('<div style="position:absolute;opacity:0.10;background-color:red;left:' + box.left + 'px;top:' + box.top + 'px;width:' + box.width +  'px;height:' + box.height + 'px"></div>')
         
     | 
| 
       1595 
1664 
     | 
    
         
             
                            html.push('<div class="' + axis.direction + 'Axis ' + axis.direction + axis.n + 'Axis" style="color:' + axis.options.color + '">');
         
     | 
| 
       1596 
1665 
     | 
    
         
             
                            for (var i = 0; i < axis.ticks.length; ++i) {
         
     | 
| 
         @@ -2198,6 +2267,13 @@ 
     | 
|
| 
       2198 
2267 
     | 
    
         
             
                                maxx = maxDistance / axisx.scale,
         
     | 
| 
       2199 
2268 
     | 
    
         
             
                                maxy = maxDistance / axisy.scale;
         
     | 
| 
       2200 
2269 
     | 
    
         | 
| 
      
 2270 
     | 
    
         
            +
                            // with inverse transforms, we can't use the maxx/maxy
         
     | 
| 
      
 2271 
     | 
    
         
            +
                            // optimization, sadly
         
     | 
| 
      
 2272 
     | 
    
         
            +
                            if (axisx.options.inverseTransform)
         
     | 
| 
      
 2273 
     | 
    
         
            +
                                maxx = Number.MAX_VALUE;
         
     | 
| 
      
 2274 
     | 
    
         
            +
                            if (axisy.options.inverseTransform)
         
     | 
| 
      
 2275 
     | 
    
         
            +
                                maxy = Number.MAX_VALUE;
         
     | 
| 
      
 2276 
     | 
    
         
            +
                            
         
     | 
| 
       2201 
2277 
     | 
    
         
             
                            if (s.lines.show || s.points.show) {
         
     | 
| 
       2202 
2278 
     | 
    
         
             
                                for (j = 0; j < points.length; j += ps) {
         
     | 
| 
       2203 
2279 
     | 
    
         
             
                                    var x = points[j], y = points[j + 1];
         
     | 
| 
         @@ -2264,7 +2340,13 @@ 
     | 
|
| 
       2264 
2340 
     | 
    
         
             
                            triggerClickHoverEvent("plothover", e,
         
     | 
| 
       2265 
2341 
     | 
    
         
             
                                                   function (s) { return s["hoverable"] != false; });
         
     | 
| 
       2266 
2342 
     | 
    
         
             
                    }
         
     | 
| 
       2267 
     | 
    
         
            -
             
     | 
| 
      
 2343 
     | 
    
         
            +
             
     | 
| 
      
 2344 
     | 
    
         
            +
                    function onMouseLeave(e) {
         
     | 
| 
      
 2345 
     | 
    
         
            +
                        if (options.grid.hoverable)
         
     | 
| 
      
 2346 
     | 
    
         
            +
                            triggerClickHoverEvent("plothover", e,
         
     | 
| 
      
 2347 
     | 
    
         
            +
                                                   function (s) { return false; });
         
     | 
| 
      
 2348 
     | 
    
         
            +
                    }
         
     | 
| 
      
 2349 
     | 
    
         
            +
             
     | 
| 
       2268 
2350 
     | 
    
         
             
                    function onClick(e) {
         
     | 
| 
       2269 
2351 
     | 
    
         
             
                        triggerClickHoverEvent("plotclick", e,
         
     | 
| 
       2270 
2352 
     | 
    
         
             
                                               function (s) { return s["clickable"] != false; });
         
     | 
| 
         @@ -2294,7 +2376,9 @@ 
     | 
|
| 
       2294 
2376 
     | 
    
         
             
                            for (var i = 0; i < highlights.length; ++i) {
         
     | 
| 
       2295 
2377 
     | 
    
         
             
                                var h = highlights[i];
         
     | 
| 
       2296 
2378 
     | 
    
         
             
                                if (h.auto == eventname &&
         
     | 
| 
       2297 
     | 
    
         
            -
                                    !(item && h.series == item.series && 
     | 
| 
      
 2379 
     | 
    
         
            +
                                    !(item && h.series == item.series &&
         
     | 
| 
      
 2380 
     | 
    
         
            +
                                      h.point[0] == item.datapoint[0] &&
         
     | 
| 
      
 2381 
     | 
    
         
            +
                                      h.point[1] == item.datapoint[1]))
         
     | 
| 
       2298 
2382 
     | 
    
         
             
                                    unhighlight(h.series, h.point);
         
     | 
| 
       2299 
2383 
     | 
    
         
             
                            }
         
     | 
| 
       2300 
2384 
     | 
    
         | 
| 
         @@ -2447,6 +2531,8 @@ 
     | 
|
| 
       2447 
2531 
     | 
    
         
             
                    return plot;
         
     | 
| 
       2448 
2532 
     | 
    
         
             
                };
         
     | 
| 
       2449 
2533 
     | 
    
         | 
| 
      
 2534 
     | 
    
         
            +
                $.plot.version = "0.7";
         
     | 
| 
      
 2535 
     | 
    
         
            +
                
         
     | 
| 
       2450 
2536 
     | 
    
         
             
                $.plot.plugins = [];
         
     | 
| 
       2451 
2537 
     | 
    
         | 
| 
       2452 
2538 
     | 
    
         
             
                // returns a string with the date d formatted according to fmt
         
     |