technical_graph 0.0.0
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/.document +5 -0
 - data/.idea/dictionaries/olek.xml +8 -0
 - data/.rvmrc +1 -0
 - data/Gemfile +14 -0
 - data/Gemfile.lock +32 -0
 - data/LICENSE.txt +20 -0
 - data/README.rdoc +19 -0
 - data/Rakefile +55 -0
 - data/VERSION +1 -0
 - data/lib/technical_graph/data_layer.rb +87 -0
 - data/lib/technical_graph/graph_axis.rb +248 -0
 - data/lib/technical_graph/graph_data_processor.rb +175 -0
 - data/lib/technical_graph/graph_image_drawer.rb +190 -0
 - data/lib/technical_graph/refactoring_backup/lib/technical_graph/axis_layer.rb +151 -0
 - data/lib/technical_graph/refactoring_backup/lib/technical_graph/axis_layer_draw_module.rb +145 -0
 - data/lib/technical_graph/refactoring_backup/lib/technical_graph.rb +55 -0
 - data/lib/technical_graph/refactoring_backup/test/test_technical_graph.rb +104 -0
 - data/lib/technical_graph/refactoring_backup/test/test_technical_graph_axis.rb +306 -0
 - data/lib/technical_graph.rb +55 -0
 - data/samples/1.png +0 -0
 - data/test/helper.rb +19 -0
 - data/test/test_technical_graph.rb +104 -0
 - data/test/test_technical_graph_axis.rb +306 -0
 - data/test/test_technical_simple_graph.rb +46 -0
 - metadata +190 -0
 
    
        data/.document
    ADDED
    
    
    
        data/.rvmrc
    ADDED
    
    | 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            rvm use 1.8.7@technical_graph --create
         
     | 
    
        data/Gemfile
    ADDED
    
    | 
         @@ -0,0 +1,14 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            source "http://rubygems.org"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            gem 'rmagick'
         
     | 
| 
      
 4 
     | 
    
         
            +
            gem 'jeweler'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            # Add dependencies to develop your gem here.
         
     | 
| 
      
 7 
     | 
    
         
            +
            # Include everything needed to run rake, tests, features, etc.
         
     | 
| 
      
 8 
     | 
    
         
            +
            group :development do
         
     | 
| 
      
 9 
     | 
    
         
            +
              gem "shoulda"
         
     | 
| 
      
 10 
     | 
    
         
            +
              gem "bundler", "~> 1.0.0"
         
     | 
| 
      
 11 
     | 
    
         
            +
              gem "rspec"
         
     | 
| 
      
 12 
     | 
    
         
            +
              gem "jeweler" #, "~> 1.6.4"
         
     | 
| 
      
 13 
     | 
    
         
            +
              gem "rcov", ">= 0"
         
     | 
| 
      
 14 
     | 
    
         
            +
            end
         
     | 
    
        data/Gemfile.lock
    ADDED
    
    | 
         @@ -0,0 +1,32 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            GEM
         
     | 
| 
      
 2 
     | 
    
         
            +
              remote: http://rubygems.org/
         
     | 
| 
      
 3 
     | 
    
         
            +
              specs:
         
     | 
| 
      
 4 
     | 
    
         
            +
                diff-lcs (1.1.3)
         
     | 
| 
      
 5 
     | 
    
         
            +
                git (1.2.5)
         
     | 
| 
      
 6 
     | 
    
         
            +
                jeweler (1.6.4)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  bundler (~> 1.0)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  git (>= 1.2.5)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  rake
         
     | 
| 
      
 10 
     | 
    
         
            +
                rake (0.9.2)
         
     | 
| 
      
 11 
     | 
    
         
            +
                rcov (0.9.10)
         
     | 
| 
      
 12 
     | 
    
         
            +
                rmagick (2.13.1)
         
     | 
| 
      
 13 
     | 
    
         
            +
                rspec (2.6.0)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  rspec-core (~> 2.6.0)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  rspec-expectations (~> 2.6.0)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  rspec-mocks (~> 2.6.0)
         
     | 
| 
      
 17 
     | 
    
         
            +
                rspec-core (2.6.4)
         
     | 
| 
      
 18 
     | 
    
         
            +
                rspec-expectations (2.6.0)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  diff-lcs (~> 1.1.2)
         
     | 
| 
      
 20 
     | 
    
         
            +
                rspec-mocks (2.6.0)
         
     | 
| 
      
 21 
     | 
    
         
            +
                shoulda (2.11.3)
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            PLATFORMS
         
     | 
| 
      
 24 
     | 
    
         
            +
              ruby
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            DEPENDENCIES
         
     | 
| 
      
 27 
     | 
    
         
            +
              bundler (~> 1.0.0)
         
     | 
| 
      
 28 
     | 
    
         
            +
              jeweler
         
     | 
| 
      
 29 
     | 
    
         
            +
              rcov
         
     | 
| 
      
 30 
     | 
    
         
            +
              rmagick
         
     | 
| 
      
 31 
     | 
    
         
            +
              rspec
         
     | 
| 
      
 32 
     | 
    
         
            +
              shoulda
         
     | 
    
        data/LICENSE.txt
    ADDED
    
    | 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Copyright (c) 2011 Aleksander Kwiatkowski
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Permission is hereby granted, free of charge, to any person obtaining
         
     | 
| 
      
 4 
     | 
    
         
            +
            a copy of this software and associated documentation files (the
         
     | 
| 
      
 5 
     | 
    
         
            +
            "Software"), to deal in the Software without restriction, including
         
     | 
