galaaz 0.4.5 → 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +696 -270
  3. data/Rakefile +9 -22
  4. data/bin/gknit +2 -217
  5. data/bin/gknit_old_r +236 -0
  6. data/bin/grun +5 -0
  7. data/blogs/dev/dev.Rmd +7 -0
  8. data/blogs/dev/dev.html +34 -26
  9. data/blogs/dev/dev.md +40 -25
  10. data/blogs/dev/dev_files/figure-html/bubble-1.png +0 -0
  11. data/blogs/dev/dev_files/figure-html/diverging_bar. +0 -0
  12. data/blogs/dev/dev_files/figure-html/diverging_bar.png +0 -0
  13. data/blogs/galaaz_ggplot/galaaz_ggplot.Rmd +4 -4
  14. data/blogs/galaaz_ggplot/galaaz_ggplot.html +251 -59
  15. data/blogs/galaaz_ggplot/galaaz_ggplot.log +640 -0
  16. data/blogs/galaaz_ggplot/galaaz_ggplot.md +199 -95
  17. data/blogs/galaaz_ggplot/galaaz_ggplot.tex +45 -228
  18. data/blogs/galaaz_ggplot/midwest.png +0 -0
  19. data/blogs/galaaz_ggplot/scatter_plot.png +0 -0
  20. data/blogs/gknit/gknit.Rmd +271 -148
  21. data/blogs/manual/manual.Rmd +212 -0
  22. data/blogs/manual/manual.html +1832 -0
  23. data/blogs/manual/manual.md +751 -0
  24. data/blogs/manual/manual_files/figure-html/diverging_bar.png +0 -0
  25. data/blogs/ruby_plot/ruby_plot.Rmd +5 -69
  26. data/blogs/ruby_plot/ruby_plot.html +195 -236
  27. data/blogs/ruby_plot/ruby_plot.md +1 -261
  28. data/blogs/ruby_plot/ruby_plot_files/figure-html/dose_len.svg +38 -38
  29. data/examples/sthda_ggplot/two_variables_disc_cont/geom_dotplot.rb +5 -5
  30. data/examples/sthda_ggplot/two_variables_disc_cont/geom_jitter.rb +1 -0
  31. data/examples/sthda_ggplot/two_variables_disc_cont/geom_violin.rb +3 -7
  32. data/examples/sthda_ggplot/two_variables_error/geom_crossbar.rb +3 -1
  33. data/lib/R_interface/r.rb +12 -9
  34. data/lib/R_interface/r_methods.rb +2 -2
  35. data/lib/R_interface/rbinary_operators.rb +2 -20
  36. data/lib/R_interface/rdata_frame.rb +56 -9
  37. data/lib/R_interface/rdevices.R +0 -12
  38. data/lib/R_interface/rexpression.rb +0 -97
  39. data/lib/R_interface/rindexed_object.rb +12 -3
  40. data/lib/R_interface/rlanguage.rb +1 -1
  41. data/lib/R_interface/rlist.rb +29 -4
  42. data/lib/R_interface/rlogical_operators.rb +50 -0
  43. data/lib/R_interface/rmatrix.rb +7 -1
  44. data/lib/R_interface/robject.rb +29 -15
  45. data/lib/R_interface/rsupport.rb +74 -58
  46. data/lib/R_interface/rsymbol.rb +2 -1
  47. data/lib/R_interface/ruby_extensions.rb +11 -2
  48. data/lib/R_interface/rvector.rb +26 -11
  49. data/lib/gknit.rb +2 -0
  50. data/lib/gknit/include_engine.rb +57 -0
  51. data/lib/gknit/knitr_engine.rb +596 -50
  52. data/lib/gknit/rb_engine.rb +56 -0
  53. data/lib/gknit/ruby_engine.rb +13 -36
  54. data/lib/util/exec_ruby.rb +132 -21
  55. data/lib/util/inline_file.rb +9 -7
  56. data/specs/all.rb +5 -0
  57. data/specs/figures/bg.jpeg +0 -0
  58. data/specs/figures/bg.png +0 -0
  59. data/specs/figures/bg.svg +57 -0
  60. data/specs/figures/no_args.jpeg +0 -0
  61. data/specs/figures/no_args.png +0 -0
  62. data/specs/figures/no_args.svg +57 -0
  63. data/specs/figures/width_height.jpeg +0 -0
  64. data/specs/figures/width_height.png +0 -0
  65. data/specs/figures/width_height_units1.jpeg +0 -0
  66. data/specs/figures/width_height_units1.png +0 -0
  67. data/specs/figures/width_height_units2.jpeg +0 -0
  68. data/specs/figures/width_height_units2.png +0 -0
  69. data/specs/r_dataframe.spec.rb +29 -27
  70. data/specs/r_devices.spec.rb +347 -0
  71. data/specs/r_eval.spec.rb +10 -3
  72. data/specs/r_formula.spec.rb +2 -2
  73. data/specs/r_language.spec.rb +112 -0
  74. data/specs/r_list.spec.rb +174 -14
  75. data/specs/r_list_apply.spec.rb +17 -10
  76. data/specs/r_matrix.spec.rb +3 -3
  77. data/specs/r_vector_operators.spec.rb +13 -7
  78. data/specs/tmp.rb +42 -12
  79. data/version.rb +1 -1
  80. metadata +28 -24
  81. data/bin/gknit2 +0 -14
  82. data/bin/prepareR.rb +0 -3
  83. data/bin/tmp.py +0 -51
  84. data/blogs/gknit/gknit.html +0 -528
  85. data/blogs/gknit/gknit.md +0 -628
  86. data/blogs/gknit/gknit.pdf +0 -0
  87. data/blogs/gknit/gknit.tex +0 -745
  88. data/blogs/gknit/gknit_files/figure-html/bubble-1.png +0 -0
  89. data/blogs/gknit/gknit_files/figure-html/diverging_bar.png +0 -0
  90. data/blogs/ruby_plot/figures/dose_len.png +0 -0
  91. data/blogs/ruby_plot/figures/facet_by_delivery.png +0 -0
  92. data/blogs/ruby_plot/figures/facet_by_dose.png +0 -0
  93. data/blogs/ruby_plot/figures/facets_by_delivery_color.png +0 -0
  94. data/blogs/ruby_plot/figures/facets_by_delivery_color2.png +0 -0
  95. data/blogs/ruby_plot/figures/facets_with_decorations.png +0 -0
  96. data/blogs/ruby_plot/figures/facets_with_jitter.png +0 -0
  97. data/blogs/ruby_plot/figures/facets_with_points.png +0 -0
  98. data/blogs/ruby_plot/figures/final_box_plot.png +0 -0
  99. data/blogs/ruby_plot/figures/final_violin_plot.png +0 -0
  100. data/blogs/ruby_plot/figures/violin_with_jitter.png +0 -0
  101. data/lib/R/eng_ruby.R +0 -62
  102. data/lib/R_interface/rdevices.rb +0 -225
