minichart 0.0.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 7a7348b03ecdf74aeaa57f5fba37079542211e40
4
- data.tar.gz: b85da04d30a6fe59f8b38b688e29962b8a69c1a2
2
+ SHA256:
3
+ metadata.gz: 7debe086fa2ba7994f1362fa53ab2d5da5cc61a0010f6f08d6ca125cc447bc27
4
+ data.tar.gz: 77dd9cf342830795872c284befe937cba7caa9c2372bdae2b8a42a44e6d4bb13
5
5
  SHA512:
6
- metadata.gz: d14c1514bc83eb80ab82b05476999824097a378af0729f47ba02e8c998e60495bbf94c79834ccbd35f531a57056ac70c15e9609e36e047724334e3009a9744c8
7
- data.tar.gz: 8141275bea9a34dad840cd7c26d19b0c693b839f4162fddb87a2c7ac77fe81286c7dae653636befb848087097e797c6056acce759de370ab689e5df650737dbd
6
+ metadata.gz: 5a331fa46640d9bfb32759a5aa160680cd684bd7f57f194e212f7b0d0f5c2af61f03f8b526702de0421dbe608fbc70c39df8c219967b8c2de9fe647f04822e42
7
+ data.tar.gz: 2fede85eef059f2ac6980ff9ba6249b1e7b716edb38eacfe514cebace11488e0cb1ca4520ff4d7a3bf58934e746e846130026c9c98f7bc41419c4216a68c8734
data/README.md CHANGED
@@ -1,17 +1,16 @@
1
- Minichart - SVG Chart Generator
2
- ==================================================
3
-
1
+ # Minichart - SVG Chart Generator
4
2
 
5
3
  ---
6
4
 
7
5
  Create SVG mini charts with Ruby
8
6
 
7
+ ![demo](examples/multiple.svg)
8
+
9
9
  ---
10
10
 
11
- Install
12
- --------------------------------------------------
11
+ ## Install
13
12
 
14
- ```
13
+ ```shell
15
14
  $ gem install minichart
16
15
  ```
17
16
 
@@ -21,17 +20,155 @@ Or with bundler:
21
20
  gem 'minichart'
22
21
  ```
23
22
 
24
- Example
25
- --------------------------------------------------
23
+ ## Usage
24
+
25
+ Require and optionally include the library:
26
26
 
27
27
  ```ruby
28
28
  require 'minichart'
29
29
  include Minichart
30
+ ```
31
+
32
+ Initialize a chart with data, and optional options:
33
+
34
+ ```ruby
35
+ data = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9]
36
+ chart = AreaChart.new data, color: 'blue'
37
+ ```
38
+
39
+ Get the full SVG output by calling `#render`:
40
+
41
+ ```ruby
42
+ puts chart.render
43
+ #=> <?xml version="1.0" standalone="no"?>
44
+ # <svg> ... </svg>
45
+ ```
46
+
47
+ Save it to file, by calling `#save`:
48
+
49
+ ```ruby
50
+ chart.save "my-chart.svg"
51
+ ```
52
+
53
+ Get its inner SVG string by calling `#to_s`:
54
+
55
+ ```ruby
56
+ puts chart.to_s
57
+ #=> <polyline fill="blue" stroke="blue" stroke-width="2" points="..."/>
58
+ ```
59
+
60
+
61
+ The objects returned from all the mini chart classes are [Victor::SVG][2] objects, so they support all methods supported by it as well.
62
+
63
+ ## Chart Types
64
+
65
+ ### Line Chart
66
+
67
+ <img src='examples/line_chart.svg' align='right' width=300>
68
+
69
+ ```ruby
70
+ LineChart.new data, height: 50, background: '#eee',
71
+ aspect_ratio: 5, color: 'green'
72
+ ```
73
+
74
+ ### Bar Chart
75
+
76
+ <img src='examples/bar_chart.svg' align='right' width=300>
77
+
78
+ ```ruby
79
+ BarChart.new data, height: 50, background: '#eee',
80
+ aspect_ratio: 5, color: 'green'
81
+ ```
82
+
83
+ ### Area Chart
30
84
 