| 
      
 6 
     | 
    
         
            +
            without limitation the rights to use, copy, modify, merge, publish,
         
     | 
| 
      
 7 
     | 
    
         
            +
            distribute, sublicense, and/or sell copies of the Software, and to
         
     | 
| 
      
 8 
     | 
    
         
            +
            permit persons to whom the Software is furnished to do so, subject to
         
     | 
| 
      
 9 
     | 
    
         
            +
            the following conditions:
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            The above copyright notice and this permission notice shall be
         
     | 
| 
      
 12 
     | 
    
         
            +
            included in all copies or substantial portions of the Software.
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         
     | 
| 
      
 15 
     | 
    
         
            +
            EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         
     | 
| 
      
 16 
     | 
    
         
            +
            MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         
     | 
| 
      
 17 
     | 
    
         
            +
            NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         
     | 
| 
      
 18 
     | 
    
         
            +
            LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         
     | 
| 
      
 19 
     | 
    
         
            +
            OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         
     | 
| 
      
 20 
     | 
    
         
            +
            WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
    
        data/README.rdoc
    ADDED
    
    | 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            = technical-graph
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Create neat graphs.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            == Contributing to technical-graph
         
     | 
| 
      
 6 
     | 
    
         
            +
             
         
     | 
| 
      
 7 
     | 
    
         
            +
            * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
         
     | 
| 
      
 8 
     | 
    
         
            +
            * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
         
     | 
| 
      
 9 
     | 
    
         
            +
            * Fork the project
         
     | 
| 
      
 10 
     | 
    
         
            +
            * Start a feature/bugfix branch
         
     | 
| 
      
 11 
     | 
    
         
            +
            * Commit and push until you are happy with your contribution
         
     | 
| 
      
 12 
     | 
    
         
            +
            * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
         
     | 
| 
      
 13 
     | 
    
         
            +
            * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            == Copyright
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            Copyright (c) 2011 Aleksander Kwiatkowski. See LICENSE.txt for
         
     | 
| 
      
 18 
     | 
    
         
            +
            further details.
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
    
        data/Rakefile
    ADDED
    
    | 
         @@ -0,0 +1,55 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'bundler'
         
     | 
| 
      
 5 
     | 
    
         
            +
            begin
         
     | 
| 
      
 6 
     | 
    
         
            +
              Bundler.setup(:default, :development)
         
     | 
| 
      
 7 
     | 
    
         
            +
            rescue Bundler::BundlerError => e
         
     | 
| 
      
 8 
     | 
    
         
            +
              $stderr.puts e.message
         
     | 
| 
      
 9 
     | 
    
         
            +
              $stderr.puts "Run `bundle install` to install missing gems"
         
     | 
| 
      
 10 
     | 
    
         
            +
              exit e.status_code
         
     | 
| 
      
 11 
     | 
    
         
            +
            end
         
     | 
| 
      
 12 
     | 
    
         
            +
            require 'rake'
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            require 'jeweler'
         
     | 
| 
      
 15 
     | 
    
         
            +
            Jeweler::Tasks.new do |gem|
         
     | 
| 
      
 16 
     | 
    
         
            +
              # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
         
     | 
| 
      
 17 
     | 
    
         
            +
              gem.name = "technical_graph"
         
     | 
| 
      
 18 
     | 
    
         
            +
              gem.homepage = "http://github.com/akwiatkowski/technical_graph"
         
     | 
| 
      
 19 
     | 
    
         
            +
              gem.license = "LGPLv3"
         
     | 
| 
      
 20 
     | 
    
         
            +
              gem.summary = %Q{Create simple and neat graphs}
         
     | 
| 
      
 21 
     | 
    
         
            +
              gem.description = %Q{Create simple and neat graphs}
         
     | 
| 
      
 22 
     | 
    
         
            +
              gem.email = "bobikx@poczta.fm"
         
     | 
| 
      
 23 
     | 
    
         
            +
              gem.authors = ["Aleksander Kwiatkowski"]
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              #gem.files =  FileList["[A-Z]*", "{bin,generators,lib,test}/**/*", 'lib/jeweler/templates/.gitignore']
         
     | 
| 
      
 26 
     | 
    
         
            +
              # dependencies defined in Gemfile
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
      
 28 
     | 
    
         
            +
            Jeweler::RubygemsDotOrgTasks.new
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            require 'rake/testtask'
         
     | 
| 
      
 31 
     | 
    
         
            +
            Rake::TestTask.new(:test) do |test|
         
     | 
| 
      
 32 
     | 
    
         
            +
              test.libs << 'lib' << 'test'
         
     | 
| 
      
 33 
     | 
    
         
            +
              test.pattern = 'test/**/test_*.rb'
         
     | 
| 
      
 34 
     | 
    
         
            +
              test.verbose = true
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            require 'rcov/rcovtask'
         
     | 
| 
      
 38 
     | 
    
         
            +
            Rcov::RcovTask.new do |test|
         
     | 
| 
      
 39 
     | 
    
         
            +
              test.libs << 'test'
         
     | 
| 
      
 40 
     | 
    
         
            +
              test.pattern = 'test/**/test_*.rb'
         
     | 
| 
      
 41 
     | 
    
         
            +
              test.verbose = true
         
     | 
| 
      
 42 
     | 
    
         
            +
              test.rcov_opts << '--exclude "gems/*"'
         
     | 