@@ -0,0 +1,56 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ##########################################################################################
4
+ # @author Rodrigo Botafogo
5
+ #
6
+ # Copyright © 2018 Rodrigo Botafogo. All Rights Reserved. Permission to use, copy, modify,
7
+ # and distribute this software and its documentation, without fee and without a signed
8
+ # licensing agreement, is hereby granted, provided that the above copyright notice, this
9
+ # paragraph and the following two paragraphs appear in all copies, modifications, and
10
+ # distributions.
11
+ #
12
+ # IN NO EVENT SHALL RODRIGO BOTAFOGO BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
13
+ # INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
14
+ # THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RODRIGO BOTAFOGO HAS BEEN ADVISED OF THE
15
+ # POSSIBILITY OF SUCH DAMAGE.
16
+ #
17
+ # RODRIGO BOTAFOGO SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
19
+ # SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
20
+ # RODRIGO BOTAFOGO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
21
+ # OR MODIFICATIONS.
22
+ ##########################################################################################
23
+
24
+ class RbEngine < KnitrEngine
25
+ include Singleton
26
+
27
+ attr_reader :engine
28
+
29
+ #--------------------------------------------------------------------------------------
30
+ # Ruby engine for processing Ruby chunks
31
+ #--------------------------------------------------------------------------------------
32
+
33
+ def initialize
34
+
35
+ @engine = Proc.new do |options|
36
+
37
+ # the 'rb' engine has the code to be executed in the options.label
38
+ # argument
39
+ # options[['code']] = options[['label']]
40
+ options.code = options.label
41
+ # we do not want the code to be returned
42
+ options.echo = false
43
+
44
+ GalaazUtil.exec_ruby(options)
45
+
46
+ end
47
+
48
+ # Add the rb engine function for processing the rb block
49
+ add(rb: @engine)
50
+
51
+ end
52
+
53
+ end
54
+
55
+ rb_engine = RbEngine.instance
56
+
@@ -21,49 +21,26 @@
21
21
  # OR MODIFICATIONS.
