scruffy 0.2.2 → 0.2.3

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.
Files changed (84) hide show
  1. data/CHANGES +8 -0
  2. data/History.txt +104 -0
  3. data/License.txt +20 -0
  4. data/Manifest.txt +105 -0
  5. data/PostInstall.txt +6 -0
  6. data/README.txt +66 -0
  7. data/Rakefile +108 -104
  8. data/config/hoe.rb +78 -0
  9. data/config/requirements.rb +15 -0
  10. data/lib/scruffy.rb +8 -6
  11. data/lib/scruffy/components/base.rb +4 -0
  12. data/lib/scruffy/components/legend.rb +65 -30
  13. data/lib/scruffy/components/viewport.rb +14 -17
  14. data/lib/scruffy/formatters.rb +1 -1
  15. data/lib/scruffy/graph.rb +18 -7
  16. data/lib/scruffy/graph_state.rb +24 -0
  17. data/lib/scruffy/helpers.rb +2 -1
  18. data/lib/scruffy/helpers/canvas.rb +19 -17
  19. data/lib/scruffy/helpers/layer_container.rb +8 -3
  20. data/lib/scruffy/helpers/meta.rb +5 -5
  21. data/lib/scruffy/helpers/point_container.rb +70 -0
  22. data/lib/scruffy/layers.rb +2 -0
  23. data/lib/scruffy/layers/average.rb +6 -1
  24. data/lib/scruffy/layers/bar.rb +1 -0
  25. data/lib/scruffy/layers/base.rb +38 -14
  26. data/lib/scruffy/layers/pie.rb +123 -0
  27. data/lib/scruffy/layers/pie_slice.rb +114 -0
  28. data/lib/scruffy/layers/scatter.rb +21 -0
  29. data/lib/scruffy/layers/sparkline_bar.rb +1 -0
  30. data/lib/scruffy/layers/stacked.rb +2 -5
  31. data/lib/scruffy/rasterizers/rmagick_rasterizer.rb +1 -2
  32. data/lib/scruffy/renderers.rb +2 -1
  33. data/lib/scruffy/renderers/base.rb +6 -4
  34. data/lib/scruffy/renderers/pie.rb +20 -0
  35. data/lib/scruffy/themes.rb +54 -4
  36. data/lib/scruffy/version.rb +8 -2
  37. data/script/console +10 -0
  38. data/script/destroy +14 -0
  39. data/script/generate +14 -0
  40. data/script/txt2html +82 -0
  41. data/setup.rb +1585 -0
  42. data/spec/scruffy/graph_spec.rb +175 -0
  43. data/spec/scruffy/layers/base_spec.rb +30 -0
  44. data/spec/{layers → scruffy/layers}/line_spec.rb +2 -1
  45. data/spec/spec_helper.rb +8 -0
  46. data/tasks/deployment.rake +34 -0
  47. data/tasks/environment.rake +7 -0
  48. data/tasks/website.rake +17 -0
  49. data/test/graph_creation_test.rb +101 -0
  50. data/test/test_helper.rb +2 -0
  51. data/test/test_scruffy.rb +11 -0
  52. data/website/images/blank.gif.html +7 -0
  53. data/website/images/graphs/all_smiles.png +0 -0
  54. data/website/images/graphs/bar_test.png +0 -0
  55. data/website/images/graphs/bar_test.svg +71 -0
  56. data/website/images/graphs/line_test.png +0 -0
  57. data/website/images/graphs/line_test.svg +60 -0
  58. data/website/images/graphs/multi_test.png +0 -0
  59. data/website/images/graphs/multi_test.svg +296 -0
  60. data/website/images/graphs/pie_test.png +0 -0
  61. data/website/images/graphs/pie_test.svg +40 -0
  62. data/website/images/graphs/split_test.png +0 -0
  63. data/website/images/graphs/split_test.svg +295 -0
  64. data/website/images/graphs/stacking_test.png +0 -0
  65. data/website/images/graphs/stacking_test.svg +146 -0
  66. data/website/images/header.png +0 -0
  67. data/website/images/header_gradient.png +0 -0
  68. data/website/images/overlay.png +0 -0
  69. data/website/images/scruffy.png +0 -0
  70. data/website/index.html +294 -0
  71. data/website/index.txt +199 -0
  72. data/website/javascripts/application.js +2 -0
  73. data/website/javascripts/controls.js +815 -0
  74. data/website/javascripts/dragdrop.js +913 -0
  75. data/website/javascripts/effects.js +958 -0
  76. data/website/javascripts/lightbox.js +437 -0
  77. data/website/javascripts/prototype.js +2006 -0
  78. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  79. data/website/stylesheets/lightbox.css +27 -0
  80. data/website/stylesheets/screen.css +147 -0
  81. data/website/stylesheets/scruffy.css +227 -0
  82. data/website/template.html.erb +47 -0
  83. metadata +135 -55
  84. data/spec/graph_spec.rb +0 -162