| 
      
 43 
     | 
    
         
            +
            end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            task :default => :test
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            require 'rake/rdoctask'
         
     | 
| 
      
 48 
     | 
    
         
            +
            Rake::RDocTask.new do |rdoc|
         
     | 
| 
      
 49 
     | 
    
         
            +
              version = File.exist?('VERSION') ? File.read('VERSION') : ""
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
              rdoc.rdoc_dir = 'rdoc'
         
     | 
| 
      
 52 
     | 
    
         
            +
              rdoc.title = "technical-graph #{version}"
         
     | 
| 
      
 53 
     | 
    
         
            +
              rdoc.rdoc_files.include('README*')
         
     | 
| 
      
 54 
     | 
    
         
            +
              rdoc.rdoc_files.include('lib/**/*.rb')
         
     | 
| 
      
 55 
     | 
    
         
            +
            end
         
     | 
    
        data/VERSION
    ADDED
    
    | 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            0.0.0
         
     | 
| 
         @@ -0,0 +1,87 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # Stores only data used for one layer
         
     | 
| 
      
 4 
     | 
    
         
            +
            # Instances of this class are used elsewhere
         
     | 
| 
      
 5 
     | 
    
         
            +
            # Stores also drawing parameters for one layer
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            class DataLayer
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              def initialize(d = [], options = { })
         
     | 
| 
      
 10 
     | 
    
         
            +
                @options = options
         
     | 
| 
      
 11 
     | 
    
         
            +
                @data_params = Hash.new
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                # set data and append initial data
         
     | 
| 
      
 14 
     | 
    
         
            +
                clear_data
         
     | 
| 
      
 15 
     | 
    
         
            +
                append_data(d)
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              # Accessor for setting chart data for layer to draw
         
     | 
| 
      
 19 
     | 
    
         
            +
              def append_data(d)
         
     | 
| 
      
 20 
     | 
    
         
            +
                if d.kind_of? Array
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @data += d
         
     | 
| 
      
 22 
     | 
    
         
            +
                  # sort, clean bad records
         
     | 
| 
      
 23 
     | 
    
         
            +
                  process_data
         
     | 
| 
      
 24 
     | 
    
         
            +
                else
         
     | 
| 
      
 25 
     | 
    
         
            +
                  raise 'Data not an Array'
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              # Array of {:x =>, :y =>}
         
     | 
| 
      
 30 
     | 
    
         
            +
              attr_reader :data
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              # Additional parameters
         
     | 
| 
      
 33 
     | 
    
         
            +
              attr_reader :data_params
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              # Color of
         
     | 
| 
      
 36 
     | 
    
         
            +
              def color
         
     | 
| 
      
 37 
     | 
    
         
            +
                return @data_params[:color] || 'blue'
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              def antialias
         
     | 
| 
      
 41 
     | 
    
         
            +
                return @data_params[:antialias] == false
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
              # Clear data
         
     | 
| 
      
 45 
     | 
    
         
            +
              def clear_data
         
     | 
| 
      
 46 
     | 
    
         
            +
                @data = Array.new
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
              # Clean and process data used for drawing current data layer
         
     | 
| 
      
 50 
     | 
    
         
            +
              def process_data
         
     | 
| 
      
 51 
     | 
    
         
            +
                # delete duplicates
         
     | 
| 
      
 52 
     | 
    
         
            +
                @data = @data.inject([]) { |result, d| result << d unless result.select { |r| r[:x] == d[:x] }.size > 0; result }
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                @data.delete_if { |d| d[:x].nil? or d[:y].nil? }
         
     | 
| 
      
 55 
     | 
    
         
            +
                @data.sort! { |d, e| d[:x] <=> e[:x] }
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                @data_params = Hash.new
         
     | 
| 
      
 58 
     | 
    
         
            +
                # default X values, if data is not empty
         
     | 
| 
      
 59 
     | 
    
         
            +
                if @data.size > 0
         
     | 
| 
      
 60 
     | 
    
         
            +
                  @data_params[:x_min] = @data.first[:x] || @options[:default_x_min]
         
     | 
| 
      
 61 
     | 
    
         
            +
                  @data_params[:x_max] = @data.last[:x] || @options[:default_x_max]
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                  # default Y values
         
     | 
| 
      
 64 
     | 
    
         
            +
                  y_sort = @data.sort { |a, b| a[:y] <=> b[:y] }
         
     | 
| 
      
 65 
     | 
    
         
            +
                  @data_params[:y_min] = y_sort.first[:y] || @options[:default_y_min]
         
     | 
| 
      
 66 
     | 
    
         
            +
                  @data_params[:y_max] = y_sort.last[:y] || @options[:@default_y_max]
         
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
              end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
              def x_min
         
     | 
| 
      
 72 
     | 
    
         
            +
                @data_params[:x_min]
         
     | 
| 
      
 73 
     | 
    
         
            +
              end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
              def x_max
         
     | 
| 
      
 76 
     | 
    
         
            +
                @data_params[:x_max]
         
     | 
| 
      
 77 
     | 
    
         
            +
              end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
              def y_min
         
     | 
| 
      
 80 
     | 
    
         
            +
                @data_params[:y_min]
         
     | 
| 
      
 81 
     | 
    
         
            +
              end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
              def y_max
         
     | 
| 
      
 84 
     | 
    
         
            +
                @data_params[:y_max]
         
     | 