22
22
  ##########################################################################################
23
23
 
24
- # Ruby engine for processing Ruby chunks
25
- eng_ruby = Proc.new do |options|
24
+ class RubyEngine < KnitrEngine
25
+ include Singleton
26
26
 
27
- begin
28
- # read the chunk code
29
- # code = R.paste(options.code, collapse: "\n") << 0
30
-
31
- # process the chunk options. Better to let interested methods process their
32
- # options
33
- KnitrEngine.process_options(options)
27
+ attr_reader :engine
34
28
 
35
- tmp_fig = R.tempfile()
36
-
37
- # opens a device for the current chunk for plot recording. Knitr provides
38
- # method chunck_device for that, but it is a non-exported method. Galaaz
39
- # does not yet provide a way to accessing non-exported methods, so, the ck_dv
40
- # local method was developed that just calls chunk_device.
41
- if (R._ck_dv(options.fig__width[1], options.fig__height[1], options.dev,
42
- options.dev__args, options.dpi, options, tmp_fig, record: true) << 0)
29
+ #--------------------------------------------------------------------------------------
30
+ # Ruby engine for processing Ruby chunks
31
+ #--------------------------------------------------------------------------------------
43
32
 
44
- # chunk requires library 'showtext'. Install and loads if not present
45
- # FIXME: library showtext is giving error when trying to execute showtext beginning
46
- if (!options[['fig.showtext']].is__null << 0) &&
47
- options[['fig.showtext']] << 0
48
- R.install_and_loads('showtext')
49
- R.showtext
50
- end
51
-
52
- dv = R.dev__cur
53
- end
54
-
55
- # executes the code
56
- res = GalaazUtil.exec_ruby(options)
33
+ def initialize
34
+
35
+ # call the RubyEngine initializer first so that @base_engine is defined
36
+ super
57
37
 
58
- # formats and outputs the code and results
59
- R.engine_output(options, out: res)
38
+ # Add the ruby engine function for processing the ruby block
39
+ add(ruby: @base_engine)
60
40
 
61
- ensure
62
- R.dev__off(dv)
63
41
  end
64
42
 
65
43
  end
66
44
 
67
- ruby_engine = KnitrEngine.new
68
- ruby_engine.add(ruby: eng_ruby)
45
+ ruby_engine = RubyEngine.instance
69
46
 
@@ -23,6 +23,52 @@
23
23
 
24
24
  require 'stringio'
25
25
 
