opal-d3 0.0.20170205

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/Gemfile +3 -0
  4. data/README.md +7 -0
  5. data/Rakefile +31 -0
  6. data/d3.js +16393 -0
  7. data/demo/Gemfile +4 -0
  8. data/demo/README.md +7 -0
  9. data/demo/app/data/elections_2016.rb +10 -0
  10. data/demo/app/data/harry_potter.rb +19 -0
  11. data/demo/app/data/iphones.rb +29 -0
  12. data/demo/app/data/london_population.rb +26 -0
  13. data/demo/app/data/man_vs_horse.rb +55 -0
  14. data/demo/app/data/mtg_modern_colors.rb +96 -0
  15. data/demo/app/data/mtg_modern_creatures.rb +116 -0
  16. data/demo/app/data/olympics_2016_medals.rb +100 -0
  17. data/demo/app/data/paradox.rb +60 -0
  18. data/demo/app/data/polish_pms.rb +28 -0
  19. data/demo/app/data/star_trek_voyager.rb +183 -0
  20. data/demo/app/data/weather_in_london.rb +381 -0
  21. data/demo/app/elections_2016.rb +19 -0
  22. data/demo/app/harry_potter.rb +35 -0
  23. data/demo/app/iphones.rb +47 -0
  24. data/demo/app/london_population.rb +46 -0
  25. data/demo/app/london_population_area.rb +42 -0
  26. data/demo/app/man_vs_horse.rb +53 -0
  27. data/demo/app/mtg_modern_colors.rb +49 -0
  28. data/demo/app/mtg_modern_creatures.rb +63 -0
  29. data/demo/app/olympics_2016_medals.rb +54 -0
  30. data/demo/app/paradox.rb +57 -0
  31. data/demo/app/polish_pms.rb +53 -0
  32. data/demo/app/star_trek_voyager.rb +39 -0
  33. data/demo/app/weather_in_london.rb +62 -0
  34. data/demo/assets/d3.js +16393 -0
  35. data/demo/assets/style.css +0 -0
  36. data/demo/config.ru +39 -0
  37. data/demo/views/index.erb +21 -0
  38. data/demo/views/visualization.erb +29 -0
  39. data/lib/opal/d3/arc.rb +21 -0
  40. data/lib/opal/d3/area.rb +49 -0
  41. data/lib/opal/d3/axis.rb +77 -0
  42. data/lib/opal/d3/band_scale.rb +29 -0
  43. data/lib/opal/d3/collections.rb +10 -0
  44. data/lib/opal/d3/color.rb +78 -0
  45. data/lib/opal/d3/continuous_scale.rb +64 -0
  46. data/lib/opal/d3/creator.rb +11 -0
  47. data/lib/opal/d3/curve.rb +74 -0
  48. data/lib/opal/d3/dsv.rb +103 -0
  49. data/lib/opal/d3/ease.rb +319 -0
  50. data/lib/opal/d3/format.rb +97 -0
  51. data/lib/opal/d3/histograms.rb +44 -0
  52. data/lib/opal/d3/interpolate.rb +125 -0
  53. data/lib/opal/d3/line.rb +29 -0
  54. data/lib/opal/d3/map.rb +52 -0
  55. data/lib/opal/d3/misc.rb +15 -0
  56. data/lib/opal/d3/native.rb +84 -0
  57. data/lib/opal/d3/nest.rb +100 -0
  58. data/lib/opal/d3/ordinal_scale.rb +56 -0
  59. data/lib/opal/d3/path.rb +22 -0
  60. data/lib/opal/d3/pie.rb +23 -0
  61. data/lib/opal/d3/point_scale.rb +26 -0
  62. data/lib/opal/d3/polygon.rb +16 -0
  63. data/lib/opal/d3/quadtree.rb +95 -0
  64. data/lib/opal/d3/quantile_scale.rb +21 -0
  65. data/lib/opal/d3/quantize_scale.rb +23 -0
  66. data/lib/opal/d3/radial_area.rb +49 -0
  67. data/lib/opal/d3/radial_line.rb +29 -0
  68. data/lib/opal/d3/random.rb +12 -0
  69. data/lib/opal/d3/search.rb +28 -0
  70. data/lib/opal/d3/selection.rb +149 -0
  71. data/lib/opal/d3/sequential_scale.rb +96 -0
  72. data/lib/opal/d3/set.rb +33 -0
  73. data/lib/opal/d3/stack.rb +11 -0
  74. data/lib/opal/d3/statistics.rb +81 -0
  75. data/lib/opal/d3/symbol.rb +70 -0
  76. data/lib/opal/d3/threshold_scale.rb +23 -0
  77. data/lib/opal/d3/time_format.rb +48 -0
  78. data/lib/opal/d3/time_interval.rb +81 -0
  79. data/lib/opal/d3/transformations.rb +13 -0
  80. data/lib/opal/d3/version.rb +5 -0
  81. data/lib/opal/d3.rb +62 -0
  82. data/lib/opal-d3.rb +9 -0
  83. data/opal-d3.gemspec +20 -0
  84. data/spec/arc_spec.rb +86 -0
  85. data/spec/area_spec.rb +102 -0
  86. data/spec/axis_spec.rb +174 -0
  87. data/spec/band_scale_spec.rb +73 -0
  88. data/spec/color_spec.rb +74 -0
  89. data/spec/continuous_scale_spec.rb +217 -0
  90. data/spec/coverage_spec.rb +23 -0
  91. data/spec/creator_spec.rb +15 -0
  92. data/spec/curve_spec.rb +214 -0
  93. data/spec/dsv_spec.rb +194 -0
  94. data/spec/ease_spec.rb +370 -0
  95. data/spec/format_spec.rb +87 -0
  96. data/spec/histograms_spec.rb +61 -0
  97. data/spec/html/d3.js +16393 -0
  98. data/spec/html/index.html.erb +12 -0
  99. data/spec/interpolate_spec.rb +152 -0
  100. data/spec/line_spec.rb +58 -0
  101. data/spec/map_spec.rb +80 -0
  102. data/spec/misc_spec.rb +19 -0
  103. data/spec/nest_spec.rb +89 -0
  104. data/spec/objects_spec.rb +22 -0
  105. data/spec/ordinal_scale_spec.rb +59 -0
  106. data/spec/path_spec.rb +65 -0
  107. data/spec/pie_spec.rb +114 -0
  108. data/spec/point_scale_spec.rb +58 -0
  109. data/spec/polygon_spec.rb +51 -0
  110. data/spec/quadtree_spec.rb +128 -0
  111. data/spec/quantile_scale_spec.rb +24 -0
  112. data/spec/quantize_scale_spec.rb +40 -0
  113. data/spec/radial_area_spec.rb +127 -0
  114. data/spec/radial_line_spec.rb +54 -0
  115. data/spec/random_spec.rb +34 -0
  116. data/spec/search_spec.rb +69 -0
  117. data/spec/selection_data_spec.rb +71 -0
  118. data/spec/selection_manipulation_spec.rb +179 -0
  119. data/spec/selection_spec.rb +214 -0
  120. data/spec/sequential_scale_spec.rb +90 -0
  121. data/spec/set_spec.rb +57 -0
  122. data/spec/spec_helper.rb +2 -0
  123. data/spec/stack_spec.rb +23 -0
  124. data/spec/statistics_spec.rb +65 -0
  125. data/spec/symbol_spec.rb +121 -0
  126. data/spec/threshold_scale_spec.rb +28 -0
  127. data/spec/time_format_spec.rb +99 -0
  128. data/spec/time_interval_spec.rb +304 -0
  129. data/spec/transformations_spec.rb +51 -0
  130. metadata +258 -0