| 
      
 85 
     | 
    
         
            +
              end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,248 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # Calculate axis (only) and draw them
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            class GraphAxis
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              attr_reader :technical_graph
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              # Accessor for options Hash
         
     | 
| 
      
 10 
     | 
    
         
            +
              def options
         
     | 
| 
      
 11 
     | 
    
         
            +
                @technical_graph.options
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              # Accessor for DataLayer Array
         
     | 
| 
      
 15 
     | 
    
         
            +
              def layers
         
     | 
| 
      
 16 
     | 
    
         
            +
                @technical_graph.layers
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              # Calculate everything
         
     | 
| 
      
 20 
     | 
    
         
            +
              def data_processor
         
     | 
| 
      
 21 
     | 
    
         
            +
                @technical_graph.data_processor
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              def image_drawer
         
     | 
| 
      
 25 
     | 
    
         
            +
                @technical_graph.image_drawer
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              def initialize(technical_graph)
         
     | 
| 
      
 29 
     | 
    
         
            +
                @technical_graph = technical_graph
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              def x_axis_fixed?
         
     | 
| 
      
 33 
     | 
    
         
            +
                options[:x_axises_fixed_interval] == true
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              # Value axis has fixed count
         
     | 
| 
      
 37 
     | 
    
         
            +
              def y_axis_fixed?
         
     | 
| 
      
 38 
     | 
    
         
            +
                options[:y_axises_fixed_interval] == true
         
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
              # Where to put axis values
         
     | 
| 
      
 42 
     | 
    
         
            +
              def value_axises
         
     | 
| 
      
 43 
     | 
    
         
            +
                return calc_axis(data_processor.y_min, data_processor.y_max, options[:y_axises_interval], options[:y_axises_count], y_axis_fixed?)
         
     | 
| 
      
 44 
     | 
    
         
            +
              end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
              # Where to put axis values
         
     | 
| 
      
 47 
     | 
    
         
            +
              def parameter_axises
         
     | 
| 
      
 48 
     | 
    
         
            +
                return calc_axis(data_processor.x_min, data_processor.x_max, options[:x_axises_interval], options[:x_axises_count], x_axis_fixed?)
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
              # Calculate axis using 2 methods
         
     | 
| 
      
 52 
     | 
    
         
            +
              def calc_axis(from, to, interval, count, fixed_interval)
         
     | 
| 
      
 53 
     | 
    
         
            +
                axises = Array.new
         
     | 
| 
      
 54 
     | 
    
         
            +
                l = to - from
         
     | 
| 
      
 55 
     | 
    
         
            +
                current = from
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                if fixed_interval
         
     | 
| 
      
 58 
     | 
    
         
            +
                  while current < to
         
     | 
| 
      
 59 
     | 
    
         
            +
                    axises << current
         
     | 
| 
      
 60 
     | 
    
         
            +
                    current += interval
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
                  return axises
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                else
         
     | 
| 
      
 65 
     | 
    
         
            +
                  (0...count).each do |i|
         
     | 
| 
      
 66 
     | 
    
         
            +
                    axises << from + (l.to_f * i.to_f) / count.to_f
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
                  return axises
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                end
         
     | 
| 
      
 71 
     | 
    
         
            +
              end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
              # Render axis on image
         
     | 
| 
      
 75 
     | 
    
         
            +
              def render_on_image(image)
         
     | 
| 
      
 76 
     | 
    
         
            +
                @image = image
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                render_values_axis
         
     | 
| 
      
 79 
     | 
    
         
            +
                render_parameters_axis
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                render_values_zero_axis
         
     | 
| 
      
 82 
     | 
    
         
            +
                render_parameters_zero_axis
         
     | 
| 
      
 83 
     | 
    
         
            +
              end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
              def axis_antialias
         
     | 
| 
      
 86 
     | 
    
         
            +
                options[:axis_antialias] == true
         
     | 
| 
      
 87 
     | 
    
         
            +
              end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
              def render_values_axis
         
     | 
| 
      
 91 
     | 
    
         
            +
                plot_axis_y_line = Magick::Draw.new
         
     | 
| 
      
 92 
     | 
    
         
            +
                plot_axis_y_text = Magick::Draw.new
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                plot_axis_y_line.stroke_antialias(axis_antialias)
         
     | 
| 
      
 95 
     | 
    
         
            +
                plot_axis_y_text.text_antialias(image_drawer.font_antialias)
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                plot_axis_y_line.fill_opacity(0)
         
     | 
| 
      
 98 
     | 
    
         
            +
                plot_axis_y_line.stroke(options[:axis_color])
         
     | 
| 
      
 99 
     | 
    
         
            +
                plot_axis_y_line.stroke_opacity(1.0)
         
     | 
| 
      
 100 
     | 
    
         
            +
                plot_axis_y_line.stroke_width(1.0)
         
     | 
| 
      
 101 
     | 
    
         
            +
                plot_axis_y_line.stroke_linecap('square')
         
     | 
| 
      
 102 
     | 
    
         
            +
                plot_axis_y_line.stroke_linejoin('miter')
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                plot_axis_y_text.font_family('helvetica')
         
     | 
| 
      
 105 
     | 
    
         
            +
                plot_axis_y_text.font_style(Magick::NormalStyle)
         
     | 
| 
      
 106 
     | 
    
         
            +
                plot_axis_y_text.text_align(Magick::LeftAlign)
         
     | 
| 
      
 107 
     | 
    
         
            +
                plot_axis_y_text.text_undercolor(options[:background_color])
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                value_axises.each do |y|
         
     | 
