lib/flammarion/plot.rb in flammarion-0.2.1 vs lib/flammarion/plot.rb in flammarion-0.3.0
- old
+ new
@@ -1,117 +1,117 @@
-module Flammarion
-
- # A representation of a plot in an engraving
- class Plot
- attr_reader :engraving
-
- # Creates a plot with it's own engraving.
- # @overload initialize()
- # @example
- # p = Flammarion::Plot.new
- # p.plot([1,2,3,4])
- # p.plot([5,6,7])
- # @overload initialize(i,t,e)
- # @api private
- def initialize(*args)
- if args.size == 0 then
- @engraving = Engraving.new
- @id = @engraving.make_id
- @target = "default"
- elsif args.size == 3 then
- id, target, engraving = args
- @id = id
- @target = target
- @engraving = engraving
- else
- raise ArgumentError.new("ArgumentError: wrong number of arguments (#{args.size} for 0 or 3)")
- end
- end
-
- # Plots data to this current plot. If it has previously been plotted, this
- # plot will be overwritten. If you want to add a new plot to an engraving,
- # then use +Flammarion::Writeable.plot+.
- # @see https://plot.ly/javascript/
- # @return [Plot] A Plot object for manipulation after creation.
- # @overload plot(array, options = {})
- # @param [Array<Number>] values A list of numbers to plot
- # @example
- # f.plot([1,3,4,2])
- # @example
- # f.plot(100.times.map{rand}, mode: 'markers')
- # @overload plot(dataset, options = {})
- # @param [Hash] A hash representing a Plotly trace
- # @example
- # f.plot(x: (1..314).to_a.map{|x| Math.sin(x.to_f / 20.0)}, y:(1..314).to_a.map{|x| Math.sin(x.to_f / 10)}, replace:true)
- # @example
- # f.plot(x: [Time.now, Time.now + 24*60*60].map(&:to_s), y: [55, 38], type:'bar', replace:true)
- # @overload plot(datasets, options = {})
- # @param [Array<Hash>] An array of Plotly traces
- # @example
- # f.plot(5.times.map{|t| {x: 100.times.to_a, y: 100.times.map{rand * t}, name: "Trace #{t}"}}, xaxis: {title: "A non-random number"}, yaxis: {title: "A random number"})
- def plot(data, options = {})
- if data.respond_to?(:keys)
- options = options.merge(data)
- if data.include?(:xy) then
- data = data.clone
- data[:x] = data[:xy].map(&:first)
- data[:y] = data[:xy].map(&:last)
- data.delete(:xy)
- end
- data = [data]
- elsif not data.first.respond_to?(:keys)
- data = [{y:data, x:(1..data.size).to_a}.merge(options)]
- end
- @engraving.send_json({action:'plot', id:@id, target:@target, data:data}.merge(options))
- end
-
- # Changes the layout of an already existing plot.
- # @see https://plot.ly/javascript/#layout-options
- def layout(options)
- @engraving.send_json({action:'plot', id:@id, target: @target, layout: options})
- end
-
- # Saves the plot as a static image. +block+ will be called with a hash
- # argurment when the plot is finished being converted to an image
- def save(options = {}, &block)
- id = @engraving.make_id
- @engraving.callbacks[id] = block
- @engraving.send_json({action:'savePlot', id:@id, target:@target, callback_id: id, format: options})
- end
-
- # Converts the plot to a png image. If a block is given, it will be called
- # with the png data. Otherwise this function will wait until the image has
- # been created, and then return a string containing the png data
- def to_png(options = {})
- png = nil
- save(options.merge({format: 'png'})) do |data|
- d = data['data']
- png = Base64.decode64(d[d.index(',') + 1..-1])
- if block_given?
- yield png
- end
- end
- unless block_given?
- sleep 0.1 while png.nil?
- return png
- end
- end
-
- # Converts the plot to an svg image. If a block is given, it will be called
- # with the svg xml string. Otherwise this function will wait until the image has
- # been created, and then return a string containing the svg xml string
- def to_svg(options = {})
- svg = nil
- save(options.merge({format: 'svg'})) do |data|
- d = data['data']
- svg = URI.unescape(d[d.index(',') + 1 .. -1])
- if block_given?
- yield svg
- end
- end
- unless block_given?
- sleep 0.1 while svg.nil?
- return svg
- end
- end
- end
-end
+module Flammarion
+
+ # A representation of a plot in an engraving
+ class Plot
+ attr_reader :engraving
+
+ # Creates a plot with it's own engraving.
+ # @overload initialize()
+ # @example
+ # p = Flammarion::Plot.new
+ # p.plot([1,2,3,4])
+ # p.plot([5,6,7])
+ # @overload initialize(i,t,e)
+ # @api private
+ def initialize(*args)
+ if args.size == 0 then
+ @engraving = Engraving.new
+ @id = @engraving.make_id
+ @target = "default"
+ elsif args.size == 3 then
+ id, target, engraving = args
+ @id = id
+ @target = target
+ @engraving = engraving
+ else
+ raise ArgumentError.new("ArgumentError: wrong number of arguments (#{args.size} for 0 or 3)")
+ end
+ end
+
+ # Plots data to this current plot. If it has previously been plotted, this
+ # plot will be overwritten. If you want to add a new plot to an engraving,
+ # then use +Flammarion::Writeable.plot+.
+ # @see https://plot.ly/javascript/
+ # @return [Plot] A Plot object for manipulation after creation.
+ # @overload plot(array, options = {})
+ # @param [Array<Number>] values A list of numbers to plot
+ # @example
+ # f.plot([1,3,4,2])
+ # @example
+ # f.plot(100.times.map{rand}, mode: 'markers')
+ # @overload plot(dataset, options = {})
+ # @param [Hash] A hash representing a Plotly trace
+ # @example
+ # f.plot(x: (1..314).to_a.map{|x| Math.sin(x.to_f / 20.0)}, y:(1..314).to_a.map{|x| Math.sin(x.to_f / 10)}, replace:true)
+ # @example
+ # f.plot(x: [Time.now, Time.now + 24*60*60].map(&:to_s), y: [55, 38], type:'bar', replace:true)
+ # @overload plot(datasets, options = {})
+ # @param [Array<Hash>] An array of Plotly traces
+ # @example
+ # f.plot(5.times.map{|t| {x: 100.times.to_a, y: 100.times.map{rand * t}, name: "Trace #{t}"}}, xaxis: {title: "A non-random number"}, yaxis: {title: "A random number"})
+ def plot(data, options = {})
+ if data.respond_to?(:keys)
+ options = options.merge(data)
+ if data.include?(:xy) then
+ data = data.clone
+ data[:x] = data[:xy].map(&:first)
+ data[:y] = data[:xy].map(&:last)
+ data.delete(:xy)
+ end
+ data = [data]
+ elsif not data.first.respond_to?(:keys)
+ data = [{y:data, x:(1..data.size).to_a}.merge(options)]
+ end
+ @engraving.send_json({action:'plot', id:@id, target:@target, data:data}.merge(options))
+ end
+
+ # Changes the layout of an already existing plot.
+ # @see https://plot.ly/javascript/#layout-options
+ def layout(options)
+ @engraving.send_json({action:'plot', id:@id, target: @target, layout: options})
+ end
+
+ # Saves the plot as a static image. +block+ will be called with a hash
+ # argurment when the plot is finished being converted to an image
+ def save(options = {}, &block)
+ id = @engraving.make_id
+ @engraving.callbacks[id] = block
+ @engraving.send_json({action:'savePlot', id:@id, target:@target, callback_id: id, format: options})
+ end
+
+ # Converts the plot to a png image. If a block is given, it will be called
+ # with the png data. Otherwise this function will wait until the image has
+ # been created, and then return a string containing the png data
+ def to_png(options = {})
+ png = nil
+ save(options.merge({format: 'png'})) do |data|
+ d = data['data']
+ png = Base64.decode64(d[d.index(',') + 1..-1])
+ if block_given?
+ yield png
+ end
+ end
+ unless block_given?
+ sleep 0.1 while png.nil?
+ return png
+ end
+ end
+
+ # Converts the plot to an svg image. If a block is given, it will be called
+ # with the svg xml string. Otherwise this function will wait until the image has
+ # been created, and then return a string containing the svg xml string
+ def to_svg(options = {})
+ svg = nil
+ save(options.merge({format: 'svg'})) do |data|
+ d = data['data']
+ svg = URI.unescape(d[d.index(',') + 1 .. -1])
+ if block_given?
+ yield svg
+ end
+ end
+ unless block_given?
+ sleep 0.1 while svg.nil?
+ return svg
+ end
+ end
+ end
+end