rails-data-explorer 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +5 -1
- data/README.md +11 -0
- data/Rakefile +62 -0
- data/doc/how_to/release.md +23 -0
- data/doc/how_to/trouble_when_packaging_assets.md +8 -0
- data/lib/rails-data-explorer-no-rails.rb +42 -0
- data/lib/rails-data-explorer.rb +5 -9
- data/lib/rails-data-explorer/chart/box_plot.rb +5 -1
- data/lib/rails-data-explorer/chart/box_plot_group.rb +22 -5
- data/lib/rails-data-explorer/chart/contingency_table.rb +45 -10
- data/lib/rails-data-explorer/chart/histogram_categorical.rb +104 -3
- data/lib/rails-data-explorer/chart/histogram_quantitative.rb +99 -2
- data/lib/rails-data-explorer/chart/histogram_temporal.rb +10 -55
- data/lib/rails-data-explorer/chart/parallel_coordinates.rb +4 -0
- data/lib/rails-data-explorer/chart/parallel_set.rb +4 -0
- data/lib/rails-data-explorer/chart/pie_chart.rb +89 -8
- data/lib/rails-data-explorer/chart/scatterplot.rb +110 -8
- data/lib/rails-data-explorer/chart/stacked_bar_chart_categorical_percent.rb +133 -14
- data/lib/rails-data-explorer/data_series.rb +37 -2
- data/lib/rails-data-explorer/data_type/categorical.rb +72 -2
- data/lib/rails-data-explorer/data_type/quantitative.rb +41 -12
- data/lib/rails-data-explorer/data_type/quantitative/temporal.rb +3 -2
- data/lib/rails-data-explorer/exploration.rb +5 -1
- data/lib/rails-data-explorer/utils/data_binner.rb +31 -0
- data/lib/rails-data-explorer/utils/data_quantizer.rb +66 -0
- data/lib/rails_data_explorer.rb +133 -0
- data/rails-data-explorer.gemspec +4 -4
- data/spec/helper.rb +7 -0
- data/spec/helper_no_rails.rb +10 -0
- data/spec/rails-data-explorer/data_series_spec.rb +45 -0
- data/spec/rails-data-explorer/data_type/categorical_spec.rb +34 -0
- data/spec/rails-data-explorer/exploration_spec.rb +55 -0
- data/spec/rails-data-explorer/utils/data_binner_spec.rb +29 -0
- data/spec/rails-data-explorer/utils/data_quantizer_spec.rb +71 -0
- data/vendor/assets/javascripts/packaged/rails-data-explorer.min.js +1 -0
- data/vendor/assets/javascripts/rails-data-explorer.js +6 -5
- data/vendor/assets/javascripts/{d3.boxplot.js → sources/d3.boxplot.js} +10 -3
- data/vendor/assets/javascripts/{d3.parcoords.js → sources/d3.parcoords.js} +1 -1
- data/vendor/assets/javascripts/{d3.parsets.js → sources/d3.parsets.js} +3 -3
- data/vendor/assets/javascripts/{d3.v3.js → sources/d3.v3.js} +0 -0
- data/vendor/assets/javascripts/{nv.d3.js → sources/nv.d3.js} +0 -0
- data/vendor/assets/javascripts/sources/vega.js +7040 -0
- data/vendor/assets/stylesheets/packaged/rails-data-explorer.min.css +9 -0
- data/vendor/assets/stylesheets/rails-data-explorer.css +7 -7
- data/vendor/assets/stylesheets/{bootstrap-theme.css → sources/bootstrap-theme.css} +0 -0
- data/vendor/assets/stylesheets/{bootstrap.css → sources/bootstrap.css} +0 -0
- data/vendor/assets/stylesheets/{d3.boxplot.css → sources/d3.boxplot.css} +0 -0
- data/vendor/assets/stylesheets/{d3.parcoords.css → sources/d3.parcoords.css} +0 -0
- data/vendor/assets/stylesheets/{d3.parsets.css → sources/d3.parsets.css} +0 -0
- data/vendor/assets/stylesheets/{nv.d3.css → sources/nv.d3.css} +0 -0
- data/vendor/assets/stylesheets/{rde-default-style.css → sources/rde-default-style.css} +0 -0
- metadata +65 -28
@@ -9,12 +9,22 @@ class RailsDataExplorer
|
|
9
9
|
|
10
10
|
def compute_chart_attrs
|
11
11
|
x_ds = @data_set.data_series.first
|
12
|
+
return false if x_ds.nil?
|
13
|
+
|
12
14
|
# compute histogram
|
13
|
-
|
15
|
+
quantizer = Utils::DataQuantizer.new(x_ds, :max_number_of_bins => 100)
|
16
|
+
quantized_values = quantizer.values
|
17
|
+
number_of_bars = quantizer.number_of_bins
|
18
|
+
width = 800
|
19
|
+
h = quantized_values.inject(Hash.new(0)) { |m,e| m[e] += 1; m }
|
14
20
|
{
|
15
21
|
values: h.map { |k,v| { x: k, y: v } },
|
22
|
+
width: width,
|
16
23
|
x_axis_label: x_ds.name,
|
17
24
|
x_axis_tick_format: x_ds.axis_tick_format,
|
25
|
+
x_scale_type: 'linear',
|
26
|
+
x_scale_nice: true,
|
27
|
+
bar_width: (width / number_of_bars.to_f) - 3,
|
18
28
|
y_axis_label: 'Frequency',
|
19
29
|
y_axis_tick_format: "d3.format('r')",
|
20
30
|
}
|
@@ -23,8 +33,89 @@ class RailsDataExplorer
|
|
23
33
|
def render
|
24
34
|
return '' unless render?
|
25
35
|
ca = compute_chart_attrs
|
36
|
+
return '' unless ca
|
37
|
+
render_vega(ca)
|
38
|
+
end
|
39
|
+
|
40
|
+
def render_vega(ca)
|
26
41
|
%(
|
27
|
-
<div class="rde-chart rde-histogram">
|
42
|
+
<div class="rde-chart rde-histogram-quantitative">
|
43
|
+
<h3 class="rde-chart-title">Histogram</h3>
|
44
|
+
<div id="#{ dom_id }"></div>
|
45
|
+
<script type="text/javascript">
|
46
|
+
(function() {
|
47
|
+
var spec = {
|
48
|
+
"width": #{ ca[:width] },
|
49
|
+
"height": 200,
|
50
|
+
"padding": {"top": 10, "left": 70, "bottom": 50, "right": 10},
|
51
|
+
"data": [
|
52
|
+
{
|
53
|
+
"name": "table",
|
54
|
+
"values": #{ ca[:values].to_json }
|
55
|
+
}
|
56
|
+
],
|
57
|
+
"scales": [
|
58
|
+
{
|
59
|
+
"name": "x",
|
60
|
+
"type": "#{ ca[:x_scale_type] }",
|
61
|
+
"range": "width",
|
62
|
+
"zero": false,
|
63
|
+
"nice": #{ ca[:x_scale_nice] },
|
64
|
+
"domain": {"data": "table", "field": "data.x"}
|
65
|
+
},
|
66
|
+
{
|
67
|
+
"name": "y",
|
68
|
+
"range": "height",
|
69
|
+
"domain": {"data": "table", "field": "data.y"}
|
70
|
+
}
|
71
|
+
],
|
72
|
+
"axes": [
|
73
|
+
{
|
74
|
+
"type": "x",
|
75
|
+
"scale": "x",
|
76
|
+
"title": "#{ ca[:x_axis_label] }",
|
77
|
+
"format": #{ ca[:x_axis_tick_format] },
|
78
|
+
},
|
79
|
+
{
|
80
|
+
"type": "y",
|
81
|
+
"scale": "y",
|
82
|
+
"title": "#{ ca[:y_axis_label] }",
|
83
|
+
"titleOffset": 60,
|
84
|
+
"format": #{ ca[:y_axis_tick_format] },
|
85
|
+
}
|
86
|
+
],
|
87
|
+
"marks": [
|
88
|
+
{
|
89
|
+
"type": "rect",
|
90
|
+
"from": {"data": "table"},
|
91
|
+
"properties": {
|
92
|
+
"enter": {
|
93
|
+
"x": {"scale": "x", "field": "data.x"},
|
94
|
+
"width": { "value": #{ ca[:bar_width] } },
|
95
|
+
"y": {"scale": "y", "field": "data.y"},
|
96
|
+
"y2": {"scale": "y", "value": 0},
|
97
|
+
},
|
98
|
+
"update": {
|
99
|
+
"fill": {"value": "#1F77B4"}
|
100
|
+
},
|
101
|
+
}
|
102
|
+
}
|
103
|
+
]
|
104
|
+
};
|
105
|
+
|
106
|
+
vg.parse.spec(spec, function(chart) {
|
107
|
+
var view = chart({ el:"##{ dom_id }" }).update();
|
108
|
+
});
|
109
|
+
|
110
|
+
})();
|
111
|
+
</script>
|
112
|
+
</div>
|
113
|
+
)
|
114
|
+
end
|
115
|
+
|
116
|
+
def render_nvd3(ca)
|
117
|
+
%(
|
118
|
+
<div class="rde-chart rde-histogram-quantitative">
|
28
119
|
<h3 class="rde-chart-title">Histogram</h3>
|
29
120
|
<div id="#{ dom_id }", style="height: 200px;">
|
30
121
|
<svg></svg>
|
@@ -52,6 +143,12 @@ class RailsDataExplorer
|
|
52
143
|
.tickFormat(#{ ca[:y_axis_tick_format] })
|
53
144
|
;
|
54
145
|
|
146
|
+
chart.tooltipContent(
|
147
|
+
function(key, x, y, e, graph) {
|
148
|
+
return '<p>' + key + '</p>' + '<p>' + y + ' at ' + x + '</p>'
|
149
|
+
}
|
150
|
+
);
|
151
|
+
|
55
152
|
d3.select('##{ dom_id } svg')
|
56
153
|
.datum(data)
|
57
154
|
.transition().duration(100)
|
@@ -1,78 +1,33 @@
|
|
1
|
+
# TODO: could I use histogram_quantitative instead and just tweak the tick mark format?
|
1
2
|
class RailsDataExplorer
|
2
3
|
class Chart
|
3
|
-
class HistogramTemporal <
|
4
|
-
|
5
|
-
def initialize(_data_set, options = {})
|
6
|
-
@data_set = _data_set
|
7
|
-
@options = {}.merge(options)
|
8
|
-
end
|
4
|
+
class HistogramTemporal < HistogramQuantitative
|
9
5
|
|
10
6
|
def compute_chart_attrs
|
11
7
|
x_ds = @data_set.data_series.first
|
8
|
+
return false if x_ds.nil?
|
9
|
+
|
12
10
|
# compute histogram
|
13
11
|
h = x_ds.values.inject(Hash.new(0)) { |m,e|
|
14
12
|
# Round to day
|
15
|
-
key = (e.beginning_of_day).to_i * 1000
|
13
|
+
key = e.nil? ? nil : (e.beginning_of_day).to_i * 1000
|
16
14
|
m[key] += 1
|
17
15
|
m
|
18
16
|
}
|
17
|
+
width = 800
|
19
18
|
{
|
20
19
|
values: h.map { |k,v| { x: k, y: v } },
|
20
|
+
width: width,
|
21
21
|
x_axis_label: x_ds.name,
|
22
22
|
x_axis_tick_format: x_ds.axis_tick_format,
|
23
|
+
x_scale_type: 'time',
|
24
|
+
x_scale_nice: "'day'",
|
25
|
+
bar_width: 2,
|
23
26
|
y_axis_label: 'Frequency',
|
24
27
|
y_axis_tick_format: "d3.format('r')",
|
25
28
|
}
|
26
29
|
end
|
27
30
|
|
28
|
-
def render
|
29
|
-
return '' unless render?
|
30
|
-
ca = compute_chart_attrs
|
31
|
-
%(
|
32
|
-
<div class="rde-chart rde-histogram">
|
33
|
-
<h3 class="rde-chart-title">Histogram</h3>
|
34
|
-
<div id="#{ dom_id }", style="height: 200px;">
|
35
|
-
<svg></svg>
|
36
|
-
</div>
|
37
|
-
<script type="text/javascript">
|
38
|
-
(function() {
|
39
|
-
var data = [
|
40
|
-
{
|
41
|
-
values: #{ ca[:values].to_json },
|
42
|
-
key: '#{ ca[:x_axis_label] }'
|
43
|
-
}
|
44
|
-
];
|
45
|
-
|
46
|
-
nv.addGraph(function() {
|
47
|
-
var chart = nv.models.historicalBarChart()
|
48
|
-
;
|
49
|
-
|
50
|
-
chart.xAxis
|
51
|
-
.axisLabel('#{ ca[:x_axis_label] }')
|
52
|
-
.tickFormat(#{ ca[:x_axis_tick_format] })
|
53
|
-
;
|
54
|
-
|
55
|
-
chart.yAxis
|
56
|
-
.axisLabel('#{ ca[:y_axis_label] }')
|
57
|
-
.tickFormat(#{ ca[:y_axis_tick_format] })
|
58
|
-
;
|
59
|
-
|
60
|
-
d3.select('##{ dom_id } svg')
|
61
|
-
.datum(data)
|
62
|
-
.transition().duration(100)
|
63
|
-
.call(chart)
|
64
|
-
;
|
65
|
-
|
66
|
-
nv.utils.windowResize(chart.update);
|
67
|
-
|
68
|
-
return chart;
|
69
|
-
});
|
70
|
-
})();
|
71
|
-
</script>
|
72
|
-
</div>
|
73
|
-
)
|
74
|
-
end
|
75
|
-
|
76
31
|
end
|
77
32
|
end
|
78
33
|
end
|
@@ -11,6 +11,8 @@ class RailsDataExplorer
|
|
11
11
|
def render
|
12
12
|
return '' unless render?
|
13
13
|
ca = compute_chart_attrs
|
14
|
+
return '' unless ca
|
15
|
+
|
14
16
|
%(
|
15
17
|
<div class="rde-chart rde-parallel-coordinates">
|
16
18
|
<h3 class="rde-chart-title">Parallel coordinates</h3>
|
@@ -50,6 +52,8 @@ class RailsDataExplorer
|
|
50
52
|
dimension_data_series = @data_set.data_series.find_all { |ds|
|
51
53
|
(ds.chart_roles[Chart::ParallelCoordinates] & [:dimension, :any]).any?
|
52
54
|
}
|
55
|
+
return false if dimension_data_series.empty?
|
56
|
+
|
53
57
|
dimension_names = dimension_data_series.map(&:name)
|
54
58
|
number_of_values = dimension_data_series.first.values.length
|
55
59
|
dimension_values = number_of_values.times.map do |idx|
|
@@ -13,6 +13,8 @@ class RailsDataExplorer
|
|
13
13
|
dimension_data_series = @data_set.data_series.find_all { |ds|
|
14
14
|
(ds.chart_roles[Chart::ParallelCoordinates] & [:dimension, :any]).any?
|
15
15
|
}
|
16
|
+
return false if dimension_data_series.empty?
|
17
|
+
|
16
18
|
number_of_values = dimension_data_series.first.values.length
|
17
19
|
dimension_names = dimension_data_series.map(&:name)
|
18
20
|
dimension_values = number_of_values.times.map do |idx|
|
@@ -34,6 +36,8 @@ class RailsDataExplorer
|
|
34
36
|
def render
|
35
37
|
return '' unless render?
|
36
38
|
ca = compute_chart_attrs
|
39
|
+
return '' unless ca
|
40
|
+
|
37
41
|
%(
|
38
42
|
<div class="rde-chart rde-parallel-set">
|
39
43
|
<h3 class="rde-chart-title">Parallel Set</h3>
|
@@ -9,25 +9,95 @@ class RailsDataExplorer
|
|
9
9
|
|
10
10
|
def compute_chart_attrs
|
11
11
|
x_ds = @data_set.data_series.first
|
12
|
+
return false if x_ds.nil?
|
13
|
+
|
12
14
|
total_count = x_ds.values.length
|
13
15
|
# compute histogram
|
14
16
|
h = x_ds.values.inject(Hash.new(0)) { |m,e| m[e] += 1; m }
|
15
17
|
{
|
16
18
|
values: h.map { |k,v|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
y_axis_tick_format: "d3.format('r')",
|
19
|
+
{ key: k, value: (v / total_count.to_f) }
|
20
|
+
}.sort(
|
21
|
+
&x_ds.label_sorter(
|
22
|
+
:key,
|
23
|
+
lambda { |a,b| b[:value] <=> a[:value] }
|
24
|
+
)
|
25
|
+
)
|
25
26
|
}
|
26
27
|
end
|
27
28
|
|
28
29
|
def render
|
29
30
|
return '' unless render?
|
30
31
|
ca = compute_chart_attrs
|
32
|
+
return '' unless ca
|
33
|
+
render_vega(ca)
|
34
|
+
end
|
35
|
+
|
36
|
+
def render_vega(ca)
|
37
|
+
%(
|
38
|
+
<div class="rde-chart rde-pie-chart">
|
39
|
+
<h3 class="rde-chart-title">Pie Chart</h3>
|
40
|
+
<div id="#{ dom_id }"></div>
|
41
|
+
<script type="text/javascript">
|
42
|
+
(function() {
|
43
|
+
var spec = {
|
44
|
+
"width": 300,
|
45
|
+
"height": 300,
|
46
|
+
"padding": {"top": 10, "left": 10, "bottom": 10, "right": 100},
|
47
|
+
"data": [
|
48
|
+
{
|
49
|
+
"name": "table",
|
50
|
+
"values": #{ ca[:values].to_json }
|
51
|
+
}
|
52
|
+
],
|
53
|
+
"scales": [
|
54
|
+
{
|
55
|
+
"name": "color",
|
56
|
+
"domain": {"data": "table", "field": "data.key"},
|
57
|
+
"range": "category10",
|
58
|
+
"type": "ordinal"
|
59
|
+
},
|
60
|
+
],
|
61
|
+
"axes": [],
|
62
|
+
"marks": [
|
63
|
+
{
|
64
|
+
"type": "arc",
|
65
|
+
"from": {
|
66
|
+
"data": "table",
|
67
|
+
"transform": [{"type": "pie", "value": "data.value"}]
|
68
|
+
},
|
69
|
+
"properties": {
|
70
|
+
"enter": {
|
71
|
+
"x": {"group": "width", "mult": 0.5},
|
72
|
+
"y": {"group": "height", "mult": 0.5},
|
73
|
+
"endAngle": {"field": "endAngle"},
|
74
|
+
"innerRadius": {"value": 100},
|
75
|
+
"outerRadius": {"value": 150},
|
76
|
+
"startAngle": {"field": "startAngle"},
|
77
|
+
"stroke": {"value": "white"},
|
78
|
+
"fill": {"field": "data.key", "scale": "color"}
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
82
|
+
],
|
83
|
+
"legends": [
|
84
|
+
{
|
85
|
+
"fill": "color",
|
86
|
+
}
|
87
|
+
],
|
88
|
+
};
|
89
|
+
|
90
|
+
vg.parse.spec(spec, function(chart) {
|
91
|
+
var view = chart({ el:"##{ dom_id }" }).update();
|
92
|
+
});
|
93
|
+
|
94
|
+
})();
|
95
|
+
</script>
|
96
|
+
</div>
|
97
|
+
)
|
98
|
+
end
|
99
|
+
|
100
|
+
def render_nvd3(ca)
|
31
101
|
%(
|
32
102
|
<div class="rde-chart rde-pie-chart">
|
33
103
|
<h3 class="rde-chart-title">Pie Chart</h3>
|
@@ -45,6 +115,11 @@ class RailsDataExplorer
|
|
45
115
|
chart.valueFormat(d3.format('.1%'))
|
46
116
|
.donut(true)
|
47
117
|
;
|
118
|
+
chart.tooltipContent(
|
119
|
+
function(key, y, e, graph) {
|
120
|
+
return '<p>' + key + '</p>' + '<p>' + y + '</p>'
|
121
|
+
}
|
122
|
+
);
|
48
123
|
|
49
124
|
d3.select('##{ dom_id } svg')
|
50
125
|
.datum(data)
|
@@ -62,6 +137,12 @@ class RailsDataExplorer
|
|
62
137
|
)
|
63
138
|
end
|
64
139
|
|
140
|
+
# Render PieChart only if there is a fairly small number of
|
141
|
+
# distinct values.
|
142
|
+
def render?
|
143
|
+
!@data_set.data_series.first.has_many_uniq_vals?
|
144
|
+
end
|
145
|
+
|
65
146
|
end
|
66
147
|
end
|
67
148
|
end
|
@@ -25,6 +25,7 @@ class RailsDataExplorer
|
|
25
25
|
y_ds = (y_candidates - [x_ds]).first
|
26
26
|
color_ds = (color_candidates - [x_ds, y_ds]).first
|
27
27
|
size_ds = (size_candidates - [x_ds, y_ds, color_ds]).first
|
28
|
+
return false if x_ds.nil? || y_ds.nil?
|
28
29
|
|
29
30
|
ca = case @data_set.dimensions_count
|
30
31
|
when 0,1
|
@@ -37,7 +38,7 @@ class RailsDataExplorer
|
|
37
38
|
r
|
38
39
|
}
|
39
40
|
{
|
40
|
-
values:
|
41
|
+
values: values_hash,
|
41
42
|
x_axis_label: x_ds.name,
|
42
43
|
x_axis_tick_format: x_ds.axis_tick_format,
|
43
44
|
y_axis_label: y_ds.name,
|
@@ -54,7 +55,7 @@ class RailsDataExplorer
|
|
54
55
|
data_series_hash[visual_attr_ds.values[idx]] << { x: x_ds.values[idx], y: y_ds.values[idx] }
|
55
56
|
}
|
56
57
|
{
|
57
|
-
values: data_series_hash
|
58
|
+
values: data_series_hash,
|
58
59
|
x_axis_label: x_ds.name,
|
59
60
|
x_axis_tick_format: x_ds.axis_tick_format,
|
60
61
|
y_axis_label: y_ds.name,
|
@@ -67,7 +68,108 @@ class RailsDataExplorer
|
|
67
68
|
|
68
69
|
def render
|
69
70
|
return '' unless render?
|
70
|
-
|
71
|
+
ca = compute_chart_attrs
|
72
|
+
return '' unless ca
|
73
|
+
render_vega(ca)
|
74
|
+
end
|
75
|
+
|
76
|
+
def render_vega(ca)
|
77
|
+
%(
|
78
|
+
<div class="rde-chart rde-scatterplot">
|
79
|
+
<h3 class="rde-chart-title">Scatterplot</h3>
|
80
|
+
<div id="#{ dom_id }"></div>
|
81
|
+
<script type="text/javascript">
|
82
|
+
(function() {
|
83
|
+
var spec = {
|
84
|
+
"width": 800,
|
85
|
+
"height": 200,
|
86
|
+
"data": [
|
87
|
+
{
|
88
|
+
"name": "table",
|
89
|
+
"values": #{ ca[:values].to_json }
|
90
|
+
},
|
91
|
+
],
|
92
|
+
"scales": [
|
93
|
+
{
|
94
|
+
"name": "x",
|
95
|
+
"nice": true,
|
96
|
+
"range": "width",
|
97
|
+
"zero": false,
|
98
|
+
"domain": {"data": "table", "field": "data.x"}
|
99
|
+
},
|
100
|
+
{
|
101
|
+
"name": "y",
|
102
|
+
"nice": true,
|
103
|
+
"range": "height",
|
104
|
+
"zero": false,
|
105
|
+
"domain": {"data": "table", "field": "data.y"}
|
106
|
+
},
|
107
|
+
// {
|
108
|
+
// "name": "c",
|
109
|
+
// "type": "ordinal",
|
110
|
+
// "domain": {"data": "iris", "field": "data.species"},
|
111
|
+
// "range": ["#800", "#080", "#008"]
|
112
|
+
// }
|
113
|
+
],
|
114
|
+
"axes": [
|
115
|
+
{
|
116
|
+
"type": "x",
|
117
|
+
"scale": "x",
|
118
|
+
"offset": 5,
|
119
|
+
"title": "#{ ca[:x_axis_label] }",
|
120
|
+
},
|
121
|
+
{
|
122
|
+
"type": "y",
|
123
|
+
"scale": "y",
|
124
|
+
"offset": 5,
|
125
|
+
"title": "#{ ca[:y_axis_label] }",
|
126
|
+
}
|
127
|
+
],
|
128
|
+
// "legends": [
|
129
|
+
// {
|
130
|
+
// "fill": "c",
|
131
|
+
// "title": "Species",
|
132
|
+
// "offset": 0,
|
133
|
+
// "properties": {
|
134
|
+
// "symbols": {
|
135
|
+
// "fillOpacity": {"value": 0.5},
|
136
|
+
// "stroke": {"value": "transparent"}
|
137
|
+
// }
|
138
|
+
// }
|
139
|
+
// }
|
140
|
+
// ],
|
141
|
+
"marks": [
|
142
|
+
{
|
143
|
+
"type": "symbol",
|
144
|
+
"from": {"data": "table"},
|
145
|
+
"properties": {
|
146
|
+
"enter": {
|
147
|
+
"x": {"scale": "x", "field": "data.x"},
|
148
|
+
"y": {"scale": "y", "field": "data.y"},
|
149
|
+
//"fill": {"scale": "c", "field": "data.species"},
|
150
|
+
"fill": { "value": "#1F77B4" },
|
151
|
+
"fillOpacity": {"value": 0.4},
|
152
|
+
},
|
153
|
+
"update": {
|
154
|
+
"size": {"value": 30},
|
155
|
+
"stroke": {"value": "transparent"}
|
156
|
+
},
|
157
|
+
}
|
158
|
+
}
|
159
|
+
]
|
160
|
+
};
|
161
|
+
|
162
|
+
vg.parse.spec(spec, function(chart) {
|
163
|
+
var view = chart({ el:"##{ dom_id }" }).update();
|
164
|
+
});
|
165
|
+
|
166
|
+
})();
|
167
|
+
</script>
|
168
|
+
</div>
|
169
|
+
)
|
170
|
+
end
|
171
|
+
|
172
|
+
def render_nvd3(ca)
|
71
173
|
%(
|
72
174
|
<div class="rde-chart rde-scatterplot">
|
73
175
|
<h3 class="rde-chart-title">Scatterplot</h3>
|
@@ -76,7 +178,7 @@ class RailsDataExplorer
|
|
76
178
|
</div>
|
77
179
|
<script type="text/javascript">
|
78
180
|
(function() {
|
79
|
-
var data = #{
|
181
|
+
var data = #{ ca[:values].to_json };
|
80
182
|
|
81
183
|
nv.addGraph(function() {
|
82
184
|
var chart = nv.models.scatterChart()
|
@@ -87,12 +189,12 @@ class RailsDataExplorer
|
|
87
189
|
.transitionDuration(300)
|
88
190
|
;
|
89
191
|
|
90
|
-
chart.xAxis.tickFormat(#{
|
91
|
-
.axisLabel('#{
|
192
|
+
chart.xAxis.tickFormat(#{ ca[:x_axis_tick_format] })
|
193
|
+
.axisLabel('#{ ca[:x_axis_label] }')
|
92
194
|
;
|
93
195
|
|
94
|
-
chart.yAxis.tickFormat(#{
|
95
|
-
.axisLabel('#{
|
196
|
+
chart.yAxis.tickFormat(#{ ca[:y_axis_tick_format] })
|
197
|
+
.axisLabel('#{ ca[:y_axis_label] }')
|
96
198
|
;
|
97
199
|
|
98
200
|
chart.tooltipContent(function(key) {
|