| 
      
 110 
     | 
    
         
            +
                  by = image_drawer.calc_bitmap_y(y)
         
     | 
| 
      
 111 
     | 
    
         
            +
                  plot_axis_y_line.line(
         
     | 
| 
      
 112 
     | 
    
         
            +
                    0, by.round,
         
     | 
| 
      
 113 
     | 
    
         
            +
                    @image.columns-1, by.round
         
     | 
| 
      
 114 
     | 
    
         
            +
                  )
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                  plot_axis_y_text.text(
         
     | 
| 
      
 117 
     | 
    
         
            +
                    5,
         
     | 
| 
      
 118 
     | 
    
         
            +
                    by.round + 15,
         
     | 
| 
      
 119 
     | 
    
         
            +
                    "#{y}"
         
     | 
| 
      
 120 
     | 
    
         
            +
                  )
         
     | 
| 
      
 121 
     | 
    
         
            +
                end
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                t = Time.now
         
     | 
| 
      
 124 
     | 
    
         
            +
                plot_axis_y_line.draw(@image)
         
     | 
| 
      
 125 
     | 
    
         
            +
                puts "#{Time.now - t} drawing lines"
         
     | 
| 
      
 126 
     | 
    
         
            +
                plot_axis_y_text.draw(@image)
         
     | 
| 
      
 127 
     | 
    
         
            +
                puts "#{Time.now - t} drawing text"
         
     | 
| 
      
 128 
     | 
    
         
            +
              end
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
              def render_parameters_axis
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                plot_axis_x_line = Magick::Draw.new
         
     | 
| 
      
 133 
     | 
    
         
            +
                plot_axis_x_text = Magick::Draw.new
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
                plot_axis_x_line.stroke_antialias(axis_antialias)
         
     | 
| 
      
 136 
     | 
    
         
            +
                plot_axis_x_text.text_antialias(axis_antialias)
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
                plot_axis_x_line.fill_opacity(0)
         
     | 
| 
      
 139 
     | 
    
         
            +
                plot_axis_x_line.stroke(options[:axis_color])
         
     | 
| 
      
 140 
     | 
    
         
            +
                plot_axis_x_line.stroke_opacity(1.0)
         
     | 
| 
      
 141 
     | 
    
         
            +
                plot_axis_x_line.stroke_width(1.0)
         
     | 
| 
      
 142 
     | 
    
         
            +
                plot_axis_x_line.stroke_linecap('square')
         
     | 
| 
      
 143 
     | 
    
         
            +
                plot_axis_x_line.stroke_linejoin('miter')
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                plot_axis_x_text.font_family('helvetica')
         
     | 
| 
      
 146 
     | 
    
         
            +
                plot_axis_x_text.font_style(Magick::NormalStyle)
         
     | 
| 
      
 147 
     | 
    
         
            +
                plot_axis_x_text.text_align(Magick::LeftAlign)
         
     | 
| 
      
 148 
     | 
    
         
            +
                plot_axis_x_text.text_undercolor(options[:background_color])
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
                parameter_axises.each do |x|
         
     | 
| 
      
 151 
     | 
    
         
            +
                  bx = image_drawer.calc_bitmap_x(x)
         
     | 
| 
      
 152 
     | 
    
         
            +
                  plot_axis_x_line.line(
         
     | 
| 
      
 153 
     | 
    
         
            +
                    bx.round, 0,
         
     | 
| 
      
 154 
     | 
    
         
            +
                    bx.round, @image.rows-1
         
     | 
| 
      
 155 
     | 
    
         
            +
                  )
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
                  plot_axis_x_text.text(
         
     | 
| 
      
 158 
     | 
    
         
            +
                    bx.round + 15,
         
     | 
| 
      
 159 
     | 
    
         
            +
                    @image.rows - 15,
         
     | 
| 
      
 160 
     | 
    
         
            +
                    "#{x}"
         
     | 
| 
      
 161 
     | 
    
         
            +
                  )
         
     | 
| 
      
 162 
     | 
    
         
            +
                end
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
                t = Time.now
         
     | 
| 
      
 165 
     | 
    
         
            +
                plot_axis_x_line.draw(@image)
         
     | 
| 
      
 166 
     | 
    
         
            +
                puts "#{Time.now - t} drawing lines"
         
     | 
| 
      
 167 
     | 
    
         
            +
                plot_axis_x_text.draw(@image)
         
     | 
| 
      
 168 
     | 
    
         
            +
                puts "#{Time.now - t} drawing text"
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
              end
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
              # TODO: make it DRY
         
     | 
| 
      
 173 
     | 
    
         
            +
              def render_values_zero_axis
         
     | 
| 
      
 174 
     | 
    
         
            +
                plot_axis_y_line = Magick::Draw.new
         
     | 
| 
      
 175 
     | 
    
         
            +
                plot_axis_y_text = Magick::Draw.new
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
                plot_axis_y_line.stroke_antialias(axis_antialias)
         
     | 
| 
      
 178 
     | 
    
         
            +
                plot_axis_y_text.text_antialias(image_drawer.font_antialias)
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
      
 180 
     | 
    
         
            +
                plot_axis_y_line.fill_opacity(0)
         
     | 
| 
      
 181 
     | 
    
         
            +
                plot_axis_y_line.stroke(options[:axis_color])
         
     | 
| 
      
 182 
     | 
    
         
            +
                plot_axis_y_line.stroke_opacity(1.0)
         
     | 
