Support for dashed lines in various patterns #10

Merged
merged 13 commits into from Jul 10, 2013
View
@@ -106,6 +106,8 @@ lib/rubyvis/scene/svg_wedge.rb
lib/rubyvis/sceneelement.rb
lib/rubyvis/transform.rb
lib/rubyvis/vector.rb
+lib/rspec/expectations/differ.rb
+lib/rspec/expectations/differ_spec.rb
spec/anchor_spec.rb
spec/area_spec.rb
spec/bar_spec.rb
View
@@ -7,16 +7,18 @@ require 'hoe'
require 'rubyvis'
require 'rspec'
require 'rspec/core/rake_task'
+require './lib/rspec/expectations/differ'
require 'rubyforge'
Hoe.plugin :git
+Hoe.plugin :gemspec
h=Hoe.spec 'rubyvis' do
self.testlib=:rspec
self.rspec_options << "-c" << "-b"
self.developer('Claudio Bustos', 'clbustos_at_gmail.com')
self.version=Rubyvis::VERSION
- self.extra_dev_deps << ["coderay",">=0"] << ["haml",">=0"] << ["nokogiri", ">=0"] << ["rspec",">=2.0"] << ["RedCloth",">=0"]
+ self.extra_dev_deps << ["coderay",">=0"] << ["haml",">=0"] << ["nokogiri", ">=0"] << ["rspec",">=2.7"] << ["RedCloth",">=0"]
end
desc "Publicar docs en rubyforge"
task :publicar_docs => [:clean, :docs] do
@@ -0,0 +1,73 @@
+# Borrowed from:
+# https://github.com/pcreux/rspec-expectations/commit/b5f8d5ab7c9a3e8d470c6ec3241179be0b78f3ac#diff-1
+
+require 'diff/lcs'
+require 'diff/lcs/hunk'
+require 'pp'
+
+module RSpec
+ module Expectations
+ class Differ
+
+
+ # This is snagged from diff/lcs/ldiff.rb (which is a commandline tool)
+ def diff_as_string(data_new, data_old)
+ data_old = data_old.split(/\n/).map! { |e| e.chomp }
+ data_new = data_new.split(/\n/).map! { |e| e.chomp }
+ output = ""
+ diffs = Diff::LCS.diff(data_old, data_new)
+ return output if diffs.empty?
+ oldhunk = hunk = nil
+ file_length_difference = 0
+ diffs.each do |piece|
+ begin
+ hunk = Diff::LCS::Hunk.new(
+ data_old, data_new, piece, context_lines, file_length_difference
+ )
+ file_length_difference = hunk.file_length_difference
+ next unless oldhunk
+ # Hunks may overlap, which is why we need to be careful when our
+ # diff includes lines of context. Otherwise, we might print
+ # redundant lines.
+ if (context_lines > 0) and hunk.overlaps?(oldhunk)
+ hunk.unshift(oldhunk)
+ else
+ output << oldhunk.diff(format)
+ end
+ ensure
+ oldhunk = hunk
+ output << "\n"
+ end
+ end
+ #Handle the last remaining hunk
+ output << oldhunk.diff(format) << "\n"
+ end
+
+
+ def diff_as_object(actual,expected)
+ actual = object_to_string(actual)
+ expected = object_to_string(expected)
+ diff_as_string(actual, expected)
+ end
+
+ protected
+
+ def format; :unified; end
+ def context_lines; 3; end
+
+ def object_to_string(object)
+ case object
+ when Hash
+ object.keys.sort_by { |k| k.to_s }.map do |k|
+ %(#{PP.singleline_pp(k, "")} => #{PP.singleline_pp(object[k], "")})
+ end.join(",\n")
+ when String
+ object
+ else
+ PP.pp(object,"")
+ end
+ end
+
+ end
+ end
+end
@@ -0,0 +1,117 @@
+require 'spec_helper'
+require 'ostruct'
+
+module RSpec
+ module Fixtures
+ class Animal
+ def initialize(name,species)
+ @name,@species = name,species
+ end
+
+ def inspect
+ <<-EOA
+<Animal
+ name=#{@name},
+ species=#{@species}
+>
+ EOA
+ end
+ end
+ end
+end
+
+describe "Diff" do
+ before(:each) do
+ @options = OpenStruct.new(:diff_format => :unified, :context_lines => 3)
+ @differ = RSpec::Expectations::Differ.new(@options)
+ end
+
+ it "outputs unified diff of two strings" do
+ expected="foo\nbar\nzap\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nline\n"
+ actual="foo\nzap\nbar\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nanother\nline\n"
+ expected_diff= <<'EOD'
+
+
+@@ -1,6 +1,6 @@
+ foo
+-zap
+ bar
++zap
+ this
+ is
+ soo
+@@ -9,6 +9,5 @@
+ equal
+ insert
+ a
+-another
+ line
+EOD
+
+ diff = @differ.diff_as_string(expected, actual)
+ diff.should eql(expected_diff)
+ end
+
+ it "outputs unified diff message of two arrays" do
+ expected = [ :foo, 'bar', :baz, 'quux', :metasyntactic, 'variable', :delta, 'charlie', :width, 'quite wide' ]
+ actual = [ :foo, 'bar', :baz, 'quux', :metasyntactic, 'variable', :delta, 'tango' , :width, 'very wide' ]
+
+ expected_diff = <<'EOD'
+
+
+@@ -5,7 +5,7 @@
+ :metasyntactic,
+ "variable",
+ :delta,
+- "tango",
++ "charlie",
+ :width,
+- "very wide"]
++ "quite wide"]
+EOD
+
+
+ diff = @differ.diff_as_object(expected,actual)
+ diff.should == expected_diff
+ end
+
+ it "outputs unified diff message of two objects" do
+ expected = RSpec::Fixtures::Animal.new "bob", "giraffe"
+ actual = RSpec::Fixtures::Animal.new "bob", "tortoise"
+
+ expected_diff = <<'EOD'
+
+@@ -1,5 +1,5 @@
+ <Animal
+ name=bob,
+- species=tortoise
++ species=giraffe
+ >
+EOD
+
+ diff = @differ.diff_as_object(expected,actual)
+ diff.should == expected_diff
+ end
+
+ it "outputs unified diff message of two hashes" do
+ expected = { :foo => 'bar', :baz => 'quux', :metasyntactic => 'variable', :delta => 'charlie', :width =>'quite wide' }
+ actual = { :foo => 'bar', :metasyntactic => 'variable', :delta => 'charlotte', :width =>'quite wide' }
+
+ expected_diff = <<'EOD'
+
+@@ -1,4 +1,5 @@
+-:delta => "charlotte",
++:baz => "quux",
++:delta => "charlie",
+ :foo => "bar",
+ :metasyntactic => "variable",
+ :width => "quite wide"
+EOD
+
+
+ diff = @differ.diff_as_object(expected,actual)
+ diff.should == expected_diff
+ end
+
+end
+
View
@@ -67,7 +67,7 @@ def self.xml_engine
if has_nokogiri? and !$rubyvis_no_nokogiri
:nokogiri
else
- puts "rexml"
+
:rexml
end
end
View
@@ -12,6 +12,7 @@ def fixed
:stroke_style=> true,
:fill_style=> true,
:segmented=> true,
+ :stroke_dasharray => true, # SVG strokeDasharray (Jamie Love protovis mod)
:interpolate=> true,
:tension=> true
}
@@ -201,7 +202,7 @@ class Area < Mark
- attr_accessor_dsl :width, :height, :line_width, [:stroke_style, lambda {|d| Rubyvis.color(d)}], [:fill_style, lambda {|d| Rubyvis.color(d)}], :segmented, :interpolate, :tension
+ attr_accessor_dsl :width, :height, :line_width, [:stroke_style, lambda {|d| Rubyvis.color(d)}], [:fill_style, lambda {|d| Rubyvis.color(d)}], :segmented, :stroke_dasharray, :interpolate, :tension
def type
'area'
end
@@ -219,7 +220,7 @@ def anchor(name)
area_anchor(name)
end
def build_implied(s)
- s.heigth=0 if s.height.nil?
+ s.height=0 if s.height.nil?
s.width=0 if s.width.nil?
mark_build_implied(s)
end
View
@@ -73,7 +73,13 @@ class Line < Mark
# Whether the line is segmented; whether variations in stroke style, line width and the other properties are treated as fixed. Rendering segmented lines is noticeably slower than non-segmented lines.
# <p>This property is <i>fixed</i>. See Rubyvis.Mark
+
+ ##
+ # :attr: stroke_dasharray
+ # Whether the line is dashed using the strokeDasharray SVG property.
+ # <p>This property is <i>fixed</i>. See Rubyvis.Mark
+
##
# :attr: interpolate
# How to interpolate between values. Linear interpolation ("linear") is the
@@ -105,7 +111,7 @@ class Line < Mark
#
# <p>This property is <i>fixed</i>. See Rubyvis.Mark
- attr_accessor_dsl :line_width, :line_join, [:stroke_style, lambda {|d| Rubyvis.color(d)}], [:fill_style, lambda {|d| Rubyvis.color(d)}], :segmented, :interpolate, :eccentricity, :tension
+ attr_accessor_dsl :line_width, :line_join, [:stroke_style, lambda {|d| Rubyvis.color(d)}], [:fill_style, lambda {|d| Rubyvis.color(d)}], :stroke_dasharray, :segmented, :interpolate, :eccentricity, :tension
# Type of line
def type
"line"
@@ -146,7 +152,14 @@ def build_instance(*args) # :nodoc:
def self.defaults
a=Rubyvis::Colors.category10()
- Line.new.mark_extend(Mark.defaults).line_join('miter').line_width(1.5).stroke_style( lambda { a.scale(parent.index)}).interpolate('linear').eccentricity(0).tension(0.7)
+ Line.new.mark_extend(Mark.defaults).
+ line_join('miter').
+ line_width(1.5).
+ stroke_style( lambda { a.scale(parent.index)}).
+ stroke_dasharray('').
+ interpolate('linear').
+ eccentricity(0).
+ tension(0.7)
end
end
end
View
@@ -6,7 +6,7 @@ def self.Rule
class Rule < Mark
include LinePrototype
@properties=Mark.properties.dup
- attr_accessor_dsl :width, :height, :line_width, [:stroke_style, lambda {|d| Rubyvis.color(d)}]
+ attr_accessor_dsl :width, :height, :line_width, [:stroke_style, lambda {|d| Rubyvis.color(d)}], :stroke_dasharray
def self.defaults
Rule.new.mark_extend(Mark.defaults).line_width(1).stroke_style('black').antialias(false)
end
@@ -43,6 +43,7 @@ def self.line(scenes)
"fill-opacity"=> (fill.opacity==0.0) ? nil : fill.opacity,
"stroke"=> stroke.color,
"stroke-opacity"=> (stroke.opacity==0.0) ? nil : stroke.opacity,
+ "stroke-dasharray"=> s.stroke_dasharray, # strokeDasharray from Jamie Love (protovis mod)
"stroke-width"=> (stroke.opacity>0) ? s.line_width / self.scale : nil,
"stroke-linejoin"=> s.line_join
});
@@ -17,6 +17,7 @@ def self.rule(scenes)
'y2'=>s.top+s.height,
"stroke"=> stroke.color,
"stroke-opacity"=> stroke.opacity,
+ "stroke-dasharray"=> s.stroke_dasharray,
"stroke-width"=> s.line_width / self.scale
})
@@ -38,7 +38,7 @@ def set_attributes(h)
end
end
def get_element(i)
- elements[i-1]
+ elements.empty? ? nil : elements[i-1]
end
#private :elements
#private :attributes
@@ -8,7 +8,7 @@ def initialize
end
include Enumerable
attr_accessor :visible
- attr_accessor :mark, :type, :child_index, :parent, :parent_index, :target, :defs, :data, :antialias, :line_width, :fill_style, :overflow, :width, :height, :top, :bottom, :left, :right, :title, :reverse, :stroke_style, :transform, :canvas, :_g, :events, :cursor, :children, :id, :segmented, :interpolate, :tension, :name, :text_baseline, :text_align, :text, :font, :text_angle, :text_style, :text_margin, :text_decoration, :text_shadow, :line_join, :eccentricity, :shape_size, :shape, :shape_angle, :shape_radius, :start_angle, :end_angle, :angle, :inner_radius, :outer_radius, :layers, :orient, :offset, :order,:url, :image_width, :image_height, :image, :_id, :nodes, :round, :links, :padding_left, :padding_right, :padding_top, :padding_bottom, :mode, :group, :depth, :breadth, :spacing, :rows, :cols, :_grid,:bands, :background_style, :positive_style, :negative_style,:directed, :_matrix
+ attr_accessor :mark, :type, :child_index, :parent, :parent_index, :target, :defs, :data, :antialias, :line_width, :fill_style, :overflow, :width, :height, :top, :bottom, :left, :right, :title, :reverse, :stroke_style, :transform, :canvas, :_g, :events, :cursor, :children, :id, :segmented, :stroke_dasharray, :interpolate, :tension, :name, :text_baseline, :text_align, :text, :font, :text_angle, :text_style, :text_margin, :text_decoration, :text_shadow, :line_join, :eccentricity, :shape_size, :shape, :shape_angle, :shape_radius, :start_angle, :end_angle, :angle, :inner_radius, :outer_radius, :layers, :orient, :offset, :order,:url, :image_width, :image_height, :image, :_id, :nodes, :round, :links, :padding_left, :padding_right, :padding_top, :padding_bottom, :mode, :group, :depth, :breadth, :spacing, :rows, :cols, :_grid,:bands, :background_style, :positive_style, :negative_style,:directed, :_matrix
def []=(v,i)
if v.is_a? Numeric
View
@@ -1,8 +1,9 @@
+require File.expand_path(File.dirname(__FILE__)+"/../lib/rspec/expectations/differ.rb")
require File.expand_path(File.dirname(__FILE__)+"/spec_helper.rb")
describe Rubyvis::Area do
include Rubyvis::GeneralSpec
it "should have correct properties" do
- props=[:antialias, :bottom, :cursor, :data, :events, :fill_style, :height, :id, :interpolate, :left, :line_width, :reverse, :right, :segmented, :stroke_style, :tension, :title, :top, :visible, :width].inject({}) {|ac, v| ac[v]=true; ac}
+ props=[:antialias, :bottom, :cursor, :data, :events, :fill_style, :height, :id, :interpolate, :left, :line_width, :reverse, :right, :segmented, :stroke_dasharray, :stroke_style, :tension, :title, :top, :visible, :width].inject({}) {|ac, v| ac[v]=true; ac}
Rubyvis::Area.properties.should==props
end
it "Rubyvis.Area be the same as Rubyvis::Area" do
@@ -140,4 +141,4 @@
doc.at_xpath("//xmlns:path").should have_path_data_close_to "M0 180Q16 160 20 160C26 160 34 186 40 180S54 120 60 120S74 183 80 180Q84 178 100 100L100 200Q84 200 80 200C74 200 66 200 60 200S46 200 40 200S26 200 20 200Q16 200 0 200Z"
end
end
-end
+end
View
@@ -117,7 +117,7 @@
it "method median returns median of values" do
Rubyvis.median([1,2,4,3]).should==2.5
Rubyvis.median([1,3,2,5,3]).should==3
- Rubyvis.median([1,3,2,5,3].map(&:to_s), lambda(&:to_f)).should==3
+ Rubyvis.median([1,3,2,5,3].map {|v| v.to_s}, lambda {|v| v.to_f}).should==3
end
it "method variance returns sum of squares" do
Rubyvis.variance([5,7,9,11]).should==20
@@ -148,4 +148,4 @@
end
end
-end
+end
Oops, something went wrong.