data/opal-d3.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ require_relative "lib/opal/d3/version"
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "opal-d3"
5
+ s.version = Opal::D3::VERSION
6
+ s.author = "Tomasz Wegrzanowski"
7
+ s.email = "Tomasz.Wegrzanowski@gmail.com"
8
+ s.homepage = "https://github.com/taw/opal-d3"
9
+ s.summary = "Ruby bindings for D3"
10
+ s.description = "Opal wrapper library for D3 library"
11
+
12
+ s.files = `git ls-files`.split("\n")
13
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
14
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ s.require_paths = ["lib"]
16
+
17
+ s.add_runtime_dependency "opal", "~> 0.10.0"
18
+ s.add_development_dependency "opal-rspec", ">= 0.6.0"
19
+ s.add_development_dependency "rake", ">= 11.3.0"
20
+ end
data/spec/arc_spec.rb ADDED
@@ -0,0 +1,86 @@
1
+ describe "d3 - arc" do
2
+ it "d3.arc" do
3
+ expect(D3.arc).to be_instance_of(D3::ArcGenerator)
4
+ end
5
+
6
+ let(:example_arc) {
7
+ D3.arc
8
+ .inner_radius(0)
9
+ .outer_radius(100)
10
+ .start_angle(0)
11
+ .end_angle(Math::PI / 2)
12
+ }
13
+
14
+ # That's a weird rounding error, documentation says "M0,-100A100,100,0,0,1,100,0L0,0Z"
15
+ it "basics" do
16
+ expect(example_arc.()).to eq("M6.123233995736766e-15,-100A100,100,0,0,1,100,0L0,0Z")
17
+ end
18
+
19
+ it "passing hash" do
20
+ arc = D3.arc
21
+ expect(arc.({
22
+ innerRadius: 0,
23
+ outerRadius: 100,
24
+ startAngle: 0,
25
+ endAngle: Math::PI / 2,
26
+ }.to_n)).to eq("M6.123233995736766e-15,-100A100,100,0,0,1,100,0L0,0Z")
27
+ end
28
+
29
+ it "arc.inner_radius" do
30
+ arc = D3.arc.inner_radius(20)
31
+ expect(arc.inner_radius.()).to eq(20)
32
+ arc.inner_radius{|t| t*10}
33
+ expect(arc.inner_radius.(12)).to eq(120)
34
+ end
35
+
36
+ it "arc.outer_radius" do
37
+ arc = D3.arc.outer_radius(100)
38
+ expect(arc.outer_radius.()).to eq(100)
39
+ arc.outer_radius{|t| t*10}
40
+ expect(arc.outer_radius.(12)).to eq(120)
41
+ end
42
+
43
+ it "arc.start_angle" do
44
+ arc = D3.arc.start_angle(Math::PI/2)
45
+ expect(arc.start_angle.()).to eq(Math::PI/2)
46
+ arc.start_angle{|t| t*10}
47
+ expect(arc.start_angle.(12)).to eq(120)
48
+ end
49
+
50
+ it "arc.end_angle" do
51
+ arc = D3.arc.end_angle(3*Math::PI/2)
52
+ expect(arc.end_angle.()).to eq(3*Math::PI/2)
53
+ arc.end_angle{|t| t*10}
54
+ expect(arc.end_angle.(12)).to eq(120)
55
+ end
56
+
57
+ it "arc.corner_radius" do
58
+ arc = D3.arc.corner_radius(5)
59
+ expect(arc.corner_radius.()).to eq(5)
60
+ arc.corner_radius{|t| t*10}
61
+ expect(arc.corner_radius.(12)).to eq(120)
62
+ expect(example_arc.corner_radius(5).()).to eq(
63
+ "M6.217248937900877e-15,-94.86832980505139"+
64
+ "A5,5,0,0,1,5.263157894736849,-99.86139979479094"+
65
+ "A100,100,0,0,1,99.86139979479093,-5.263157894736842"+
66
+ "A5,5,0,0,1,94.86832980505139,0"+
67
+ "L0,0Z"
68
+ )
69
+ end
70
+
71
+ it "arc.centroid" do
72
+ expect(example_arc.centroid).to eq([35.35533905932738, -35.35533905932737])
73
+ expect(D3.arc.centroid({
74
+ innerRadius: 20,
75
+ outerRadius: 40,
76
+ startAngle: Math::PI * 0.25,
77
+ endAngle: Math::PI * 0.75 ,
78
+ }.to_n)).to eq([30,0])
79
+ end
80
+ end
81
+
82
+ __END__
83
+
84
+ arc.padAngle - set the angle between adjacent arcs, for padded arcs.
85
+ arc.padRadius - set the radius at which to linearize padding.
86
+ arc.context - set the rendering context.
data/spec/area_spec.rb ADDED
@@ -0,0 +1,102 @@
1
+ describe "d3 - area" do
2
+ it "d3.area" do
3
+ expect(D3.area).to be_instance_of(D3::AreaGenerator)
4
+ end
5
+
6
+ let(:simple_data) {[
7
+ {year: 2007, value: 93.24},
8
+ {year: 2008, value: 95.35},
9
+ {year: 2009, value: 98.84},
10
+ {year: 2010, value: 99.92},
11
+ {year: 2011, value: 99.80},
12
+ {year: 2014, value: 99.47},
13
+ ]}
14
+
15
+ describe "basics" do
16
+ let(:area) {
17
+ D3.area
18
+ .x{|d| (d[:year]-2000)*10 }
19
+ .y1{|d| d[:value] }
20
+ .y0(50)
21
+ }
22
+ it "basics" do
23
+ expect(area.(simple_data)).to eq(
24
+ "M70,93.24L80,95.35L90,98.84L100,99.92L110,99.8L140,99.47L140,50L110,50L100,50L90,50L80,50L70,50Z"
25
+ )
26
+ end
27
+
28
+ it "curve" do
29
+ expect(area.curve).to be_instance_of(D3::Curve)
30
+ expect(area.curve(D3.curve_natural).(simple_data)).to eq(%W[
31
+ M70,93.24
32
+ C73.3652312599681,93.76974481658695,76.7304625199362,94.29948963317388,80,95.35
33
+ C83.2695374800638,96.40051036682611,86.4433811802233,97.97178628389153,90,98.84
34
+ C93.5566188197767,99.70821371610847,97.49601275917065,99.87336523125998,100,99.92
35
+ C102.50398724082935,99.96663476874002,103.5725677830941,99.89475279106857,110,99.8
36
+ C116.4274322169059,99.70524720893143,128.21371610845296,99.5876236044657,140,99.47L140,50
37
+ C128.21371610845296,50,116.4274322169059,50,110,50
38
+ C103.5725677830941,50,102.50398724082936,50,100,50
39
+ C97.49601275917064,50,93.55661881977672,50,90,50
40
+ C86.44338118022328,50,83.2695374800638,50,80,50
41
+ C76.7304625199362,50,73.3652312599681,50,70,50Z
42
+ ].join)
43
+ end
44
+
45
+ it ".defined" do
46
+ expect(area.defined{|d| d[:year] != 2010}.(simple_data)).to eq(
47
+ "M70,93.24L80,95.35L90,98.84L90,50L80,50L70,50ZM110,99.8L140,99.47L140,50L110,50Z"
48
+ )
49
+ end
50
+ end
51
+
52
+ describe "line generators" do
53
+ let(:area) {
54
+ D3.area
55
+ .x0{|d| (d[:year]-2000)*10 }
56
+ .x1{|d| (d[:year]-2000)*20 }
57
+ .y1{|d| d[:value] }
58
+ .y0(50)
59
+ }
60
+ let(:point) { {year: 2042, value: 117 } }
61
+
62
+ it ".x/.x0/.x1" do
63
+ expect(area.x0.(point)).to eq(420)
64
+ expect(area.x1.(point)).to eq(840)
65
+ expect(area.x.(point)).to eq(420)
66
+ end
67
+
68
+ it ".y/.y0/.y1" do
69
+ expect(area.y0.(point)).to eq(50)
70
+ expect(area.y1.(point)).to eq(117)
71
+ expect(area.y.(point)).to eq(50)
72
+ end
73
+
74
+ it ".line_x0" do # x0 y0
75
+ expect(area.line_x0).to be_instance_of(D3::LineGenerator)
76
+ expect(area.line_x0.x.(point)).to eq(420)
77
+ expect(area.line_x0.y.(point)).to eq(50)
78
+ end
79
+
80
+ it ".line_x1" do # x1 y0
81
+ expect(area.line_x1).to be_instance_of(D3::LineGenerator)
82
+ expect(area.line_x1.x.(point)).to eq(840)
83
+ expect(area.line_x1.y.(point)).to eq(50)
84
+ end
85
+
86
+ it ".line_y0" do # x0 y0
87
+ expect(area.line_y0).to be_instance_of(D3::LineGenerator)
88
+ expect(area.line_y0.x.(point)).to eq(420)
89
+ expect(area.line_y0.y.(point)).to eq(50)
90
+ end
91
+
92
+ it ".line_y1" do # x0 y1
93
+ expect(area.line_y1).to be_instance_of(D3::LineGenerator)
94
+ expect(area.line_y1.x.(point)).to eq(420)
95
+ expect(area.line_y1.y.(point)).to eq(117)
96
+ end
97
+ end
98
+ end
99
+
100
+ __END__
101
+
102
+ area.context - set the rendering context.
data/spec/axis_spec.rb ADDED
@@ -0,0 +1,174 @@
1
+ describe "d3 - axis" do
2
+ after(:each) do
3
+ D3.select("#test-area").html("")
4
+ end
5
+
6
+ let(:scale) { D3.scale_linear.domain([0,80_000_000]).range([0,800]) }
7
+ let(:scale2) { D3.scale_linear.domain([0,30]).range([0,600]) }
8
+ let(:axis) { D3.axis_top(scale) }
9
+
10
+ it "d3.axis_top" do
11
+ expect(D3.axis_top(scale)).to be_instance_of(D3::Axis)
12
+ end
13
+
14
+ it "d3.axis_bottom" do
15
+ expect(D3.axis_bottom(scale)).to be_instance_of(D3::Axis)
16
+ end
17
+
18
+ it "d3.axis_right" do
19
+ expect(D3.axis_right(scale)).to be_instance_of(D3::Axis)
20
+ end
21
+
22
+ it "d3.axis_left" do
23
+ expect(D3.axis_left(scale)).to be_instance_of(D3::Axis)
24
+ end
25
+
26
+ it "axis.scale" do
27
+ expect(axis.scale).to eq(scale)
28
+ axis.scale(scale2)
29
+ expect(axis.scale).to eq(scale2)
30
+ axis.scale = scale
31
+ expect(axis.scale).to eq(scale)
32
+ end
33
+
34
+ it "axis.tick_size_inner" do
35
+ expect(axis.tick_size_inner).to eq(6)
36
+ axis.tick_size_inner(20)
37
+ expect(axis.tick_size_inner).to eq(20)
38
+ end
39
+
40
+ it "axis.tick_size_outer" do
41
+ expect(axis.tick_size_outer).to eq(6)
42
+ axis.tick_size_outer(20)
43
+ expect(axis.tick_size_outer).to eq(20)
44
+ end
45
+
46
+ it "axis.tick_size" do
47
+ expect(axis.tick_size).to eq(6)
48
+ axis.tick_size(20)
49
+ expect(axis.tick_size).to eq(20)
50
+ end
51
+
52
+ it "axis.tick_padding" do
53
+ expect(axis.tick_padding).to eq(3)
54
+ axis.tick_padding(10)
55
+ expect(axis.tick_padding).to eq(10)
56
+ end
57
+
58
+ describe "axis.tick_values" do
59
+ it "defaults" do
60
+ context = D3.select("#test-area").append("svg")
61
+ expect(axis.tick_values).to eq(nil)
62
+ axis.(context)
63
+ expect(D3.select("#test-area").html).to eq([
64
+ '<svg fill="none" font-size="10" font-family="sans-serif" text-anchor="middle">',
65
+ '<path class="domain" stroke="#000" d="M0.5,-6V0.5H800.5V-6"></path>',
66
+ '<g class="tick" opacity="1" transform="translate(0,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">0</text></g>',
67
+ '<g class="tick" opacity="1" transform="translate(100,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">10,000,000</text></g>',
68
+ '<g class="tick" opacity="1" transform="translate(200,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">20,000,000</text></g>',
69
+ '<g class="tick" opacity="1" transform="translate(300,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">30,000,000</text></g>',
70
+ '<g class="tick" opacity="1" transform="translate(400,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">40,000,000</text></g>',
71
+ '<g class="tick" opacity="1" transform="translate(500,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">50,000,000</text></g>',
72
+ '<g class="tick" opacity="1" transform="translate(600,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">60,000,000</text></g>',
73
+ '<g class="tick" opacity="1" transform="translate(700,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">70,000,000</text></g>',
74
+ '<g class="tick" opacity="1" transform="translate(800,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">80,000,000</text></g>',
75
+ '</svg>',
76
+ ].join)
77
+ end
78
+
79
+ it "set/get" do
80
+ context = D3.select("#test-area").append("svg")
81
+ axis.tick_values = [0, 20_000_000, 40_000_000]
82
+ expect(axis.tick_values).to eq([0, 20_000_000, 40_000_000])
83
+ axis.(context)
84
+ expect(D3.select("#test-area").html).to eq([
85
+ '<svg fill="none" font-size="10" font-family="sans-serif" text-anchor="middle">',
86
+ '<path class="domain" stroke="#000" d="M0.5,-6V0.5H800.5V-6"></path>',
87
+ '<g class="tick" opacity="1" transform="translate(0,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">0</text></g>',
88
+ '<g class="tick" opacity="1" transform="translate(200,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">20,000,000</text></g>',
89
+ '<g class="tick" opacity="1" transform="translate(400,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">40,000,000</text></g>',
90
+ '</svg>',
91
+ ].join)
92
+ axis.tick_values(nil)
93
+ expect(axis.tick_values).to eq(nil)
94
+ end
95
+ end
96
+
97
+ describe "axis.tick_format" do
98
+ let(:scale) { D3.scale_linear.domain([0,80_000]).range([0,800]) }
99
+ it "basics" do
100
+ context = D3.select("#test-area").append("svg")
101
+ expect(axis.tick_format).to eq(nil)
102
+ axis.tick_values = [0, 20_000, 40_000]
103
+ axis.tick_format = D3.format(",.2f")
104
+ axis.(context)
105
+ expect(D3.select("#test-area").html).to eq([
106
+ '<svg fill="none" font-size="10" font-family="sans-serif" text-anchor="middle">',
107
+ '<path class="domain" stroke="#000" d="M0.5,-6V0.5H800.5V-6"></path>',
108
+ '<g class="tick" opacity="1" transform="translate(0,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">0.00</text></g>',
109
+ '<g class="tick" opacity="1" transform="translate(200,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">20,000.00</text></g>',
110
+ '<g class="tick" opacity="1" transform="translate(400,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">40,000.00</text></g>',
111
+ '</svg>',
112
+ ].join)
113
+ end
114
+
115
+ it "block" do
116
+ context = D3.select("#test-area").append("svg")
117
+ expect(axis.tick_format).to eq(nil)
118
+ axis.tick_values = [0, 20_000, 40_000]
119
+ axis.tick_format{|d| "#{d}x"}
120
+ expect(axis.tick_format.(5)).to eq("5x")
121
+ axis.(context)
122
+ expect(D3.select("#test-area").html).to eq([
123
+ '<svg fill="none" font-size="10" font-family="sans-serif" text-anchor="middle">',
124
+ '<path class="domain" stroke="#000" d="M0.5,-6V0.5H800.5V-6"></path>',
125
+ '<g class="tick" opacity="1" transform="translate(0,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">0x</text></g>',
126
+ '<g class="tick" opacity="1" transform="translate(200,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">20000x</text></g>',
127
+ '<g class="tick" opacity="1" transform="translate(400,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">40000x</text></g>',
128
+ '</svg>',
129
+ ].join)
130
+ end
131
+ end
132
+
133
+ it "axis.ticks" do
134
+ context = D3.select("#test-area").append("svg")
135
+ axis.ticks(10, ".2f")
136
+ axis.(context)
137
+ expect(D3.select("#test-area").html).to eq([
138
+ '<svg fill="none" font-size="10" font-family="sans-serif" text-anchor="middle">',
139
+ '<path class="domain" stroke="#000" d="M0.5,-6V0.5H800.5V-6"></path>',
140
+ '<g class="tick" opacity="1" transform="translate(0,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">0.00</text></g>',
141
+ '<g class="tick" opacity="1" transform="translate(100,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">10000000.00</text></g>',
142
+ '<g class="tick" opacity="1" transform="translate(200,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">20000000.00</text></g>',
143
+ '<g class="tick" opacity="1" transform="translate(300,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">30000000.00</text></g>',
144
+ '<g class="tick" opacity="1" transform="translate(400,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">40000000.00</text></g>',
145
+ '<g class="tick" opacity="1" transform="translate(500,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">50000000.00</text></g>',
146
+ '<g class="tick" opacity="1" transform="translate(600,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">60000000.00</text></g>',
147
+ '<g class="tick" opacity="1" transform="translate(700,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">70000000.00</text></g>',
148
+ '<g class="tick" opacity="1" transform="translate(800,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">80000000.00</text></g>',
149
+ '</svg>',
150
+ ].join)
151
+ end
152
+
153
+ it "axis.tick_arguments" do
154
+ context = D3.select("#test-area").append("svg")
155
+ expect(axis.tick_arguments).to eq([])
156
+ axis.tick_arguments([10, ".2f"])
157
+ expect(axis.tick_arguments).to eq([10, ".2f"])
158
+ axis.(context)
159
+ expect(D3.select("#test-area").html).to eq([
160
+ '<svg fill="none" font-size="10" font-family="sans-serif" text-anchor="middle">',
161
+ '<path class="domain" stroke="#000" d="M0.5,-6V0.5H800.5V-6"></path>',
162
+ '<g class="tick" opacity="1" transform="translate(0,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">0.00</text></g>',
163
+ '<g class="tick" opacity="1" transform="translate(100,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">10000000.00</text></g>',
164
+ '<g class="tick" opacity="1" transform="translate(200,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">20000000.00</text></g>',
165
+ '<g class="tick" opacity="1" transform="translate(300,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">30000000.00</text></g>',
166
+ '<g class="tick" opacity="1" transform="translate(400,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">40000000.00</text></g>',
167
+ '<g class="tick" opacity="1" transform="translate(500,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">50000000.00</text></g>',
168
+ '<g class="tick" opacity="1" transform="translate(600,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">60000000.00</text></g>',
169
+ '<g class="tick" opacity="1" transform="translate(700,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">70000000.00</text></g>',
170
+ '<g class="tick" opacity="1" transform="translate(800,0)"><line stroke="#000" y2="-6" x1="0.5" x2="0.5"></line><text fill="#000" y="-9" x="0.5" dy="0em">80000000.00</text></g>',
171
+ '</svg>',
172
+ ].join)
173
+ end
174
+ end
@@ -0,0 +1,73 @@
1
+ describe "d3 - band scale" do
2
+ it "d3.scale_band" do
3
+ expect(D3.scale_band).to be_instance_of(D3::BandScale)
4
+ end
5
+
6
+ let(:d) { ("a".."f").to_a }
7
+ it "basics" do
8
+ scale = D3.scale_band.domain(d)
9
+ expect(d.map{|v| scale.(v).round(2)}).to eq([0, 0.17, 0.33, 0.5, 0.67, 0.83])
10
+ expect(scale.bandwidth).to eq(0.16666666666666666)
11
+ expect(scale.step).to eq(0.16666666666666666)
12
+ expect(scale.("z")).to eq(nil)
13
+ end
14
+
15
+ it "padding" do
16
+ scale = D3.scale_band.domain(d).range([0,100])
17
+ expect(scale.padding).to eq(0)
18
+ expect(scale.padding_inner).to eq(0)
19
+ expect(scale.padding_outer).to eq(0)
20
+
21
+ scale.padding(0.5)
22
+ expect(scale.padding).to eq(0.5)
23
+ expect(scale.padding_inner).to eq(0.5)
24
+ expect(scale.padding_outer).to eq(0.5)
25
+
26
+ scale.padding_inner(0.2)
27
+ scale.padding_outer(0.4)
28
+ expect(scale.padding).to eq(0.2)
29
+ expect(scale.padding_inner).to eq(0.2)
30
+ expect(scale.padding_outer).to eq(0.4)
31
+
32
+ expect(d.map{|v| scale.(v).round(2)}).to eq([6.06, 21.21, 36.36, 51.52, 66.67, 81.82])
33
+ expect(scale.bandwidth).to eq(12.121212121212123)
34
+ expect(scale.step).to eq(15.151515151515152)
35
+ end
36
+
37
+ it "copy" do
38
+ scale = D3.scale_band.domain(d)
39
+ sc = scale.copy.range([10,20])
40
+ expect(scale.domain).to eq(d)
41
+ expect(sc.domain).to eq(d)
42
+ expect(scale.range).to eq([0,1])
43
+ expect(sc.range).to eq([10,20])
44
+ end
45
+
46
+ it "align" do
47
+ scale = D3.scale_band.domain(d).range([0,100])
48
+ expect(scale.align).to eq(0.5)
49
+ scale.padding_inner(0.2)
50
+ scale.padding_outer(0.4)
51
+ expect(d.map{|v| scale.(v).round(2)}).to eq([6.06, 21.21, 36.36, 51.52, 66.67, 81.82])
52
+
53
+ scale.align(0)
54
+ expect(scale.align).to eq(0)
55
+ expect(d.map{|v| scale.(v).round(2)}).to eq([0, 15.15, 30.3, 45.45, 60.61, 75.76])
56
+
57
+ scale.align(1)
58
+ expect(scale.align).to eq(1)
59
+ expect(d.map{|v| scale.(v).round(2)}).to eq([12.12, 27.27, 42.42, 57.58, 72.73, 87.88])
60
+ expect(scale.bandwidth).to eq(12.121212121212123)
61
+ expect(scale.step).to eq(15.151515151515152)
62
+ end
63
+
64
+ it "round" do
65
+ scale = D3.scale_band.domain(d).range([0,100])
66
+ expect(scale.round).to eq(false)
67
+ scale.range_round([0,1000])
68
+ expect(scale.range).to eq([0,1000])
69
+ expect(scale.round).to eq(true)
70
+ # This rounding is somewhat weird
71
+ expect(d.map{|v| scale.(v)}).to eq([2, 168, 334, 500, 666, 832])
72
+ end
73
+ end
@@ -0,0 +1,74 @@
1
+ describe "d3-colors" do
2
+ it "d3.color" do
3
+ expect(D3.color("blue")).to be_instance_of(D3::Color)
4
+ end
5
+
6
+ it "supported syntax" do
7
+ expect(D3.color("rgb(255, 255, 255)").to_s).to eq("rgb(255, 255, 255)")
8
+ expect(D3.color("rgb(10%, 20%, 30%)").to_s).to eq("rgb(26, 51, 77)")
9
+ expect(D3.color("rgba(255, 255, 255, 0.4)").to_s).to eq("rgba(255, 255, 255, 0.4)")
10
+ expect(D3.color("rgba(10%, 20%, 30%, 0.4)").to_s).to eq("rgba(26, 51, 77, 0.4)")
11
+ expect(D3.color("hsl(120, 50%, 20%)").to_s).to eq("rgb(25, 77, 25)")
12
+ expect(D3.color("hsla(120, 50%, 20%, 0.4)").to_s).to eq("rgba(25, 77, 25, 0.4)")
13
+ expect(D3.color("#ffeeaa").to_s).to eq("rgb(255, 238, 170)")
14
+ expect(D3.color("#fea").to_s).to eq("rgb(255, 238, 170)")
15
+ expect(D3.color("steelblue").to_s).to eq("rgb(70, 130, 180)")
16
+ end
17
+
18
+ it "invalid colors" do
19
+ expect{ D3.color("poop_emoji") }.to raise_error(/Invalid color/)
20
+ end
21
+
22
+ it "color.brighter" do
23
+ steelblue = D3.color("steelblue")
24
+ expect(steelblue.brighter.to_s).to eq("rgb(100, 186, 255)")
25
+ expect(steelblue.brighter(0.25).to_s).to eq("rgb(77, 142, 197)")
26
+ end
27
+
28
+ it "color.darker" do
29
+ steelblue = D3.color("steelblue")
30
+ expect(steelblue.darker.to_s).to eq("rgb(49, 91, 126)")
31
+ expect(steelblue.darker(0.25).to_s).to eq("rgb(64, 119, 165)")
32
+ end
33
+
34
+ it "color.displayable?" do
35
+ expect(D3.color("rgb(255,255,255)")).to be_displayable
36
+ expect(D3.color("rgb(260,260,260)")).to_not be_displayable
37
+ end
38
+
39
+ it "d3.rgb" do
40
+ steelblue = D3.rgb("steelblue")
41
+ expect([steelblue.r, steelblue.g, steelblue.b]).to eq([70, 130, 180])
42
+ expect(D3.rgb(10,20,30).to_s).to eq("rgb(10, 20, 30)")
43
+ expect(D3.rgb(10,20,30,0.5).to_s).to eq("rgba(10, 20, 30, 0.5)")
44
+ expect(D3.rgb(D3.hsl("steelblue")).to_s).to eq("rgb(70, 130, 180)")
45
+ end
46
+
47
+ it "d3.hsl" do
48
+ steelblue = D3.hsl("steelblue")
49
+ expect([steelblue.h, steelblue.s, steelblue.l]).to eq([207.27272727272728, 0.44, 0.4901960784313726])
50
+ expect(D3.hsl(207.27272727272728, 0.44, 0.4901960784313726).to_s).to eq("rgb(70, 130, 180)")
51
+ expect(D3.hsl(207.27272727272728, 0.44, 0.4901960784313726, 0.5).to_s).to eq("rgba(70, 130, 180, 0.5)")
52
+ end
53
+
54
+ it "d3.lab" do
55
+ steelblue = D3.lab("steelblue")
56
+ expect([steelblue.l, steelblue.a, steelblue.b]).to eq([52.46551718768575, -4.0774710123572255, -32.19186122981343])
57
+ expect(D3.lab(52.46551718768575, -4.0774710123572255, -32.19186122981343).to_s).to eq("rgb(70, 130, 180)")
58
+ expect(D3.lab(52.46551718768575, -4.0774710123572255, -32.19186122981343, 0.5).to_s).to eq("rgba(70, 130, 180, 0.5)")
59
+ end
60
+
61
+ it "d3.hcl" do
62
+ steelblue = D3.hcl("steelblue")
63
+ expect([steelblue.h, steelblue.c, steelblue.l]).to eq([262.78126775909277, 32.44906314974561, 52.46551718768575])
64
+ expect(D3.hcl(262.78126775909277, 32.44906314974561, 52.46551718768575).to_s).to eq("rgb(70, 130, 180)")
65
+ expect(D3.hcl(262.78126775909277, 32.44906314974561, 52.46551718768575, 0.5).to_s).to eq("rgba(70, 130, 180, 0.5)")
66
+ end
67
+
68
+ it "d3.cubehelix" do
69
+ steelblue = D3.cubehelix("steelblue")
70
+ expect([steelblue.h, steelblue.s, steelblue.l]).to eq([202.84837896488932, 0.6273147230777709, 0.460784355920337])
71
+ expect(D3.cubehelix(202.84837896488932, 0.6273147230777709, 0.460784355920337).to_s).to eq("rgb(70, 130, 180)")
72
+ expect(D3.cubehelix(202.84837896488932, 0.6273147230777709, 0.460784355920337, 0.5).to_s).to eq("rgba(70, 130, 180, 0.5)")
73
+ end
74
+ end