| 
      
 183 
     | 
    
         
            +
                plot_axis_y_line.stroke_width(2.0)
         
     | 
| 
      
 184 
     | 
    
         
            +
                plot_axis_y_line.stroke_linecap('square')
         
     | 
| 
      
 185 
     | 
    
         
            +
                plot_axis_y_line.stroke_linejoin('miter')
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
                plot_axis_y_text.font_family('helvetica')
         
     | 
| 
      
 188 
     | 
    
         
            +
                plot_axis_y_text.font_style(Magick::NormalStyle)
         
     | 
| 
      
 189 
     | 
    
         
            +
                plot_axis_y_text.text_align(Magick::LeftAlign)
         
     | 
| 
      
 190 
     | 
    
         
            +
                plot_axis_y_text.text_undercolor(options[:background_color])
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
                y = 0.0
         
     | 
| 
      
 193 
     | 
    
         
            +
                by = image_drawer.calc_bitmap_y(y)
         
     | 
| 
      
 194 
     | 
    
         
            +
                plot_axis_y_line.line(
         
     | 
| 
      
 195 
     | 
    
         
            +
                  0, by.round,
         
     | 
| 
      
 196 
     | 
    
         
            +
                  @image.columns-1, by.round
         
     | 
| 
      
 197 
     | 
    
         
            +
                )
         
     | 
| 
      
 198 
     | 
    
         
            +
             
     | 
| 
      
 199 
     | 
    
         
            +
                plot_axis_y_text.text(
         
     | 
| 
      
 200 
     | 
    
         
            +
                  5,
         
     | 
| 
      
 201 
     | 
    
         
            +
                  by.round + 15,
         
     | 
| 
      
 202 
     | 
    
         
            +
                  "#{y}"
         
     | 
| 
      
 203 
     | 
    
         
            +
                )
         
     | 
| 
      
 204 
     | 
    
         
            +
             
     | 
| 
      
 205 
     | 
    
         
            +
                # TODO: why normal axis does not need it?
         
     | 
| 
      
 206 
     | 
    
         
            +
                plot_axis_y_line.draw(@image)
         
     | 
| 
      
 207 
     | 
    
         
            +
                plot_axis_y_text.draw(@image)
         
     | 
| 
      
 208 
     | 
    
         
            +
              end
         
     | 
| 
      
 209 
     | 
    
         
            +
             
     | 
| 
      
 210 
     | 
    
         
            +
              def render_parameters_zero_axis
         
     | 
| 
      
 211 
     | 
    
         
            +
             
     | 
| 
      
 212 
     | 
    
         
            +
                plot_axis_x_line = Magick::Draw.new
         
     | 
| 
      
 213 
     | 
    
         
            +
                plot_axis_x_text = Magick::Draw.new
         
     | 
| 
      
 214 
     | 
    
         
            +
             
     | 
| 
      
 215 
     | 
    
         
            +
                plot_axis_x_line.stroke_antialias(axis_antialias)
         
     | 
| 
      
 216 
     | 
    
         
            +
                plot_axis_x_text.text_antialias(axis_antialias)
         
     | 
| 
      
 217 
     | 
    
         
            +
             
     | 
| 
      
 218 
     | 
    
         
            +
                plot_axis_x_line.fill_opacity(0)
         
     | 
| 
      
 219 
     | 
    
         
            +
                plot_axis_x_line.stroke(options[:axis_color])
         
     | 
| 
      
 220 
     | 
    
         
            +
                plot_axis_x_line.stroke_opacity(1.0)
         
     | 
| 
      
 221 
     | 
    
         
            +
                plot_axis_x_line.stroke_width(2.0)
         
     | 
| 
      
 222 
     | 
    
         
            +
                plot_axis_x_line.stroke_linecap('square')
         
     | 
| 
      
 223 
     | 
    
         
            +
                plot_axis_x_line.stroke_linejoin('miter')
         
     | 
| 
      
 224 
     | 
    
         
            +
             
     | 
| 
      
 225 
     | 
    
         
            +
                plot_axis_x_text.font_family('helvetica')
         
     | 
| 
      
 226 
     | 
    
         
            +
                plot_axis_x_text.font_style(Magick::NormalStyle)
         
     | 
| 
      
 227 
     | 
    
         
            +
                plot_axis_x_text.text_align(Magick::LeftAlign)
         
     | 
| 
      
 228 
     | 
    
         
            +
                plot_axis_x_text.text_undercolor(options[:background_color])
         
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
      
 230 
     | 
    
         
            +
                x = 0.0
         
     | 
| 
      
 231 
     | 
    
         
            +
                bx = image_drawer.calc_bitmap_x(x)
         
     | 
| 
      
 232 
     | 
    
         
            +
                plot_axis_x_line.line(
         
     | 
| 
      
 233 
     | 
    
         
            +
                  bx.round, 0,
         
     | 
| 
      
 234 
     | 
    
         
            +
                  bx.round, @image.rows-1
         
     | 
| 
      
 235 
     | 
    
         
            +
                )
         
     | 
| 
      
 236 
     | 
    
         
            +
             
     | 
| 
      
 237 
     | 
    
         
            +
                plot_axis_x_text.text(
         
     | 
| 
      
 238 
     | 
    
         
            +
                  bx.round + 15,
         
     | 
| 
      
 239 
     | 
    
         
            +
                  @image.rows - 15,
         
     | 
| 
      
 240 
     | 
    
         
            +
                  "#{x}"
         
     | 
| 
      
 241 
     | 
    
         
            +
                )
         
     | 