26
+ #----------------------------------------------------------------------------------------
27
+ # Path StringIO puts... Already opened an issue in RC12
28
+ #----------------------------------------------------------------------------------------
29
+
30
+ class StringIO
31
+
32
+ def puts(*args)
33
+
34
+ if args.empty?
35
+ write(DEFAULT_RECORD_SEPARATOR)
36
+ else
37
+ args.each do |arg|
38
+
39
+ # method to_s is not being called when the output is diverted
40
+ # need to fix it
41
+ if (arg.is_a? R::Object)
42
+ arg = arg.to_s
43
+ end
44
+
45
+ if arg.nil?
46
+ line = ''
47
+ elsif Thread.guarding? arg
48
+ line = '[...]'
49
+ else
50
+ begin
51
+ arg = Truffle::Type.coerce_to(arg, Array, :to_ary)
52
+ Thread.recursion_guard arg do
53
+ arg.each { |a| puts a }
54
+ end
55
+ next
56
+ rescue
57
+ line = arg.to_s
58
+ end
59
+ end
60
+
61
+ write(line)
62
+ write(DEFAULT_RECORD_SEPARATOR) # unless line[-1] == ?\n
63
+ end
64
+ end
65
+
66
+ nil
67
+ end
68
+
69
+ end
70
+
71
+
26
72
  #----------------------------------------------------------------------------------------
27
73
  # Class RubyChunk is used only as a context for all ruby chunks in the rmarkdown file.
28
74
  # This allows for chunks to access instance_variables (@)
@@ -30,6 +76,18 @@ require 'stringio'
30
76
 
31
77
  class RubyChunk
32
78
 
79
+ def self.init
80
+ @@outputs = R.list
81
+ end
82
+
83
+ def self.get_outputs
84
+ @@outputs
85
+ end
86
+
87
+ def self.outputs(obj)
88
+ @@outputs = R.c(@@outputs, obj)
89
+ end
90
+
33
91
  end
34
92
 
35
93
  #----------------------------------------------------------------------------------------
@@ -53,39 +111,92 @@ module GalaazUtil
53
111
  # options[["eval"]], this is because eval is a Ruby function and doing options.eval
54
112
  # will call the eval method on options, which is not what we want
55
113
  #----------------------------------------------------------------------------------------
56
-
114
+
57
115
  def self.exec_ruby(options)
58
116
 
117
+ RubyChunk.init
118
+
59
119
  # read the chunk code
60
- code = R.paste(options.code, collapse: "\n") << 0
120
+ code = R.paste(options.code, collapse: "\n") >> 0
121
+
122
+ # the output should be a list with the proper structure to pass to
123
+ # function engine_output. We first add the souce code from the block to
124
+ # the list
125
+ out_list = R.list(R.structure(R.list(src: code), class: 'source')) if
126
+ options.echo >> 0
61
127
 
62
- out_list = R.list
63
- out_list["source"] = code if (options.echo << 0)
64
-
65
128
  begin
66
- # Set up standard output as a StringIO object.
129
+
130
+ # set $stdout to a new StringIO object so that everything that is
131
+ # output from instance_eval is captured and can be sent to the
132
+ # report
67
133
  $stdout = StringIO.new
68
- RubyChunk.instance_eval(code) if (options[["eval"]] << 0)
134
+
135
+ # Execute the Ruby code in the scope of class RubyChunk. This is done
136
+ # so that instance variables created in one chunk can be used again on
137
+ # another chunk
138
+ RubyChunk.instance_eval(code) if (options[["eval"]] >> 0)
139
+
140
+ # add the returned value to the list
141
+ # this should have captured everything in the evaluation code
142
+ # it is not working since at least RC10.
69
143
  out = $stdout.string
70
- # KnitrEngine.capture_plot
71
144
 
145
+ out_list = R.c(out_list, out)
146
+
147
+ rescue StandardError => e
148
+
149
+ # print the error message
150
+ if (options.message >> 0)
151
+ message = R.list(R.structure(R.list(message: e.message), class: 'message'))
152
+ out_list = R.c(out_list, message)
153
+ end
154
+
155
+ # Print the backtrace of the error message
156
+ if (options.warning >> 0)
157
+ bt = ""
158
+ e.backtrace.each { |line| bt << line + "\n"}
159
+ warning = R.list(R.structure(R.list(message: bt), class: 'message'))
160
+ out_list = R.c(out_list, warning)
161
+ end
162
+
163
+ rescue SyntaxError => e
164
+ STDERR.puts "A syntax error occured in ruby block '#{options.label >> 0}'"
165
+ raise SyntaxError.new(e)
166
+
167
+ ensure
72
168
  # return $stdout to standard output