31
- plot = LineChart.new
32
- plot.aspect_ratio = 2
33
- plot.data = [10, 30, 20, 40, 30]
34
- plot.save 'line'
85
+ <img src='examples/area_chart.svg' align='right' width=300>
86
+
87
+ ```ruby
88
+ AreaChart.new data, height: 50, background: '#eee',
89
+ aspect_ratio: 5, color: 'green'
90
+ ```
91
+
92
+ ### Horizontal Bar Meter
93
+
94
+ <img src='examples/multiple_horizontal_bars.svg' align='right'>
95
+
96
+ ```ruby
97
+ positive = HorizontalBarMeter.new 70,
98
+ height: 20, width: 250, background: '#9f9', color: 'green'
99
+
100
+ negative = HorizontalBarMeter.new -80,
101
+ height: 20, width: 250, background: '#f99', color: 'red'
102
+
103
+ dual = HorizontalBarMeter.new 80,
104
+ height: 20, width: 250, background: '#99f', color: 'blue',
105
+ mode: :dual, zero_line: true
35
106
  ```
36
107
 
37
- See more examples in the examples folder.
108
+ Meter charts support [additional options](#meter-options).
109
+
110
+ ### Vertical Bar Meter
111
+
112
+ <img src='examples/multiple_vertical_bars.svg' align='right'>
113
+
114
+ ```ruby
115
+ positive = VerticalBarMeter.new 70,
116
+ width: 20, height: 250, background: '#9f9', color: 'green'
117
+
118
+ negative = VerticalBarMeter.new -80,
119
+ width: 20, height: 250, background: '#f99', color: 'red'
120
+
121
+ dual = VerticalBarMeter.new 80,
122
+ width: 20, height: 250, background: '#99f', color: 'blue',
123
+ mode: :dual, zero_line: true
124
+ ```
125
+
126
+ Meter charts support [additional options](#meter-options).
127
+
128
+
129
+ ## Options
130
+
131
+ ### Basic Options
132
+
133
+ All chart classes support a second hash argument for options
134
+
135
+ ```ruby
136
+ chart = LineChart.new data, options
137
+ ```
138
+
139
+ | Option | Default | Description |
140
+ | -------------- | ----------------------------- | ------------------------------------------------------------ |
141
+ | `background` | `"white"` | Chart background color |
142
+ | `color` | `"#333"` | Chart color |
143
+ | `aspect_ratio` | `3` | Set automatic width |
144
+ | `height` | `100`<sup>*</sup> | Chart height in pixels |
145
+ | `width` | Calculated by `aspect_ratio`<sup>*</sup> | Chart width in pixels |
146
+ | `stroke` | `2` | Line stroke width.<br />In `BarChart` determines the gap between bars |
147
+ | `style` | *None* | Style hash for the SVG |
148
+
149
+ _* Default dimensions are reversed for horizontal meters - `width` defaults to 100, and `height` is calculated automatically._
150
+
151
+ ### Meter Options
152
+
153
+ Meter charts support these options in additon to the basic options:
154
+
155
+ | Option | Default | Description |
156
+ | -------------------------- | --------- | ------------------------------------------------------------ |
157
+ | `mode` | `:auto` | Display mode.<br />Can be `:positive`, `:negative`, `:auto` or `:dual` |
158
+ | `max` | `100` | The absolute maximum value.<br />This number should be positive even for negative charts |
159
+ | `zero_line` | `false` | If true, mark the zero line |
160
+ | `zero_line_size` | `6` | Size of the zero line |
161
+ | `zero_line_color` | `"black"` | Color of the zero line |
162
+ | `clipping_indicator` | `false` | If true, show when the value exceeds the range |
163
+ | `clipping_indicator_size` | `6` | Size of the clipping indicator |
164
+ | `clipping_indicator_color` | `"yelow"` | Color of the clipping indicator |
165
+
166
+ ## Examples
167
+
168
+ See more examples (code and SVG output) in the [examples folder][1].
169
+
170
+ ---
171
+
172
+
173
+ [1]: https://github.com/DannyBen/minichart/tree/master/examples#examples
174
+ [2]: https://github.com/DannyBen/victor
@@ -1,4 +1,12 @@
1
1
  require 'victor'
2
- require 'minichart/chart'
3
- require 'minichart/line_chart'
4
- require 'minichart/bar_chart'
2
+ require 'minichart/id_generator'
3
+ require 'minichart/base'
4
+ require 'minichart/charts/chart'
5
+ require 'minichart/charts/line_chart'
6
+ require 'minichart/charts/bar_chart'
7
+ require 'minichart/charts/area_chart'
8
+ require 'minichart/meters/meter'
9
+ require 'minichart/meters/vertical_bar_meter'
10
+ require 'minichart/meters/horizontal_bar_meter'
11
+
12
+ require 'byebug' if ENV['BYEBUG']
@@ -0,0 +1,67 @@
1
+ module Minichart
2
+ # Base class for all Minichart classes
3
+ class Base < Victor::SVGBase
4
+ attr_reader :aspect_ratio, :background, :color, :data,
5
+ :height, :stroke, :style, :width, :opts
6
+
7
+ def initialize(data, opts = {})
8
+ @data, @opts = data, opts
9
+
10
+ # super height: height, width: width, style: style, viewBox: viewbox
11
+ super viewBox: viewbox, style: style
12
+ element :rect, x: 0, y: 0, width: width, height: height,
13
+ fill: background, stroke_width: 0
14
+
15
+ clip_path_id = IDGenerator.next
16
+ setup_clip_path clip_path_id
17
+
18
+ element :g, clip_path: "url(##{clip_path_id})" do
19
+ build
20
+ end
21
+ end
22
+
23
+ def setup_clip_path(id)
24
+ element :defs do
25
+ element :clipPath, id: id do
26
+ element :rect, width: width, height: height
27
+ end
28
+ end
29
+ end
30
+
31
+ def background
32
+ opts[:background] ||= 'white'
33
+ end
34
+
35
+ def aspect_ratio
36
+ opts[:aspect_ratio] ||= 3
37
+ end
38
+
39
+ def height
40
+ opts[:height] ||= 100
41
+ end
42
+
43
+ def width
44
+ opts[:width] ||= (aspect_ratio * height).round
45
+ end
46
+
47
+ def stroke
48
+ opts[:stroke] ||= 2
49
+ end
50
+
51
+ def style
52
+ opts[:style] ||= {}
53
+ end
54
+
55
+ def color
56
+ opts[:color] ||= '#333'
57
+ end
58
+
59
+ def viewbox
60
+ "0 0 #{width} #{height}"
61
+ end
62
+
63
+ def build
64
+ raise NotImplementedError, "#build is not implemented"
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,27 @@
1
+ module Minichart
2
+ class AreaChart < Chart
3
+ def build
4
+ element :polyline, fill: color,
5
+ stroke: color,
6
+ stroke_width: stroke,
7
+ stroke_linejoin: :round,
8
+ points: points
9
+ end
10
+
11
+ protected
12
+
13
+ def points
14
+ result = ["0,#{height}"]
15
+
16
+ inverted_points.each do |point|
17
+ x = width*point[0]
18
+ y = height*point[1]
19
+ result << "#{x},#{y}"
20
+ end
21
+
22
+ result << "#{width},#{height}"
23
+
24
+ result
25
+ end
26
+ end
27
+ end
@@ -1,33 +1,29 @@
1
- module Minichart
2
- class BarChart < Chart
3
- def build
4
- opts = { x_point_count: data.size }
5
-
6
- inverted_points(opts).each do |x, y|
7
- svg.rect bar_options x, y
8
- end
9
- end
10
-
11
- private
12
-
13
- def style
14
- @style ||= { stroke_width: 1, stroke: '#eee' }
15
- end
16
-
17
- def bar_width
18
- @bar_width ||= width / data.size
19
- end
20
-
21
- def bar_options(x, y)
22
- y = y*height
23
- bar_height = height-y
24
- {
25
- x: x*width,
26
- y: y, width:
27
- bar_width, height:
28
- bar_height,
29
- style: style
30
- }
31
- end
32
- end
33
- end
1
+ module Minichart
2
+ class BarChart < Chart
3
+ def build
4
+ opts = { x_point_count: data.size }
5
+
6
+ inverted_points(opts).each do |x, y|
7
+ element :rect, bar_options(x, y)
8
+ end
9
+ end
10
+
11
+ protected
12
+
13
+ def bar_width
14
+ @bar_width ||= width / data.size
15
+ end
16
+
17
+ def bar_options(x, y)
18
+ y = y*height
19
+ bar_height = height-y
20
+ {
21
+ x: x*width,
22
+ y: y,
23
+ width: bar_width,
24
+ height: bar_height,
25
+ style: { fill: color, stroke_width: stroke, stroke: background }
26
+ }
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,28 @@
1
+ module Minichart
2
+ # Base class for charts with data series
3
+ class Chart < Base
4
+
5
+ protected
6
+
7
+ def inverted_points(opts={})
8
+ normalized_points(opts).map { |point| [point[0], 1-point[1]] }
9
+ end
10
+
11
+ def normalized_points(opts={})
12
+ x_point_count = opts[:x_point_count] || data.count-1
13
+
14
+ range = (data.max - data.min).to_f
15
+ x_width = 1 / (x_point_count).to_f
16
+ result = []
17
+
18
+ data.each_with_index do |y, index|
19
+ x = index*x_width
20
+ y = (y - data.min) / range
21
+ result << [x,y]
22
+ end
23
+
24
+ result
25
+ end
26
+
27
+ end
28
+ end
@@ -1,17 +1,23 @@
1
- module Minichart
2
- class LineChart < Chart
3
- def build
4
- svg.polyline fill: :none, stroke: :black, stroke_width: 2, points: points
5
- end
6
-
7
- def points
8
- result = []
9
- inverted_points.each do |point|
10
- x = width*point[0]
11
- y = height*point[1]
12
- result << "#{x},#{y}"
13
- end
14
- result
15
- end
16
- end
17
- end
1
+ module Minichart
2
+ class LineChart < Chart
3
+ def build
4
+ element :polyline, fill: :none,
5
+ stroke: color,
6
+ stroke_width: stroke,
7
+ stroke_linejoin: :round,
8
+ points: points
9
+ end
10
+
11
+ protected
12
+
13
+ def points
14
+ result = []
15
+ inverted_points.each do |point|
16
+ x = width*point[0]
17
+ y = height*point[1]
18
+ result << "#{x},#{y}"
19
+ end
20
+ result
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,14 @@
1
+ module Minichart
2
+ module IDGenerator
3
+ class << self
4
+ def next
5
+ @id ||= 0
6
+ "minichart-#{@id += 1}"
7
+ end
8
+
9
+ def reset
10
+ @id = 0
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,64 @@
1
+ module Minichart
2
+ class HorizontalBarMeter < Meter
3
+ def build
4
+ draw_bar
5
+ draw_zero_line if zero_line
6
+ draw_clipping_indicator if clipping_indicator and clipping?
7
+ end
8
+
9
+ protected
10
+
11
+ def draw_bar
12
+ x = if mode == :negative
13
+ width - bar_width
14
+ elsif mode == :dual
15
+ middle = width * 0.5
16
+ value >= 0 ? middle : middle - bar_width
17
+ else
18
+ 0
19
+ end
20
+
21
+ element :rect, x: x, y: 0, height: height, width: bar_width, style: style
22
+ end
23
+
24
+ def draw_clipping_indicator
25
+ x = if mode == :positive or (mode == :dual and value > 0)
26
+ width - clipping_indicator_size
27
+ else
28
+ 0
29
+ end
30
+
31
+ element :rect, x: x, y: 0,
32
+ height: height, width: clipping_indicator_size,
33
+ fill: clipping_indicator_color, stroke_width: 0
34
+
35
+ end
36
+
37
+ def draw_zero_line
38
+ x = if mode == :negative
39
+ width - zero_line_size
40
+ elsif mode == :dual
41
+ width / 2 - zero_line_size / 2
42
+ else
43
+ 0
44
+ end
45
+
46
+ element :rect, x: x, y: 0,
47
+ height: height, width: zero_line_size,
48
+ fill: zero_line_color, stroke_width: 0
49
+
50
+ end
51
+
52
+ def width_factor
53
+ width / max.to_f
54
+ end
55
+
56
+ def bar_width
57
+ if mode == :dual
58
+ clamped_value.abs * width_factor * 0.5
59
+ else
60
+ clamped_value.abs * width_factor
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,73 @@
1
+ module Minichart
2
+ # Base class for charts with a single value
3
+ class Meter < Base
4
+
5
+ protected
6
+
7
+ def value
8
+ data
9
+ end
10
+
11
+ def clipping?
12
+ value > max || value < -max
13
+ end
14
+
15
+ def mode
16
+ @mode ||= mode!
17
+ end
18
+
19
+ def mode!
20
+ opts[:mode] ||= :auto
21
+
22
+ if opts[:mode] == :auto
23
+ value >= 0 ? :positive : :negative
24
+ else
25
+ opts[:mode].to_sym
26
+ end
27
+ end
28
+
29
+ def max
30
+ opts[:max] ||= 100
31
+ end
32
+
33
+ def zero_line
34
+ opts[:zero_line]
35
+ end
36
+
37
+ def zero_line_size
38
+ opts[:zero_line_size] ||= 6
39
+ end
40
+
41
+ def zero_line_color
42
+ opts[:zero_line_color] ||= 'black'
43
+ end
44
+
45
+ def clipping_indicator
46
+ opts[:clipping_indicator]
47
+ end
48
+
49
+ def clipping_indicator_size
50
+ opts[:clipping_indicator_size] ||= 6
51
+ end
52
+
53
+ def clipping_indicator_color
54
+ opts[:clipping_indicator_color] ||= 'yellow'
55
+ end
56
+
57
+ def clamped_value
58
+ case mode
59
+ when :positive
60
+ value.clamp 0, max
61
+ when :negative
62
+ value.clamp -max, 0
63
+ when :dual
64
+ value.clamp -max, max
65
+ end
66
+ end
67
+
68
+ def style
69
+ { fill: color, stroke_width: stroke, stroke: background }
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,72 @@
1
+ module Minichart
2
+ class VerticalBarMeter < Meter
3
+ def build
4
+ draw_bar
5
+ draw_zero_line if zero_line
6
+ draw_clipping_indicator if clipping_indicator and clipping?
7
+ end
8
+
9
+ protected
10
+
11
+ def width
12
+ opts[:width] ||= 100
13
+ end
14
+
15
+ def height
16
+ opts[:height] ||= (aspect_ratio * width).round
17
+ end
18
+
19
+ def draw_bar
20
+ y = if mode == :positive
21
+ height - bar_height
22
+ elsif mode == :dual
23
+ middle = height * 0.5
24
+ value >= 0 ? middle - bar_height : middle
25
+ else
26
+ 0
27
+ end
28
+
29
+ element :rect, x: 0, y: y, height: bar_height, width: width, style: style
30
+ end
31
+
32
+ def draw_clipping_indicator
33
+ y = if mode == :negative or (mode == :dual and value < 0)
34
+ height - clipping_indicator_size
35
+ else
36
+ 0
37
+ end
38
+
39
+ element :rect, x: 0, y: y,
40
+ height: clipping_indicator_size, width: width,
41
+ fill: clipping_indicator_color, stroke_width: 0
42
+
43
+ end
44
+
45
+ def draw_zero_line
46
+ y = if mode == :positive
47
+ height - zero_line_size
48
+ elsif mode == :dual
49
+ height / 2 - zero_line_size / 2
50
+ else
51
+ 0
52
+ end
53
+
54
+ element :rect, x: 0, y: y,
55
+ height: zero_line_size, width: width,
56
+ fill: zero_line_color, stroke_width: 0
57
+
58
+ end
59
+
60
+ def height_factor
61
+ height / max.to_f
62
+ end
63
+
64
+ def bar_height
65
+ if mode == :dual
66
+ clamped_value.abs * height_factor * 0.5
67
+ else
68
+ clamped_value.abs * height_factor
69
+ end
70
+ end
71
+ end
72
+ end
@@ -1,3 +1,3 @@
1
1
  module Minichart
2
- VERSION = "0.0.1"
2
+ VERSION = "0.2.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minichart
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danny Ben Shitrit
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-20 00:00:00.000000000 Z
11
+ date: 2020-05-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: victor
@@ -16,70 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.1'
19
+ version: '0.3'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.1'
27
- - !ruby/object:Gem::Dependency
28
- name: runfile
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '0.8'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '0.8'
41
- - !ruby/object:Gem::Dependency
42
- name: runfile-tasks
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '0.4'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '0.4'
55
- - !ruby/object:Gem::Dependency
56
- name: byebug
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '9.0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '9.0'
69
- - !ruby/object:Gem::Dependency
70
- name: filewatcher
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '0.5'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '0.5'
26
+ version: '0.3'
83
27
  description: Generate mini charts with SVG
84
28
  email: db@dannyben.com
85
29
  executables: []
@@ -88,9 +32,15 @@ extra_rdoc_files: []
88
32
  files:
89
33
  - README.md
90
34
  - lib/minichart.rb
91
- - lib/minichart/bar_chart.rb
92
- - lib/minichart/chart.rb
93
- - lib/minichart/line_chart.rb
35
+ - lib/minichart/base.rb
36
+ - lib/minichart/charts/area_chart.rb
37
+ - lib/minichart/charts/bar_chart.rb
38
+ - lib/minichart/charts/chart.rb
39
+ - lib/minichart/charts/line_chart.rb
40
+ - lib/minichart/id_generator.rb
41
+ - lib/minichart/meters/horizontal_bar_meter.rb
42
+ - lib/minichart/meters/meter.rb
43
+ - lib/minichart/meters/vertical_bar_meter.rb
94
44
  - lib/minichart/version.rb
95
45
  homepage: https://github.com/DannyBen/minichart
96
46
  licenses:
@@ -104,15 +54,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
104
54
  requirements:
105
55
  - - ">="
106
56
  - !ruby/object:Gem::Version
107
- version: 2.0.0
57
+ version: 2.5.0
108
58
  required_rubygems_version: !ruby/object:Gem::Requirement
109
59
  requirements:
110
60
  - - ">="
111
61
  - !ruby/object:Gem::Version
112
62
  version: '0'
113
63
  requirements: []
114
- rubyforge_project:
115
- rubygems_version: 2.6.6
64
+ rubygems_version: 3.1.2
116
65
  signing_key:
117
66
  specification_version: 4
118
67
  summary: SVG Mini Charts
@@ -1,47 +0,0 @@
1
- module Minichart
2
- class Chart
3
- attr_accessor :data, :aspect_ratio
4
-
5
- def save(name)
6
- svg.rect x: 0, y: 0, width: width, height: height, fill: '#ccc'
7
- build
8
- svg.save name
9
- end
10
-
11
- def build
12
- raise "Subeclass needs to implement #build"
13
- end
14
-
15
- def inverted_points(opts={})
16
- normalized_points(opts).map { |point| [point[0], 1-point[1]] }
17
- end
18
-
19
- def normalized_points(opts={})
20
- x_point_count = opts[:x_point_count] || data.count-1
21
-
22
- range = (data.max - data.min).to_f
23
- x_width = 1/(x_point_count).to_f
24
- result = []
25
-
26
- data.each_with_index do |y, index|
27
- x = index*x_width
28
- y = (y-data.min)/range
29
- result << [x,y]
30
- end
31
-
32
- result
33
- end
34
-
35
- def width
36
- @width ||= (aspect_ratio * height).round
37
- end
38
-
39
- def height
40
- 100
41
- end
42
-
43
- def svg
44
- @svg ||= SVG.new viewBox: "0 0 #{width} #{height}", style: { background: '#ddd' }
45
- end
46
- end
47
- end