| 
      
 242 
     | 
    
         
            +
             
     | 
| 
      
 243 
     | 
    
         
            +
                # TODO: why normal axis does not need it?
         
     | 
| 
      
 244 
     | 
    
         
            +
                plot_axis_x_line.draw(@image)
         
     | 
| 
      
 245 
     | 
    
         
            +
                plot_axis_x_text.draw(@image)
         
     | 
| 
      
 246 
     | 
    
         
            +
              end
         
     | 
| 
      
 247 
     | 
    
         
            +
             
     | 
| 
      
 248 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,175 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'technical_graph/data_layer'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            # Calculate every aspect of graph, but not directly image oriented variables
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            class GraphDataProcessor
         
     | 
| 
      
 8 
     | 
    
         
            +
              attr_reader :technical_graph
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              # Accessor for options Hash
         
     | 
| 
      
 11 
     | 
    
         
            +
              def options
         
     | 
| 
      
 12 
     | 
    
         
            +
                @technical_graph.options
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              # Accessor for DataLayer Array
         
     | 
| 
      
 16 
     | 
    
         
            +
              def layers
         
     | 
| 
      
 17 
     | 
    
         
            +
                @technical_graph.layers
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              def initialize(technical_graph)
         
     | 
| 
      
 21 
     | 
    
         
            +
                @technical_graph = technical_graph
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                options[:x_min] ||= (Time.now - 24 * 3600).to_f
         
     | 
| 
      
 24 
     | 
    
         
            +
                options[:x_max] ||= Time.now.to_f
         
     | 
| 
      
 25 
     | 
    
         
            +
                options[:y_min] ||= 0.0
         
     | 
| 
      
 26 
     | 
    
         
            +
                options[:y_max] ||= 1.0
         
     | 
| 
      
 27 
     | 
    
         
            +
                # :default - coords are default
         
     | 
| 
      
 28 
     | 
    
         
            +
                # :fixed or whatever else - min/max coords are fixed
         
     | 
| 
      
 29 
     | 
    
         
            +
                options[:xy_behaviour] ||= :default
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                # number of axises
         
     | 
| 
      
 32 
     | 
    
         
            +
                options[:y_axises_count] ||= 10
         
     | 
| 
      
 33 
     | 
    
         
            +
                options[:x_axises_count] ||= 10
         
     | 
| 
      
 34 
     | 
    
         
            +
                # interval
         
     | 
| 
      
 35 
     | 
    
         
            +
                options[:y_axises_interval] ||= 1.0
         
     | 
| 
      
 36 
     | 
    
         
            +
                options[:x_axises_interval] ||= 1.0
         
     | 
| 
      
 37 
     | 
    
         
            +
                # when false then axises are generated to meet 'count'
         
     | 
| 
      
 38 
     | 
    
         
            +
                # when true then axises are generated every X from lowest
         
     | 
| 
      
 39 
     | 
    
         
            +
                options[:x_axises_fixed_interval] = true if options[:x_axises_fixed_interval].nil?
         
     | 
| 
      
 40 
     | 
    
         
            +
                options[:y_axises_fixed_interval] = true if options[:y_axises_fixed_interval].nil?
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                # default truncate string used for rendering numbers
         
     | 
| 
      
 43 
     | 
    
         
            +
                options[:truncate_string] ||= "%.2f"
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                @zoom_x = 1.0
         
     | 
| 
      
 46 
     | 
    
         
            +
                @zoom_y = 1.0
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
              # Ranges are fixed
         
     | 
| 
      
 50 
     | 
    
         
            +
              def fixed?
         
     | 
| 
      
 51 
     | 
    
         
            +
                options[:xy_behaviour] == :fixed
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
              # Ranges without zoom
         
     | 
| 
      
 55 
     | 
    
         
            +
              def raw_x_min
         
     | 
| 
      
 56 
     | 
    
         
            +
                options[:x_min]
         
     | 
| 
      
 57 
     | 
    
         
            +
              end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
              def raw_x_max
         
     | 
| 
      
 60 
     | 
    
         
            +
                options[:x_max]
         
     | 
| 
      
 61 
     | 
    
         
            +
              end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
              def raw_y_min
         
     | 
| 
      
 64 
     | 
    
         
            +
                options[:y_min]
         
     | 
| 
      
 65 
     | 
    
         
            +
              end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
              def raw_y_max
         
     | 
| 
      
 68 
     | 
    
         
            +
                options[:y_max]
         
     | 
| 
      
 69 
     | 
    
         
            +
              end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
              # Ranges with zoom
         
     | 
| 
      
 72 
     | 
    
         
            +
              def x_min
         
     | 
| 
      
 73 
     | 
    
         
            +
                calc_x_zoomed([self.raw_x_min]).first
         
     | 
| 
      
 74 
     | 
    
         
            +
              end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
              def x_max
         
     | 
| 
      
 77 
     | 
    
         
            +
                calc_x_zoomed([self.raw_x_max]).first
         
     | 
| 
      
 78 
     | 
    
         
            +
              end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
              def y_min
         
     | 
| 
      
 81 
     | 
    
         
            +
                calc_y_zoomed([self.raw_y_min]).first
         
     | 
| 
      
 82 
     | 
    
         
            +
              end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
              def y_max
         
     | 
| 
      
 85 
     | 
    
         
            +
                calc_y_zoomed([self.raw_y_max]).first
         
     | 