73
169
  $stdout = STDOUT
74
- # return everything that was outputed
75
- out_list["text"] = out
76
- rescue StandardError => e
77
- out_list["message"] = e.message if (options.message << 0)
78
- out_list["warning"] = e.backtrace.inspect if (options.warning << 0)
79
170
  end
80
-
81
- # TODO: check the name of procedures since communication is
82
- # bidirectional. The name parse_arg was done thinking only on
83
- # the Ruby -> R direction.
84
- # exec_ruby returns its output to an R script, so we need to pass
85
- # the output (out_list) through parse_arg to make it available
86
- # to R.
87
- (options.include << 0)? R::Support.parse_arg(out_list) : nil
171
+
172
+ (options.include >> 0)? out_list : R.list
88
173
 
89
174
  end
175
+
176
+ #----------------------------------------------------------------------------------------
177
+ # Used by old gknit. Will eventually be replaced by exe_ruby
178
+ #----------------------------------------------------------------------------------------
179
+
180
+ def self.exec_ruby_tor(code)
181
+
182
+ # the output should be a list with the proper structure to pass to
183
+ # function engine_output.
184
+ out_list = R.list(R.structure(R.list(src: code), class: 'source'))
185
+
186
+ # Set up standard output as a StringIO object.
187
+ $stdout = StringIO.new
188
+ RubyChunk.instance_eval(code)
189
+
190
+ # this should have captured everything in the evaluation code
191
+ # it is not working since at least RC10.
192
+ out = $stdout.string
193
+
194
+ out_list = R.c(out_list, out)
195
+
196
+ # return $stdout to standard output
197
+ $stdout = STDOUT
198
+ R::Support.parse_arg(out_list)
90
199
 
200
+ end
201
+
91
202
  end
@@ -38,8 +38,8 @@ module GalaazUtil
38
38
 
39
39
  filename << ".rb" if File.extname(filename) == ""
40
40
  file = "#{pwd}/#{filename}"
41
-
42
- if (relative == 'require ')
41
+
42
+ if (relative == false)
43
43
  $LOAD_PATH.each do |path|
44
44
  begin
45
45
  files = Dir.entries(path)
@@ -47,13 +47,13 @@ module GalaazUtil
47
47
  next
48
48
  end
49
49
 
50
- if files != nil && files.include?("bigdecimal.rb")
50
+ if files != nil
51
51
  file = "#{path}/#{filename}"
52
- break
52
+ break if File.exist?(file)
53
53
  end
54
54
  end
55
55
  end
56
-
56
+
57
57
  if File.exist?(file)
58
58
  code = ""
59
59
  File.open(file, "r") do |fileObj|
@@ -61,10 +61,12 @@ module GalaazUtil
61
61
  code << line
62
62
  end
63
63
  end
64
- code
64
+
65
65
  else
66
- raise Errno::ENOENT, "file #{filename} not found"
66
+ raise Errno::ENOENT, "file #{filename} not found in #{$LOAD_PATH}"
67
67
  end
68
+
69
+ code
68
70
  end
69
71
 
70
72
  end
@@ -49,7 +49,12 @@ require_relative 'r_matrix.spec'
49
49
  # Specification for R::Dataframes
50
50
  require_relative 'r_dataframe.spec'
51
51
 
52
+ # Specification for language features
53
+ require_relative 'r_function.spec'
52
54
  require_relative 'r_formula.spec'
53
55
 
56
+ # Test file generation
57
+ require_relative 'r_devices.spec'
58
+
54
59
  # Testes for NSE
55
60
  # require_relative 'r_nse.spec'