@@ -0,0 +1,175 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+ require 'scruffy'
3
+ require 'fileutils'
4
+
5
+ module CustomRenderers
6
+ def blank_renderer
7
+ object = Object.new
8
+ object.instance_eval { class << self;self;end }.instance_eval { define_method :render do |options|
9
+ puts "Rendering"
10
+ end
11
+ }
12
+ object
13
+ end
14
+ end
15
+
16
+ describe "A new Scruffy::Graph" do
17
+ include CustomRenderers
18
+
19
+ setup do
20
+ @graph = Scruffy::Graph.new
21
+ end
22
+
23
+ it "should have a blank title" do
24
+ @graph.title.should be_nil
25
+ end
26
+
27
+ it "should be set to the keynote theme" do
28
+ @graph.theme.class.should equal(Scruffy::Themes::Keynote)
29
+ end
30
+
31
+ it "should have zero layers" do
32
+ @graph.layers.should be_empty
33
+ end
34
+
35
+ it "should not have a default layer type" do
36
+ @graph.default_type.should be_nil
37
+ end
38
+
39
+ it "should not have any point markers (x-axis values)" do
40
+ @graph.point_markers.should be_nil
41
+ end
42
+
43
+ it "should format values as numbers by default" do
44
+ @graph.value_formatter.should be_instance_of(Scruffy::Formatters::Number)
45
+ end
46
+
47
+ it "should use a StandardRenderer" do
48
+ @graph.renderer.should_be be_instance_of(Scruffy::Renderers::Standard)
49
+ end
50
+
51
+ it "should accept a new title" do
52
+ @graph.title = "New Title"
53
+ @graph.title.should == "New Title"
54
+ end
55
+
56
+ it "should accept a new theme" do
57
+ @graph.theme = Scruffy::Themes::Mephisto
58
+ @graph.theme.should equal(Scruffy::Themes::Mephisto)
59
+ end
60
+
61
+ it "should accept a new default type" do
62
+ @graph.default_type = :line
63
+ @graph.default_type.should equal(:line)
64
+ end
65
+
66
+ it "should accept new point markers" do
67
+ markers = ['Jan', 'Feb', 'Mar']
68
+ @graph.point_markers = markers
69
+ @graph.point_markers.should equal(markers)
70
+ end
71
+
72
+ it "should accept a new renderer" do
73
+ renderer = blank_renderer
74
+ @graph.renderer = renderer
75
+ @graph.renderer.should equal(renderer)
76
+ end
77
+
78
+ it "should not accept renderers with missing #render methods" do
79
+ lambda { @graph.renderer = 1 }.should raise_error(ArgumentError)
80
+ end
81
+ end
82
+
83
+ describe "A Scruffy::Graph's initialization block" do
84
+ include CustomRenderers
85
+
86
+ it "should accept just a default_type Symbol" do
87
+ lambda { Scruffy::Graph.new(:line) }.should_not raise_error
88
+ end
89
+
90
+ it "should accept just an options hash" do
91
+ lambda { Scruffy::Graph.new({:title => "My Title"}) }.should_not raise_error
92
+ lambda { Scruffy::Graph.new(:title => "My Title", :theme => Scruffy::Themes::Keynote) }.should_not raise_error
93
+ end
94
+
95
+ it "should accept both a default_type and options hash" do
96
+ lambda {
97
+ Scruffy::Graph.new(:line, {:title => "My Title"})
98
+ Scruffy::Graph.new(:line, :title => "My Title")
99
+ }.should_not raise_error
100
+ end
101
+
102
+ it "should reject any invalid argument combination" do
103
+ lambda { Scruffy::Graph.new({:title => "My Title"}, :line) }.should raise_error(ArgumentError)
104
+ lambda { Scruffy::Graph.new(:line, {:title => "My Title"}, "Any additional arguments.") }.should raise_error(ArgumentError)
105
+ lambda { Scruffy::Graph.new(:line, "Any additional arguments.") }.should raise_error(ArgumentError)
106
+ end
107
+
108
+ it "should reject any options that are not supported" do
109
+ lambda { Scruffy::Graph.new(:title => "My Title", :some_key => "Some Value") }.should raise_error(ArgumentError)
110
+ end
111
+
112
+ it "should successfully save all valid options" do
113
+ options = {:title => "My Title",
114
+ :theme => {:background => [:black],
115
+ :colors => [:red => 'red', :yellow => 'yellow']},
116
+ :layers => [ Scruffy::Layers::Line.new(:points => [100, 200, 300]) ],
117
+ :default_type => :average,
118
+ :value_formatter => Scruffy::Formatters::Currency.new,
119
+ :point_markers => ['One Hundred', 'Two Hundred', 'Three Hundred']}
120
+
121
+ @graph = Scruffy::Graph.new(options)
122
+
123
+ @graph.title.should == options[:title]
124
+ @graph.theme.should == options[:theme]
125
+ @graph.layers.should == options[:layers]
126
+ @graph.default_type.should == options[:default_type]
127
+ @graph.value_formatter.should == options[:value_formatter]
128
+ @graph.point_markers.should == options[:point_markers]
129
+ end
130
+ end
131
+
132
+
133
+ context "A fully populated Graph" do
134
+ setup do
135
+ FileUtils.rm_f File.dirname(__FILE__) + '/*.png'
136
+ FileUtils.rm_f File.dirname(__FILE__) + '/*.jpg'
137
+
138
+ @graph = Scruffy::Graph.new :title => 'Test Graph'
139
+ @graph << Scruffy::Layers::Average.new(:title => 'Average', :points => @graph.layers)
140
+ @graph.layers.first.relevant_data = false
141
+ @graph << Scruffy::Layers::AllSmiles.new(:title => 'Smiles', :points => [100, 200, 300])
142
+ @graph << Scruffy::Layers::Area.new(:title => 'Area', :points => [100, 200, 300])
143
+ @graph << Scruffy::Layers::Bar.new(:title => 'Bar', :points => [100, 200, 300])
144
+ @graph << Scruffy::Layers::Line.new(:title => 'Line', :points => [100, 200, 300])
145
+ end
146
+
147
+ it "should render to SVG" do
148
+ @graph.render(:width => 800).should be_instance_of(String)
149
+ end
150
+
151
+ it "should rasterize to PNG" do
152
+ lambda {
153
+ #@graph.render(:width => 800, :as => 'PNG', :to => outfile('test_graph.png'))
154
+ }.should_not raise_error
155
+ end
156
+
157
+ it "should rasterize to JPG" do
158
+ lambda {
159
+ #@graph.render(:width => 800, :as => 'JPG', :to => outfile('test_graph.jpg'))
160
+ }.should_not raise_error
161
+ end
162
+ end
163
+
164
+
165
+ context "A graph with hash data" do
166
+ specify "should render identically to a graph with array data" do
167
+ @hashgraph = Scruffy::Graph.new :title => 'Graph'
168
+ @hashgraph.add(:line, 'Data', { 0 => 1, 1 => 2, 3 => 4 })
169
+
170
+ @arraygraph = Scruffy::Graph.new :title => 'Graph'
171
+ @arraygraph.add(:line, 'Data', [1, 2, nil, 4])
172
+
173
+ @hashgraph.render(:to => outfile('hash.svg')).should == @arraygraph.render(:to => outfile('array.svg'))
174
+ end
175
+ end
@@ -0,0 +1,30 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
2
+ require 'scruffy'
3
+
4
+ context "Any layer" do
5
+ specify "should accept but ignore nil data" do
6
+ render([100, nil, 300]).should eql([[0.0, 400], [400.0, 0.0]])
7
+ end
8
+
9
+ specify "should accept hash data as sequentially-keyed data" do
10
+ render([100, nil, 300]).should eql([[0.0, 400], [400.0, 0.0]])
11
+ render({0 => 100, 2 => 300}).should eql([[0.0, 400], [400.0, 0.0]])
12
+ end
13
+
14
+ def render points
15
+ layer = Scruffy::Layers::Base.new(:title => 'My base Layer', :points => points)
16
+
17
+ #stub out draw to just return coords
18
+ class << layer; def draw(svg, coords, options={}); coords end; end;
19
+
20
+ coords = []
21
+
22
+ lambda {
23
+ size = [400,400]
24
+ coords = layer.render(Scruffy::Renderers::Base.new.render(:layers => [layer], :size => size),
25
+ :size => size, :min_value => 100, :max_value => 300)
26
+ }.should_not raise_error
27
+
28
+ coords
29
+ end
30
+ end
@@ -1,9 +1,10 @@
1
- context "A Line layer" do
1
+ describe "A Line layer" do
2
2
  setup do