| 
      
 86 
     | 
    
         
            +
              end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
              # Accessors
         
     | 
| 
      
 89 
     | 
    
         
            +
              private
         
     | 
| 
      
 90 
     | 
    
         
            +
              def raw_x_min=(x)
         
     | 
| 
      
 91 
     | 
    
         
            +
                options[:x_min] = x
         
     | 
| 
      
 92 
     | 
    
         
            +
              end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
              def raw_x_max=(x)
         
     | 
| 
      
 95 
     | 
    
         
            +
                options[:x_max] = x
         
     | 
| 
      
 96 
     | 
    
         
            +
              end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
              def raw_y_min=(y)
         
     | 
| 
      
 99 
     | 
    
         
            +
                options[:y_min] = y
         
     | 
| 
      
 100 
     | 
    
         
            +
              end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
              def raw_y_max=(y)
         
     | 
| 
      
 103 
     | 
    
         
            +
                options[:y_max] = y
         
     | 
| 
      
 104 
     | 
    
         
            +
              end
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
              public
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
              # Consider changing ranges if needed
         
     | 
| 
      
 109 
     | 
    
         
            +
              def process_data_layer(data_layer)
         
     | 
| 
      
 110 
     | 
    
         
            +
                # ranges are set, can't change
         
     | 
| 
      
 111 
     | 
    
         
            +
                return if fixed?
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                # updating ranges
         
     | 
| 
      
 114 
     | 
    
         
            +
                self.raw_y_max = data_layer.y_max if not data_layer.y_max.nil? and data_layer.y_max > self.raw_y_max
         
     | 
| 
      
 115 
     | 
    
         
            +
                self.raw_x_max = data_layer.x_max if not data_layer.x_max.nil? and data_layer.x_max > self.raw_x_max
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                self.raw_y_min = data_layer.y_min if not data_layer.y_min.nil? and data_layer.y_min < self.raw_y_min
         
     | 
| 
      
 118 
     | 
    
         
            +
                self.raw_x_min = data_layer.x_min if not data_layer.x_min.nil? and data_layer.x_min < self.raw_x_min
         
     | 
| 
      
 119 
     | 
    
         
            +
              end
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
              # Change overall image zoom
         
     | 
| 
      
 122 
     | 
    
         
            +
              def zoom=(z = 1.0)
         
     | 
| 
      
 123 
     | 
    
         
            +
                self.x_zoom = z
         
     | 
| 
      
 124 
     | 
    
         
            +
                self.y_zoom = z
         
     | 
| 
      
 125 
     | 
    
         
            +
              end
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
              # Change X axis zoom
         
     | 
| 
      
 128 
     | 
    
         
            +
              def x_zoom=(z = 1.0)
         
     | 
| 
      
 129 
     | 
    
         
            +
                @zoom_x = z
         
     | 
| 
      
 130 
     | 
    
         
            +
              end
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
              # Change X axis zoom
         
     | 
| 
      
 133 
     | 
    
         
            +
              def y_zoom=(z = 1.0)
         
     | 
| 
      
 134 
     | 
    
         
            +
                @zoom_y = z
         
     | 
| 
      
 135 
     | 
    
         
            +
              end
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
              attr_reader :zoom_x, :zoom_y
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
              # Calculate zoomed X position for Array of X'es
         
     | 
| 
      
 140 
     | 
    
         
            +
              def calc_x_zoomed(old_xes)
         
     | 
| 
      
 141 
     | 
    
         
            +
                # default zoom
         
     | 
| 
      
 142 
     | 
    
         
            +
                if self.zoom_x == 1.0
         
     | 
| 
      
 143 
     | 
    
         
            +
                  return old_xes
         
     | 
| 
      
 144 
     | 
    
         
            +
                end
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
                a = (raw_x_max.to_f + raw_x_min.to_f) / 2.0
         
     | 
| 
      
 147 
     | 
    
         
            +
                new_xes = Array.new
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
                old_xes.each do |x|
         
     | 
| 
      
 150 
     | 
    
         
            +
                  d = x - a
         
     | 
| 
      
 151 
     | 
    
         
            +
                  new_xes << (a + d * self.zoom_x)
         
     | 
| 
      
 152 
     | 
    
         
            +
                end
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                return new_xes
         
     | 
| 
      
 155 
     | 
    
         
            +
              end
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
              # Calculate zoomed Y position for Array of Y'es
         
     | 
| 
      
 158 
     | 
    
         
            +
              def calc_y_zoomed(old_yes)
         
     | 
| 
      
 159 
     | 
    
         
            +
                # default zoom
         
     | 
| 
      
 160 
     | 
    
         
            +
                if self.zoom_y == 1.0
         
     | 
| 
      
 161 
     | 
    
         
            +
                  return old_yes
         
     | 
| 
      
 162 
     | 
    
         
            +
                end
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
                a = (raw_y_max.to_f + raw_y_min.to_f) / 2.0
         
     | 
| 
      
 165 
     | 
    
         
            +
                new_yes = Array.new
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
                old_yes.each do |y|
         
     | 
| 
      
 168 
     | 
    
         
            +
                  d = y - a
         
     | 
| 
      
 169 
     | 
    
         
            +
                  new_yes << (a + d * self.zoom_y)
         
     | 
| 
      
 170 
     | 
    
         
            +
                end
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
                return new_yes
         
     | 
| 
      
 173 
     | 
    
         
            +
              end
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
      
 175 
     | 
    
         
            +
            end
         
     |