Binary file
Binary file
@@ -0,0 +1,57 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' version='1.1' viewBox='0 0 506 506' style='fill:transparent'>
4
+ <g style='stroke-width:1.4226377952755906;stroke-linejoin:round;stroke-linecap:round'>
5
+ <rect x='0' y='0' width='506' height='506' style='stroke:#FFFFFF;fill:#FFFFFF'/>
6
+ <rect x='31' y='6' width='469' height='473' style='stroke:rgb(0,0,0);stroke-opacity:0.000;fill:#EBEBEB'/>
7
+ </g><g style='stroke-width:0.7113188976377953;stroke-linejoin:round;stroke-linecap:butt'>
8
+ <polyline points='31,446 500,446' style='stroke:#FFFFFF'/>
9
+ <polyline points='31,301 500,301' style='stroke:#FFFFFF'/>
10
+ <polyline points='31,156 500,156' style='stroke:#FFFFFF'/>
11
+ <polyline points='31,11 500,11' style='stroke:#FFFFFF'/>
12
+ </g><g style='stroke-width:1.4226377952755906;stroke-linejoin:round;stroke-linecap:butt'>
13
+ <polyline points='31,373 500,373' style='stroke:#FFFFFF'/>
14
+ <polyline points='31,228 500,228' style='stroke:#FFFFFF'/>
15
+ <polyline points='31,84 500,84' style='stroke:#FFFFFF'/>
16
+ <polyline points='119,479 119,6' style='stroke:#FFFFFF'/>
17
+ <polyline points='266,479 266,6' style='stroke:#FFFFFF'/>
18
+ <polyline points='412,479 412,6' style='stroke:#FFFFFF'/>
19
+ </g><g style='stroke-width:0.9448818897637796;stroke-linejoin:round;stroke-linecap:round'>
20
+ <circle cx='119' cy='207' r='2' style='stroke:#333333;fill:#333333'/>
21
+ </g><g style='stroke-width:1.4226377952755906;stroke-linejoin:round;stroke-linecap:butt'>
22
+ <polyline points='119,341 119,263' style='stroke:#333333'/>
23
+ <polyline points='119,413 119,457' style='stroke:#333333'/>
24
+ </g><g style='stroke-width:1.4226377952755906;stroke-linejoin:round;stroke-linecap:round'>
25
+ <polyline points='64,341 64,413 174,413 174,341 64,341 64,341' style='stroke:#333333;fill:#FFFFFF'/>
26
+ </g><g style='stroke-width:2.8452755905511813;stroke-linejoin:round;stroke-linecap:butt'>
27
+ <polyline points='64,375 174,375' style='stroke:#333333'/>
28
+ </g><g style='stroke-width:1.4226377952755906;stroke-linejoin:round;stroke-linecap:butt'>
29
+ <polyline points='266,180 266,123' style='stroke:#333333'/>
30
+ <polyline points='266,283 266,321' style='stroke:#333333'/>
31
+ </g><g style='stroke-width:1.4226377952755906;stroke-linejoin:round;stroke-linecap:round'>
32
+ <polyline points='211,180 211,283 321,283 321,180 211,180 211,180' style='stroke:#333333;fill:#FFFFFF'/>
33
+ </g><g style='stroke-width:2.8452755905511813;stroke-linejoin:round;stroke-linecap:butt'>
34
+ <polyline points='211,239 321,239' style='stroke:#333333'/>
35
+ </g><g style='stroke-width:1.4226377952755906;stroke-linejoin:round;stroke-linecap:butt'>
36
+ <polyline points='412,115 412,27' style='stroke:#333333'/>
37
+ <polyline points='412,177 412,250' style='stroke:#333333'/>
38
+ </g><g style='stroke-width:1.4226377952755906;stroke-linejoin:round;stroke-linecap:round'>
39
+ <polyline points='358,115 358,177 467,177 467,115 358,115 358,115' style='stroke:#333333;fill:#FFFFFF'/>
40
+ </g><g style='stroke-width:2.8452755905511813;stroke-linejoin:round;stroke-linecap:butt'>
41
+ <polyline points='358,142 467,142' style='stroke:#333333'/>
42
+ </g><text x='16' y='376' lengthAdjust='spacingAndGlyphs' textLength='11px' style='font-size:8.8px;fill:#4D4D4D'>10</text>
43
+ <text x='16' y='231' lengthAdjust='spacingAndGlyphs' textLength='11px' style='font-size:8.8px;fill:#4D4D4D'>20</text>
44
+ <text x='16' y='87' lengthAdjust='spacingAndGlyphs' textLength='11px' style='font-size:8.8px;fill:#4D4D4D'>30</text>
45
+ <g style='stroke-width:1.4226377952755906;stroke-linejoin:round;stroke-linecap:butt'>
46
+ <polyline points='29,373 31,373' style='stroke:#333333'/>
47
+ <polyline points='29,228 31,228' style='stroke:#333333'/>
48
+ <polyline points='29,84 31,84' style='stroke:#333333'/>
49
+ <polyline points='119,482 119,479' style='stroke:#333333'/>
50
+ <polyline points='266,482 266,479' style='stroke:#333333'/>
51
+ <polyline points='412,482 412,479' style='stroke:#333333'/>
52
+ </g><text x='111' y='490' lengthAdjust='spacingAndGlyphs' textLength='16px' style='font-size:8.8px;fill:#4D4D4D'>0.5</text>
53
+ <text x='263' y='490' lengthAdjust='spacingAndGlyphs' textLength='5px' style='font-size:8.8px;fill:#4D4D4D'>1</text>
54
+ <text x='410' y='490' lengthAdjust='spacingAndGlyphs' textLength='5px' style='font-size:8.8px;fill:#4D4D4D'>2</text>
55
+ <text x='253' y='500' lengthAdjust='spacingAndGlyphs' textLength='26px' style='font-size:11.0px;fill:#000000'>dose</text>
56
+ <text x='13' y='252' lengthAdjust='spacingAndGlyphs' textLength='20px' style='font-size:11.0px;fill:#000000' transform='rotate(-90,13,252)'>len</text>
57
+ </svg>
Binary file
@@ -0,0 +1,57 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' version='1.1' viewBox='0 0 506 506' style='fill:transparent'>
4
+ <g style='stroke-width:1.4226377952755906;stroke-linejoin:round;stroke-linecap:round'>
5
+ <rect x='0' y='0' width='506' height='506' style='stroke:#FFFFFF;fill:#FFFFFF'/>
6
+ <rect x='31' y='6' width='469' height='473' style='stroke:rgb(0,0,0);stroke-opacity:0.000;fill:#EBEBEB'/>
7
+ </g><g style='stroke-width:0.7113188976377953;stroke-linejoin:round;stroke-linecap:butt'>
8
+ <polyline points='31,446 500,446' style='stroke:#FFFFFF'/>
9
+ <polyline points='31,301 500,301' style='stroke:#FFFFFF'/>
10
+ <polyline points='31,156 500,156' style='stroke:#FFFFFF'/>
11
+ <polyline points='31,11 500,11' style='stroke:#FFFFFF'/>
12
+ </g><g style='stroke-width:1.4226377952755906;stroke-linejoin:round;stroke-linecap:butt'>
13
+ <polyline points='31,373 500,373' style='stroke:#FFFFFF'/>
14
+ <polyline points='31,228 500,228' style='stroke:#FFFFFF'/>
15
+ <polyline points='31,84 500,84' style='stroke:#FFFFFF'/>
16
+ <polyline points='119,479 119,6' style='stroke:#FFFFFF'/>
17
+ <polyline points='266,479 266,6' style='stroke:#FFFFFF'/>
18
+ <polyline points='412,479 412,6' style='stroke:#FFFFFF'/>
19
+ </g><g style='stroke-width:0.9448818897637796;stroke-linejoin:round;stroke-linecap:round'>
20
+ <circle cx='119' cy='207' r='2' style='stroke:#333333;fill:#333333'/>
21
+ </g><g style='stroke-width:1.4226377952755906;stroke-linejoin:round;stroke-linecap:butt'>
22
+ <polyline points='119,341 119,263' style='stroke:#333333'/>
23
+ <polyline points='119,413 119,457' style='stroke:#333333'/>
24
+ </g><g style='stroke-width:1.4226377952755906;stroke-linejoin:round;stroke-linecap:round'>
25
+ <polyline points='64,341 64,413 174,413 174,341 64,341 64,341' style='stroke:#333333;fill:#FFFFFF'/>
26
+ </g><g style='stroke-width:2.8452755905511813;stroke-linejoin:round;stroke-linecap:butt'>
27
+ <polyline points='64,375 174,375' style='stroke:#333333'/>
28
+ </g><g style='stroke-width:1.4226377952755906;stroke-linejoin:round;stroke-linecap:butt'>
29
+ <polyline points='266,180 266,123' style='stroke:#333333'/>
30
+ <polyline points='266,283 266,321' style='stroke:#333333'/>
31
+ </g><g style='stroke-width:1.4226377952755906;stroke-linejoin:round;stroke-linecap:round'>
32
+ <polyline points='211,180 211,283 321,283 321,180 211,180 211,180' style='stroke:#333333;fill:#FFFFFF'/>
33
+ </g><g style='stroke-width:2.8452755905511813;stroke-linejoin:round;stroke-linecap:butt'>
34
+ <polyline points='211,239 321,239' style='stroke:#333333'/>
35
+ </g><g style='stroke-width:1.4226377952755906;stroke-linejoin:round;stroke-linecap:butt'>
36
+ <polyline points='412,115 412,27' style='stroke:#333333'/>
37
+ <polyline points='412,177 412,250' style='stroke:#333333'/>
38
+ </g><g style='stroke-width:1.4226377952755906;stroke-linejoin:round;stroke-linecap:round'>
39
+ <polyline points='358,115 358,177 467,177 467,115 358,115 358,115' style='stroke:#333333;fill:#FFFFFF'/>
40
+ </g><g style='stroke-width:2.8452755905511813;stroke-linejoin:round;stroke-linecap:butt'>
41
+ <polyline points='358,142 467,142' style='stroke:#333333'/>
42
+ </g><text x='16' y='376' lengthAdjust='spacingAndGlyphs' textLength='11px' style='font-size:8.8px;fill:#4D4D4D'>10</text>
43
+ <text x='16' y='231' lengthAdjust='spacingAndGlyphs' textLength='11px' style='font-size:8.8px;fill:#4D4D4D'>20</text>
44
+ <text x='16' y='87' lengthAdjust='spacingAndGlyphs' textLength='11px' style='font-size:8.8px;fill:#4D4D4D'>30</text>
45
+ <g style='stroke-width:1.4226377952755906;stroke-linejoin:round;stroke-linecap:butt'>
46
+ <polyline points='29,373 31,373' style='stroke:#333333'/>
47
+ <polyline points='29,228 31,228' style='stroke:#333333'/>
48
+ <polyline points='29,84 31,84' style='stroke:#333333'/>
49
+ <polyline points='119,482 119,479' style='stroke:#333333'/>
50
+ <polyline points='266,482 266,479' style='stroke:#333333'/>
51
+ <polyline points='412,482 412,479' style='stroke:#333333'/>
52
+ </g><text x='111' y='490' lengthAdjust='spacingAndGlyphs' textLength='16px' style='font-size:8.8px;fill:#4D4D4D'>0.5</text>
53
+ <text x='263' y='490' lengthAdjust='spacingAndGlyphs' textLength='5px' style='font-size:8.8px;fill:#4D4D4D'>1</text>
54
+ <text x='410' y='490' lengthAdjust='spacingAndGlyphs' textLength='5px' style='font-size:8.8px;fill:#4D4D4D'>2</text>
55
+ <text x='253' y='500' lengthAdjust='spacingAndGlyphs' textLength='26px' style='font-size:11.0px;fill:#000000'>dose</text>
56
+ <text x='13' y='252' lengthAdjust='spacingAndGlyphs' textLength='20px' style='font-size:11.0px;fill:#000000' transform='rotate(-90,13,252)'>len</text>
57
+ </svg>