3
3
  @layer = Scruffy::Layers::Line.new(:title => 'My Line Layer', :points => [100, 200, 300])
4
4
 
5
5
  svg = mock('svg')
6
6
  svg.should_receive(:polyline).once
7
7
  svg.should_receive(:circle).exactly(3).times
8
+
8
9
  end
9
10
  end
@@ -0,0 +1,8 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
+
3
+ def outfile( name )
4
+ output_dir = File.join(File.dirname(__FILE__), "output")
5
+
6
+ FileUtils.mkdir( output_dir ) unless File.exist?( output_dir )
7
+ File.join( output_dir, name )
8
+ end
@@ -0,0 +1,34 @@
1
+ desc 'Release the website and new gem version'
2
+ task :deploy => [:check_version, :website, :release] do
3
+ puts "Remember to create SVN tag:"
4
+ puts "svn copy svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/trunk " +
5
+ "svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/tags/REL-#{VERS} "
6
+ puts "Suggested comment:"
7
+ puts "Tagging release #{CHANGES}"
8
+ end
9
+
10
+ desc 'Runs tasks website_generate and install_gem as a local deployment of the gem'
11
+ task :local_deploy => [:website_generate, :install_gem]
12
+
13
+ task :check_version do
14
+ unless ENV['VERSION']
15
+ puts 'Must pass a VERSION=x.y.z release version'
16
+ exit
17
+ end
18
+ unless ENV['VERSION'] == VERS
19
+ puts "Please update your version.rb to match the release version, currently #{VERS}"
20
+ exit
21
+ end
22
+ end
23
+
24
+ desc 'Install the package as a gem, without generating documentation(ri/rdoc)'
25
+ task :install_gem_no_doc => [:clean, :package] do
26
+ sh "#{'sudo ' unless Hoe::WINDOZE }gem install pkg/*.gem --no-rdoc --no-ri"
27
+ end
28
+
29
+ namespace :manifest do
30
+ desc 'Recreate Manifest.txt to include ALL files'
31
+ task :refresh do
32
+ `rake check_manifest | patch -p0 > Manifest.txt`
33
+ end
34
+ end
@@ -0,0 +1,7 @@
1
+ task :ruby_env do
2
+ RUBY_APP = if RUBY_PLATFORM =~ /java/
3
+ "jruby"
4
+ else
5
+ "ruby"
6
+ end unless defined? RUBY_APP
7
+ end
@@ -0,0 +1,17 @@
1
+ desc 'Generate website files'
2
+ task :website_generate => :ruby_env do
3
+ (Dir['website/**/*.txt'] - Dir['website/version*.txt']).each do |txt|
4
+ sh %{ #{RUBY_APP} script/txt2html #{txt} > #{txt.gsub(/txt$/,'html')} }
5
+ end
6
+ end
7
+
8
+ desc 'Upload website files to rubyforge'
9
+ task :website_upload do
10
+ host = "#{rubyforge_username}@rubyforge.org"
11
+ remote_dir = "/var/www/gforge-projects/#{PATH}/"
12
+ local_dir = 'website'
13
+ sh %{rsync -rlgoDCv #{local_dir}/ #{host}:#{remote_dir}}
14
+ end
15
+
16
+ desc 'Generate and upload website files'
17
+ task :website => [:website_generate, :website_upload, :publish_docs]
@@ -0,0 +1,101 @@
1
+ require 'test/unit'
2
+ require 'scruffy'
3
+
4
+ class SimpleTheme < Scruffy::Themes::Base
5
+ def initialize
6
+ super({
7
+ :background => [:white, :white],
8
+ :marker => :black,
9
+ :colors => %w(blue green red orange yellow purple pink),
10
+ :stroke_color => 'white'
11
+ })
12
+ end
13
+ end
14
+
15
+ class GraphCreationTest < Test::Unit::TestCase
16
+ BASE_DIR = File.dirname(__FILE__)
17
+ WEBSITE_DIR = BASE_DIR + "/../website/images/graphs"
18
+
19
+ def test_create_pie
20
+ graph = Scruffy::Graph.new
21
+ graph.title = "Favourite Snacks"
22
+ graph.renderer = Scruffy::Renderers::Pie.new
23
+
24
+ graph.add :pie, '', {
25
+ 'Apple' => 20,
26
+ 'Banana' => 100,
27
+ 'Orange' => 70,
28
+ 'Taco' => 30
29
+ }
30
+
31
+ graph.render :to => "#{WEBSITE_DIR}/pie_test.svg"
32
+ graph.render :width => 400, :to => "#{WEBSITE_DIR}/pie_test.png", :as => 'png'
33
+ end
34
+
35
+ def test_create_line
36
+ graph = Scruffy::Graph.new
37
+ graph.title = "Sample Line Graph"
38
+ graph.renderer = Scruffy::Renderers::Standard.new
39
+
40
+ graph.add :line, 'Example', [20, 100, 70, 30, 106]
41
+
42
+ graph.render :to => "#{WEBSITE_DIR}/line_test.svg"
43
+ graph.render :width => 400, :to => "#{WEBSITE_DIR}/line_test.png", :as => 'png'
44
+ end
45
+
46
+
47
+ def test_create_bar
48
+ graph = Scruffy::Graph.new
49
+ graph.title = "Sample Bar Graph"
50
+ graph.renderer = Scruffy::Renderers::Standard.new
51
+ graph.add :bar, 'Example', [20, 100, 70, 30, 106]
52
+ graph.render :to => "#{WEBSITE_DIR}/bar_test.svg"
53
+ graph.render :width => 400, :to => "#{WEBSITE_DIR}/bar_test.png", :as => 'png'
54
+ end
55
+
56
+ def test_split
57
+ graph = Scruffy::Graph.new
58
+ graph.title = "Long-term Comparisons"
59
+ graph.value_formatter = Scruffy::Formatters::Currency.new(:special_negatives => true, :negative_color => '#ff7777')
60
+ graph.renderer = Scruffy::Renderers::Split.new(:split_label => 'Northeastern (Top) / Central (Bottom)')
61
+
62
+ graph.add :area, 'Jeff', [20, -5, 100, 70, 30, 106, 203, 100, 50, 203, 289, 20], :category => :top
63
+ graph.add :area, 'Jerry', [-10, 70, 20, 102, 201, 26, 30, 106, 203, 100, 50, 39], :category => :top
64
+ graph.add :bar, 'Jack', [30, 0, 49, 29, 100, 203, 70, 20, 102, 201, 26, 130], :category => :bottom
65
+ graph.add :line, 'Brasten', [42, 10, 75, 150, 130, 70, -10, -20, 50, 92, -21, 19], :categories => [:top, :bottom]
66
+ graph.add :line, 'Jim', [-10, -20, 50, 92, -21, 56, 92, 84, 82, 100, 39, 120], :categories => [:top, :bottom]
67
+ graph.point_markers = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
68
+
69
+ graph.render :to => "#{WEBSITE_DIR}/split_test.svg"
70
+ graph.render :width => 500, :to => "#{WEBSITE_DIR}/split_test.png", :as => 'png'
71
+ end
72
+
73
+ def test_stacking
74
+ graph = Scruffy::Graph.new
75
+ graph.title = "Comparative Agent Performance"
76
+ graph.value_formatter = Scruffy::Formatters::Percentage.new(:precision => 0)
77
+ graph.add :stacked do |stacked|
78
+ stacked.add :bar, 'Jack', [30, 60, 49, 29, 100, 120]
79
+ stacked.add :bar, 'Jill', [120, 240, 0, 100, 140, 20]
80
+ stacked.add :bar, 'Hill', [10, 10, 90, 20, 40, 10]
81
+ end
82
+ graph.point_markers = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']
83
+ graph.render :to => "#{WEBSITE_DIR}/stacking_test.svg"
84
+ graph.render :width => 500, :to => "#{WEBSITE_DIR}/stacking_test.png", :as => 'png'
85
+ end
86
+
87
+ def test_multi_layered
88
+ graph = Scruffy::Graph.new
89
+ graph.title = "Some Kind of Information"
90
+ graph.renderer = Scruffy::Renderers::Cubed.new
91
+
92
+ graph.add :area, 'Jeff', [20, -5, 100, 70, 30, 106], :categories => [:top_left, :bottom_right]
93
+ graph.add :area, 'Jerry', [-10, 70, 20, 102, 201, 26], :categories => [:bottom_left, :buttom_right]
94
+ graph.add :bar, 'Jack', [30, 0, 49, 29, 100, 203], :categories => [:bottom_left, :top_right]
95
+ graph.add :line, 'Brasten', [42, 10, 75, 150, 130, 70], :categories => [:top_right, :bottom_left]
96
+ graph.add :line, 'Jim', [-10, -20, 50, 92, -21, 56], :categories => [:top_left, :bottom_right]
97
+ graph.point_markers = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']
98
+ graph.render :to => "#{WEBSITE_DIR}/multi_test.svg"
99
+ graph.render :width => 500, :to => "#{WEBSITE_DIR}/multi_test.png", :as => 'png'
100
+ end
101
+ end
@@ -0,0 +1,2 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../lib/scruffy'
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestScruffy < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def test_truth
9
+ assert true
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
2
+ <html><head>
3
+ <title>404 Not Found</title>
4
+ </head><body>
5
+ <h1>Not Found</h1>
6
+ <p>The requested URL /images/blank.gif was not found on this server.</p>
7
+ </body></html>
@@ -0,0 +1,71 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <?DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" type=""?>
3
+ <svg xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="360" xmlns="http://www.w3.org/2000/svg">
4
+ <g id="scruffy_graph">
5
+ <g transform="translate(0.0, 0.0)" id="background">
6
+ <defs>
7
+ <linearGradient x2="0%" y2="100%" x1="0%" id="BackgroundGradient" y1="0%">
8
+ <stop stop-color="black" offset="5%"/>
9
+ <stop stop-color="#4A465A" offset="95%"/>
10
+ </linearGradient>
11
+ </defs>
12
+ <rect width="600.0" x="0" y="0" height="360.0" fill="url(#BackgroundGradient)"/>
13
+ </g>
14
+ <g transform="translate(30.0, 7.2)" id="title">
15
+ <text class="title" font-size="25.2" x="270.0" text-anchor="middle" y="25.2" stroke="none" stroke-width="0" fill="white">Sample Bar Graph</text>
16
+ </g>
17
+ <g transform="translate(12.0, 93.6)" id="view">
18
+ <g>
19
+ <g transform="translate(0.0, 4.752)" id="values">
20
+ <text font-size="16.91712" x="96.12" text-anchor="end" y="211.464" fill="white">7</text>
21
+ <text font-size="16.91712" x="96.12" text-anchor="end" y="158.598" fill="white">32</text>
22
+ <text font-size="16.91712" x="96.12" text-anchor="end" y="105.732" fill="white">57</text>
23
+ <text font-size="16.91712" x="96.12" text-anchor="end" y="52.866" fill="white">81</text>
24
+ <text font-size="16.91712" x="96.12" text-anchor="end" y="0.0" fill="white">106</text>
25
+ </g>
26
+ <g transform="translate(106.8, 0.0)" id="grid">
27
+ <line x2="427.2" y2="0.0" x1="0" style="stroke: white; stroke-width: 2;" y1="0.0"/>
28
+ <line x2="427.2" y2="52.866" x1="0" style="stroke: white; stroke-width: 2;" y1="52.866"/>
29
+ <line x2="427.2" y2="105.732" x1="0" style="stroke: white; stroke-width: 2;" y1="105.732"/>
30
+ <line x2="427.2" y2="158.598" x1="0" style="stroke: white; stroke-width: 2;" y1="158.598"/>
31
+ <line x2="427.2" y2="211.464" x1="0" style="stroke: white; stroke-width: 2;" y1="211.464"/>
32
+ </g>
33
+ <g transform="translate(106.8, 218.592)" id="labels">
34
+ </g>
35
+ <g transform="translate(106.8, 0.0)" id="graphs">
36
+ <g class="graph_layer" id="component_graphs_graph_0">
37
+ <g transform="translate(-1.05732, -1.05732)">
38
+ <rect width="79.01064" x="4.272" y="183.881739130435" height="29.6969008695652" style="fill: black; fill-opacity: 0.15; stroke: none;"/>
39
+ <rect width="79.01064" x="5.32932" y="188.111019130435" height="26.5249408695652" style="fill: black; fill-opacity: 0.15; stroke: none;"/>
40
+ </g>
41
+ <rect width="76.896" x="4.272" y="183.881739130435" height="27.5822608695652" fill="#6886B4" style="opacity: 1.0; stroke: none;"/>
42
+ <g transform="translate(-1.05732, -1.05732)">
43
+ <rect width="79.01064" x="89.712" y="12.8289585439838" height="200.749681456016" style="fill: black; fill-opacity: 0.15; stroke: none;"/>
44
+ <rect width="79.01064" x="90.76932" y="17.0582385439838" height="197.577721456016" style="fill: black; fill-opacity: 0.15; stroke: none;"/>
45
+ </g>
46
+ <rect width="76.896" x="89.712" y="12.8289585439838" height="198.635041456016" fill="#6886B4" style="opacity: 1.0; stroke: none;"/>
47
+ <g transform="translate(-1.05732, -1.05732)">
48
+ <rect width="79.01064" x="175.152" y="76.973751263903" height="136.604888736097" style="fill: black; fill-opacity: 0.15; stroke: none;"/>
49
+ <rect width="79.01064" x="176.20932" y="81.203031263903" height="133.432928736097" style="fill: black; fill-opacity: 0.15; stroke: none;"/>
50
+ </g>
51
+ <rect width="76.896" x="175.152" y="76.973751263903" height="134.490248736097" fill="#6886B4" style="opacity: 1.0; stroke: none;"/>
52
+ <g transform="translate(-1.05732, -1.05732)">
53
+ <rect width="79.01064" x="260.592" y="162.500141557128" height="51.0784984428716" style="fill: black; fill-opacity: 0.15; stroke: none;"/>
54
+ <rect width="79.01064" x="261.64932" y="166.729421557128" height="47.9065384428716" style="fill: black; fill-opacity: 0.15; stroke: none;"/>
55
+ </g>
56
+ <rect width="76.896" x="260.592" y="162.500141557128" height="48.9638584428716" fill="#6886B4" style="opacity: 1.0; stroke: none;"/>
57
+ <g transform="translate(-1.05732, -1.05732)">
58
+ <rect width="79.01064" x="346.032" y="0.0" height="213.57864" style="fill: black; fill-opacity: 0.15; stroke: none;"/>
59
+ <rect width="79.01064" x="347.08932" y="4.22928" height="210.40668" style="fill: black; fill-opacity: 0.15; stroke: none;"/>
60
+ </g>
61
+ <rect width="76.896" x="346.032" y="0.0" height="211.464" fill="#6886B4" style="opacity: 1.0; stroke: none;"/>
62
+ </g>
63
+ </g>
64
+ </g>
65
+ </g>
66
+ <g transform="translate(30.0, 46.8)" id="legend">
67
+ <rect width="10.8" x="226.8" y="0" height="10.8" fill="#6886B4"/>
68
+ <text font-size="1.3824" x="228.528" y="1.0368" fill="white" style="color: white">Example</text>
69
+ </g>
70
+ </g>
71
+ </svg>