nvd3-rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (167) hide show
  1. data/.gitmodules +3 -0
  2. data/README.md +101 -0
  3. data/lib/nvd3-rails.rb +1 -0
  4. data/lib/nvd3/rails.rb +8 -0
  5. data/lib/nvd3/rails/engine.rb +6 -0
  6. data/lib/nvd3/rails/version.rb +5 -0
  7. data/nvd3-rails.gemspec +21 -0
  8. data/vendor/assets/javascripts/nvd3-rails.js +7 -0
  9. data/vendor/assets/javascripts/nvd3/.git.sample/HEAD +1 -0
  10. data/vendor/assets/javascripts/nvd3/.git.sample/config +13 -0
  11. data/vendor/assets/javascripts/nvd3/.git.sample/description +1 -0
  12. data/vendor/assets/javascripts/nvd3/.git.sample/hooks/applypatch-msg.sample +15 -0
  13. data/vendor/assets/javascripts/nvd3/.git.sample/hooks/commit-msg.sample +24 -0
  14. data/vendor/assets/javascripts/nvd3/.git.sample/hooks/post-update.sample +8 -0
  15. data/vendor/assets/javascripts/nvd3/.git.sample/hooks/pre-applypatch.sample +14 -0
  16. data/vendor/assets/javascripts/nvd3/.git.sample/hooks/pre-commit.sample +50 -0
  17. data/vendor/assets/javascripts/nvd3/.git.sample/hooks/pre-push.sample +53 -0
  18. data/vendor/assets/javascripts/nvd3/.git.sample/hooks/pre-rebase.sample +169 -0
  19. data/vendor/assets/javascripts/nvd3/.git.sample/hooks/prepare-commit-msg.sample +36 -0
  20. data/vendor/assets/javascripts/nvd3/.git.sample/hooks/update.sample +128 -0
  21. data/vendor/assets/javascripts/nvd3/.git.sample/index +0 -0
  22. data/vendor/assets/javascripts/nvd3/.git.sample/info/exclude +6 -0
  23. data/vendor/assets/javascripts/nvd3/.git.sample/logs/HEAD +1 -0
  24. data/vendor/assets/javascripts/nvd3/.git.sample/logs/refs/heads/master +1 -0
  25. data/vendor/assets/javascripts/nvd3/.git.sample/logs/refs/remotes/origin/HEAD +1 -0
  26. data/vendor/assets/javascripts/nvd3/.git.sample/objects/pack/pack-babbb312d58dd7f03870b530a1b9a84c80918be3.idx +0 -0
  27. data/vendor/assets/javascripts/nvd3/.git.sample/objects/pack/pack-babbb312d58dd7f03870b530a1b9a84c80918be3.pack +0 -0
  28. data/vendor/assets/javascripts/nvd3/.git.sample/packed-refs +5 -0
  29. data/vendor/assets/javascripts/nvd3/.git.sample/refs/heads/master +1 -0
  30. data/vendor/assets/javascripts/nvd3/.git.sample/refs/remotes/origin/HEAD +1 -0
  31. data/vendor/assets/javascripts/nvd3/.gitignore +24 -0
  32. data/vendor/assets/javascripts/nvd3/LICENSE.md +49 -0
  33. data/vendor/assets/javascripts/nvd3/Makefile +56 -0
  34. data/vendor/assets/javascripts/nvd3/README.md +43 -0
  35. data/vendor/assets/javascripts/nvd3/build.bat +6 -0
  36. data/vendor/assets/javascripts/nvd3/deprecated/bar.html +198 -0
  37. data/vendor/assets/javascripts/nvd3/deprecated/bar.js +250 -0
  38. data/vendor/assets/javascripts/nvd3/deprecated/charts/cumulativeLineChart.js +174 -0
  39. data/vendor/assets/javascripts/nvd3/deprecated/charts/discreteBarChart.js +157 -0
  40. data/vendor/assets/javascripts/nvd3/deprecated/charts/lineChart.js +159 -0
  41. data/vendor/assets/javascripts/nvd3/deprecated/charts/lineChartDaily.js +168 -0
  42. data/vendor/assets/javascripts/nvd3/deprecated/charts/stackedAreaChart.js +177 -0
  43. data/vendor/assets/javascripts/nvd3/deprecated/cumulativeLine.html +171 -0
  44. data/vendor/assets/javascripts/nvd3/deprecated/cumulativeLine.js +334 -0
  45. data/vendor/assets/javascripts/nvd3/deprecated/discreteBarChartWithEnabledTooltip.html +129 -0
  46. data/vendor/assets/javascripts/nvd3/deprecated/discreteBarChartWithEnabledTooltip.js +222 -0
  47. data/vendor/assets/javascripts/nvd3/deprecated/discreteBarWithAxes.html +172 -0
  48. data/vendor/assets/javascripts/nvd3/deprecated/discreteBarWithAxes.js +152 -0
  49. data/vendor/assets/javascripts/nvd3/deprecated/lineChart-old.html +83 -0
  50. data/vendor/assets/javascripts/nvd3/deprecated/lineChartDaily.html +109 -0
  51. data/vendor/assets/javascripts/nvd3/deprecated/linePlusBar.html +173 -0
  52. data/vendor/assets/javascripts/nvd3/deprecated/linePlusBar.js +250 -0
  53. data/vendor/assets/javascripts/nvd3/deprecated/lineWithFocus.html +137 -0
  54. data/vendor/assets/javascripts/nvd3/deprecated/lineWithFocus.js +354 -0
  55. data/vendor/assets/javascripts/nvd3/deprecated/lineWithFourAxes.html +144 -0
  56. data/vendor/assets/javascripts/nvd3/deprecated/lineWithFourAxes.js +218 -0
  57. data/vendor/assets/javascripts/nvd3/deprecated/lineWithLegend.html +142 -0
  58. data/vendor/assets/javascripts/nvd3/deprecated/lineWithLegend.js +176 -0
  59. data/vendor/assets/javascripts/nvd3/deprecated/monthendAxis.html +99 -0
  60. data/vendor/assets/javascripts/nvd3/deprecated/multiBarHorizontalWithLegend.html +258 -0
  61. data/vendor/assets/javascripts/nvd3/deprecated/multiBarHorizontalWithLegend.js +226 -0
  62. data/vendor/assets/javascripts/nvd3/deprecated/multiBarWithLegend.html +162 -0
  63. data/vendor/assets/javascripts/nvd3/deprecated/multiBarWithLegend.js +249 -0
  64. data/vendor/assets/javascripts/nvd3/deprecated/pie.js +263 -0
  65. data/vendor/assets/javascripts/nvd3/deprecated/scatterChart.html +110 -0
  66. data/vendor/assets/javascripts/nvd3/deprecated/scatterChart.js +294 -0
  67. data/vendor/assets/javascripts/nvd3/deprecated/scatterFisheyeChart.js +418 -0
  68. data/vendor/assets/javascripts/nvd3/deprecated/scatterWithLegend.html +167 -0
  69. data/vendor/assets/javascripts/nvd3/deprecated/scatterWithLegend.js +261 -0
  70. data/vendor/assets/javascripts/nvd3/deprecated/stackedArea.js +286 -0
  71. data/vendor/assets/javascripts/nvd3/deprecated/stackedAreaChart.html +183 -0
  72. data/vendor/assets/javascripts/nvd3/deprecated/stackedAreaChart_old.html +137 -0
  73. data/vendor/assets/javascripts/nvd3/deprecated/stackedAreaWithLegend.html +222 -0
  74. data/vendor/assets/javascripts/nvd3/deprecated/stackedAreaWithLegend.js +297 -0
  75. data/vendor/assets/javascripts/nvd3/examples/bullet.html +96 -0
  76. data/vendor/assets/javascripts/nvd3/examples/bulletChart.html +94 -0
  77. data/vendor/assets/javascripts/nvd3/examples/crossfilter.html +167 -0
  78. data/vendor/assets/javascripts/nvd3/examples/crossfilterWithDimentions.html +180 -0
  79. data/vendor/assets/javascripts/nvd3/examples/crossfilterWithTables.html +288 -0
  80. data/vendor/assets/javascripts/nvd3/examples/cumulativeLineChart.html +155 -0
  81. data/vendor/assets/javascripts/nvd3/examples/discreteBarChart.html +116 -0
  82. data/vendor/assets/javascripts/nvd3/examples/dynamicTimeSeries.html +148 -0
  83. data/vendor/assets/javascripts/nvd3/examples/historicalBar.html +157 -0
  84. data/vendor/assets/javascripts/nvd3/examples/horizon.html +163 -0
  85. data/vendor/assets/javascripts/nvd3/examples/images/grey-minus.png +0 -0
  86. data/vendor/assets/javascripts/nvd3/examples/images/grey-plus.png +0 -0
  87. data/vendor/assets/javascripts/nvd3/examples/indentedtree.html +126 -0
  88. data/vendor/assets/javascripts/nvd3/examples/legend.html +75 -0
  89. data/vendor/assets/javascripts/nvd3/examples/line.html +95 -0
  90. data/vendor/assets/javascripts/nvd3/examples/lineChart.html +112 -0
  91. data/vendor/assets/javascripts/nvd3/examples/lineChartSVGResize.html +151 -0
  92. data/vendor/assets/javascripts/nvd3/examples/linePlusBarChart.html +114 -0
  93. data/vendor/assets/javascripts/nvd3/examples/linePlusBarWithFocusChart.html +128 -0
  94. data/vendor/assets/javascripts/nvd3/examples/lineTimeSeries.html +142 -0
  95. data/vendor/assets/javascripts/nvd3/examples/lineWithFisheyeChart.html +101 -0
  96. data/vendor/assets/javascripts/nvd3/examples/lineWithFocusChart.html +87 -0
  97. data/vendor/assets/javascripts/nvd3/examples/multiBar.html +92 -0
  98. data/vendor/assets/javascripts/nvd3/examples/multiBarChart.html +93 -0
  99. data/vendor/assets/javascripts/nvd3/examples/multiBarHorizontalChart.html +388 -0
  100. data/vendor/assets/javascripts/nvd3/examples/multiChart.html +93 -0
  101. data/vendor/assets/javascripts/nvd3/examples/nations.json +1 -0
  102. data/vendor/assets/javascripts/nvd3/examples/pie.html +93 -0
  103. data/vendor/assets/javascripts/nvd3/examples/pieChart.html +114 -0
  104. data/vendor/assets/javascripts/nvd3/examples/scatter.html +95 -0
  105. data/vendor/assets/javascripts/nvd3/examples/scatterChart.html +115 -0
  106. data/vendor/assets/javascripts/nvd3/examples/scatterPlusLineChart.html +116 -0
  107. data/vendor/assets/javascripts/nvd3/examples/sparkline.html +62 -0
  108. data/vendor/assets/javascripts/nvd3/examples/sparklinePlus.html +67 -0
  109. data/vendor/assets/javascripts/nvd3/examples/stackedArea.html +155 -0
  110. data/vendor/assets/javascripts/nvd3/examples/stackedAreaChart.html +245 -0
  111. data/vendor/assets/javascripts/nvd3/examples/stream_layers.js +35 -0
  112. data/vendor/assets/javascripts/nvd3/lib/cie.js +155 -0
  113. data/vendor/assets/javascripts/nvd3/lib/crossfilter.js +1180 -0
  114. data/vendor/assets/javascripts/nvd3/lib/crossfilter.min.js +1 -0
  115. data/vendor/assets/javascripts/nvd3/lib/d3.v2.js +7033 -0
  116. data/vendor/assets/javascripts/nvd3/lib/d3.v2.min.js +4 -0
  117. data/vendor/assets/javascripts/nvd3/lib/fisheye.js +86 -0
  118. data/vendor/assets/javascripts/nvd3/lib/hive.js +80 -0
  119. data/vendor/assets/javascripts/nvd3/lib/horizon.js +192 -0
  120. data/vendor/assets/javascripts/nvd3/lib/sankey.js +292 -0
  121. data/vendor/assets/javascripts/nvd3/nv.d3.js +11762 -0
  122. data/vendor/assets/javascripts/nvd3/src/core.js +117 -0
  123. data/vendor/assets/javascripts/nvd3/src/models/axis.js +398 -0
  124. data/vendor/assets/javascripts/nvd3/src/models/backup/bullet.js +250 -0
  125. data/vendor/assets/javascripts/nvd3/src/models/backup/bulletChart.js +349 -0
  126. data/vendor/assets/javascripts/nvd3/src/models/bullet.js +377 -0
  127. data/vendor/assets/javascripts/nvd3/src/models/bulletChart.js +341 -0
  128. data/vendor/assets/javascripts/nvd3/src/models/cumulativeLineChart.js +609 -0
  129. data/vendor/assets/javascripts/nvd3/src/models/discreteBar.js +327 -0
  130. data/vendor/assets/javascripts/nvd3/src/models/discreteBarChart.js +290 -0
  131. data/vendor/assets/javascripts/nvd3/src/models/distribution.js +146 -0
  132. data/vendor/assets/javascripts/nvd3/src/models/historicalBar.js +289 -0
  133. data/vendor/assets/javascripts/nvd3/src/models/indentedTree.js +306 -0
  134. data/vendor/assets/javascripts/nvd3/src/models/legend.js +203 -0
  135. data/vendor/assets/javascripts/nvd3/src/models/line.js +286 -0
  136. data/vendor/assets/javascripts/nvd3/src/models/lineChart.js +359 -0
  137. data/vendor/assets/javascripts/nvd3/src/models/lineDynTimeSeriesChart.js +434 -0
  138. data/vendor/assets/javascripts/nvd3/src/models/linePlusBarChart.js +422 -0
  139. data/vendor/assets/javascripts/nvd3/src/models/linePlusBarWithFocusChart.js +657 -0
  140. data/vendor/assets/javascripts/nvd3/src/models/lineTimeSeriesChart.js +340 -0
  141. data/vendor/assets/javascripts/nvd3/src/models/lineWithFisheye.js +197 -0
  142. data/vendor/assets/javascripts/nvd3/src/models/lineWithFisheyeChart.js +324 -0
  143. data/vendor/assets/javascripts/nvd3/src/models/lineWithFocusChart.js +565 -0
  144. data/vendor/assets/javascripts/nvd3/src/models/multiAxisLineChart.js +312 -0
  145. data/vendor/assets/javascripts/nvd3/src/models/multiBar.js +416 -0
  146. data/vendor/assets/javascripts/nvd3/src/models/multiBarChart.js +445 -0
  147. data/vendor/assets/javascripts/nvd3/src/models/multiBarHorizontal.js +420 -0
  148. data/vendor/assets/javascripts/nvd3/src/models/multiBarHorizontalChart.js +415 -0
  149. data/vendor/assets/javascripts/nvd3/src/models/multiBarTimeSeries.js +371 -0
  150. data/vendor/assets/javascripts/nvd3/src/models/multiBarTimeSeriesChart.js +403 -0
  151. data/vendor/assets/javascripts/nvd3/src/models/multiChart.js +444 -0
  152. data/vendor/assets/javascripts/nvd3/src/models/ohlcBar.js +365 -0
  153. data/vendor/assets/javascripts/nvd3/src/models/pie.js +358 -0
  154. data/vendor/assets/javascripts/nvd3/src/models/pieChart.js +281 -0
  155. data/vendor/assets/javascripts/nvd3/src/models/scatter.js +622 -0
  156. data/vendor/assets/javascripts/nvd3/src/models/scatterChart.js +576 -0
  157. data/vendor/assets/javascripts/nvd3/src/models/scatterPlusLineChart.js +577 -0
  158. data/vendor/assets/javascripts/nvd3/src/models/sparkline.js +179 -0
  159. data/vendor/assets/javascripts/nvd3/src/models/sparklinePlus.js +291 -0
  160. data/vendor/assets/javascripts/nvd3/src/models/stackedArea.js +336 -0
  161. data/vendor/assets/javascripts/nvd3/src/models/stackedAreaChart.js +453 -0
  162. data/vendor/assets/javascripts/nvd3/src/nv.d3.css +671 -0
  163. data/vendor/assets/javascripts/nvd3/src/tooltip.js +129 -0
  164. data/vendor/assets/javascripts/nvd3/src/utils.js +105 -0
  165. data/vendor/assets/javascripts/set-nvd3-env.js.erb +5 -0
  166. data/vendor/assets/stylesheets/nvd3-rails.css +3 -0
  167. metadata +233 -0
@@ -0,0 +1,250 @@
1
+
2
+ nv.models.linePlusBar = function() {
3
+ var margin = {top: 30, right: 60, bottom: 50, left: 60},
4
+ getWidth = function() { return 960 },
5
+ getHeight = function() { return 500 },
6
+ dotRadius = function() { return 2.5 },
7
+ getX = function(d) { return d.x },
8
+ getY = function(d) { return d.y },
9
+ color = d3.scale.category20().range(),
10
+ dispatch = d3.dispatch('tooltipShow', 'tooltipHide');
11
+
12
+ var x = d3.scale.linear(),
13
+ y1 = d3.scale.linear(),
14
+ y2 = d3.scale.linear(),
15
+ xAxis = nv.models.axis().scale(x).orient('bottom'),
16
+ yAxis1 = nv.models.axis().scale(y1).orient('left'),
17
+ yAxis2 = nv.models.axis().scale(y2).orient('right'),
18
+ legend = nv.models.legend().height(30),
19
+ lines = nv.models.line(),
20
+ bars = nv.models.historicalBar();
21
+
22
+
23
+ function chart(selection) {
24
+ selection.each(function(data) {
25
+ var width = getWidth(),
26
+ height = getHeight(),
27
+ availableWidth = width - margin.left - margin.right,
28
+ availableHeight = height - margin.top - margin.bottom;
29
+
30
+ var series1 = data.filter(function(d) { return !d.disabled && d.bar })
31
+ .map(function(d) {
32
+ return d.values.map(function(d,i) {
33
+ return { x: getX(d,i), y: getY(d,i) }
34
+ })
35
+ });
36
+
37
+ var series2 = data.filter(function(d) { return !d.disabled && !d.bar })
38
+ .map(function(d) {
39
+ return d.values.map(function(d,i) {
40
+ return { x: getX(d,i), y: getY(d,i) }
41
+ })
42
+ });
43
+
44
+ x .domain(d3.extent(d3.merge(series1.concat(series2)), function(d) { return d.x } ))
45
+ .range([0, availableWidth]);
46
+
47
+ y1 .domain(d3.extent(d3.merge(series1), function(d) { return d.y } ))
48
+ .range([availableHeight, 0]);
49
+
50
+ y2 .domain(d3.extent(d3.merge(series2), function(d) { return d.y } ))
51
+ .range([availableHeight, 0]);
52
+
53
+ lines
54
+ .width(availableWidth)
55
+ .height(availableHeight)
56
+ .color(data.map(function(d,i) {
57
+ return d.color || color[i % 10];
58
+ }).filter(function(d,i) { return !data[i].disabled && !data[i].bar }))
59
+
60
+ bars
61
+ .width(availableWidth)
62
+ .height(availableHeight)
63
+ .color(data.map(function(d,i) {
64
+ return d.color || color[i % 10];
65
+ }).filter(function(d,i) { return !data[i].disabled && data[i].bar }))
66
+
67
+
68
+ var wrap = d3.select(this).selectAll('g.wrap.linePlusBar').data([data]);
69
+ var gEnter = wrap.enter().append('g').attr('class', 'wrap nvd3 linePlusBar').append('g');
70
+
71
+ gEnter.append('g').attr('class', 'x axis');
72
+ gEnter.append('g').attr('class', 'y1 axis');
73
+ gEnter.append('g').attr('class', 'y2 axis');
74
+ gEnter.append('g').attr('class', 'barsWrap');
75
+ gEnter.append('g').attr('class', 'linesWrap');
76
+ gEnter.append('g').attr('class', 'legendWrap');
77
+
78
+
79
+ legend.dispatch.on('legendClick', function(d,i) {
80
+ d.disabled = !d.disabled;
81
+
82
+ if (!data.filter(function(d) { return !d.disabled }).length) {
83
+ data.map(function(d) {
84
+ d.disabled = false;
85
+ wrap.selectAll('.series').classed('disabled', false);
86
+ return d;
87
+ });
88
+ }
89
+
90
+ selection.transition().call(chart);
91
+ });
92
+
93
+
94
+ lines.dispatch.on('elementMouseover.tooltip', function(e) {
95
+ dispatch.tooltipShow({
96
+ point: e.point,
97
+ series: e.series,
98
+ pos: [e.pos[0] + margin.left, e.pos[1] + margin.top],
99
+ seriesIndex: e.seriesIndex,
100
+ pointIndex: e.pointIndex
101
+ });
102
+ });
103
+
104
+ lines.dispatch.on('elementMouseout.tooltip', function(e) {
105
+ dispatch.tooltipHide(e);
106
+ });
107
+
108
+
109
+
110
+ bars.dispatch.on('elementMouseover.tooltip', function(e) {
111
+ e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
112
+ dispatch.tooltipShow(e);
113
+ });
114
+
115
+ bars.dispatch.on('elementMouseout.tooltip', function(e) {
116
+ dispatch.tooltipHide(e);
117
+ });
118
+
119
+
120
+
121
+ //TODO: margins should be adjusted based on what components are used: axes, axis labels, legend
122
+ margin.top = legend.height();
123
+
124
+ var g = wrap.select('g')
125
+ .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
126
+
127
+
128
+ legend.width(width/2 - margin.right);
129
+
130
+ g.select('.legendWrap')
131
+ .datum(data.map(function(series) {
132
+ series.key = series.key + (series.bar ? ' (left axis)' : ' (right axis)');
133
+ return series;
134
+ }))
135
+ .attr('transform', 'translate(' + (width/2 - margin.left) + ',' + (-margin.top) +')')
136
+ .call(legend);
137
+
138
+
139
+ var barsData = data.filter(function(d) { return !d.disabled && d.bar });
140
+
141
+ var barsWrap = g.select('.barsWrap')
142
+ .datum(barsData.length ? barsData : [{values:[]}])
143
+ //.datum(data.filter(function(d) { return !d.disabled && d.bar }))
144
+
145
+ var linesWrap = g.select('.linesWrap')
146
+ .datum(data.filter(function(d) { return !d.disabled && !d.bar }))
147
+
148
+
149
+ d3.transition(barsWrap).call(bars);
150
+ d3.transition(linesWrap).call(lines);
151
+
152
+
153
+ xAxis
154
+ .domain(x.domain())
155
+ .range(x.range())
156
+ .ticks( width / 100 )
157
+ .tickSize(-availableHeight, 0);
158
+
159
+ g.select('.x.axis')
160
+ .attr('transform', 'translate(0,' + y1.range()[0] + ')');
161
+ d3.transition(g.select('.x.axis'))
162
+ .call(xAxis);
163
+
164
+ yAxis1
165
+ .domain(y1.domain())
166
+ .range(y1.range())
167
+ .ticks( height / 36 )
168
+ .tickSize(-availableWidth, 0);
169
+
170
+ d3.transition(g.select('.y1.axis'))
171
+ .call(yAxis1);
172
+
173
+ yAxis2
174
+ .domain(y2.domain())
175
+ .range(y2.range())
176
+ .ticks( height / 36 )
177
+ .tickSize(series1.length ? 0 : -availableWidth, 0); // Show the y2 rules only if y1 has none
178
+
179
+ g.select('.y2.axis')
180
+ .attr('transform', 'translate(' + x.range()[1] + ',0)');
181
+
182
+ d3.transition(g.select('.y2.axis'))
183
+ .call(yAxis2);
184
+
185
+ });
186
+
187
+ return chart;
188
+ }
189
+
190
+ chart.dispatch = dispatch;
191
+ chart.legend = legend;
192
+ chart.lines = lines;
193
+ chart.bars = bars;
194
+ chart.xAxis = xAxis;
195
+ chart.yAxis1 = yAxis1;
196
+ chart.yAxis2 = yAxis2;
197
+
198
+ //d3.rebind(chart, lines, 'interactive');
199
+ //consider rebinding x and y as well
200
+
201
+ chart.x = function(_) {
202
+ if (!arguments.length) return getX;
203
+ getX = _;
204
+ lines.x(_);
205
+ bars.x(_);
206
+ return chart;
207
+ };
208
+
209
+ chart.y = function(_) {
210
+ if (!arguments.length) return getY;
211
+ getY = _;
212
+ lines.y(_);
213
+ bars.y(_);
214
+ return chart;
215
+ };
216
+
217
+ chart.margin = function(_) {
218
+ if (!arguments.length) return margin;
219
+ margin = _;
220
+ return chart;
221
+ };
222
+
223
+ chart.width = function(_) {
224
+ if (!arguments.length) return getWidth;
225
+ getWidth = d3.functor(_);
226
+ return chart;
227
+ };
228
+
229
+ chart.height = function(_) {
230
+ if (!arguments.length) return getHeight;
231
+ getHeight = d3.functor(_);
232
+ return chart;
233
+ };
234
+
235
+ chart.dotRadius = function(_) {
236
+ if (!arguments.length) return dotRadius;
237
+ dotRadius = d3.functor(_);
238
+ lines.dotRadius = _;
239
+ return chart;
240
+ };
241
+
242
+ chart.color = function(_) {
243
+ if (!arguments.length) return color;
244
+ color = _;
245
+ legend.color(_);
246
+ return chart;
247
+ };
248
+
249
+ return chart;
250
+ }
@@ -0,0 +1,137 @@
1
+ <!DOCTYPE html>
2
+ <meta charset="utf-8">
3
+
4
+ <link href="../src/d3.css" rel="stylesheet" type="text/css">
5
+
6
+ <style>
7
+
8
+
9
+ body {
10
+ overflow-y:scroll;
11
+ }
12
+
13
+ text {
14
+ font: 12px sans-serif;
15
+ }
16
+
17
+ </style>
18
+ <body>
19
+
20
+ <div id="test1">
21
+ <svg></svg>
22
+ </div>
23
+
24
+ <script src="../lib/d3.v2.js"></script>
25
+ <script src="../nv.d3.js"></script>
26
+ <script src="../src/tooltip.js"></script>
27
+ <script src="../src/models/legend.js"></script>
28
+ <script src="../src/models/axis.js"></script>
29
+ <script src="../src/models/scatter.js"></script>
30
+ <script src="../src/models/line.js"></script>
31
+ <script src="../src/models/lineWithFocus.js"></script>
32
+ <script src="stream_layers.js"></script>
33
+ <script>
34
+
35
+ var test_data = stream_layers(3,128,.1).map(function(data, i) {
36
+ return {
37
+ key: 'Stream' + i,
38
+ values: data
39
+ };
40
+ });
41
+
42
+ nv.addGraph({
43
+ generate: function() {
44
+ var width = nv.utils.windowSize().width - 40,
45
+ height = nv.utils.windowSize().height - 40;
46
+
47
+ var chart = nv.models.lineWithFocus()
48
+ .width(width)
49
+ .height(height)
50
+ .yTickFormat(d3.format('.2r'))
51
+ .xTickFormat(d3.format('.2r'))
52
+
53
+
54
+ var svg = d3.select('#test1 svg')
55
+ .attr('width', width)
56
+ .attr('height', height)
57
+ .datum(test_data);
58
+
59
+ svg.transition().duration(500).call(chart);
60
+
61
+ return chart;
62
+ },
63
+ callback: function(graph) {
64
+
65
+ graph.dispatch.on('tooltipShow', function(e) {
66
+ var offsetElement = document.getElementById("test1"),
67
+ left = e.pos[0] + offsetElement.offsetLeft,
68
+ top = e.pos[1] + offsetElement.offsetTop,
69
+ formatter = d3.format('.2r');
70
+
71
+ var content = '<h3>' + e.series.key + '</h3>' +
72
+ '<p>' +
73
+ formatter(graph.y()(e.point)) + ', ' + formatter(graph.x()(e.point)) +
74
+ '</p>';
75
+
76
+ nv.tooltip.show([left, top], content);
77
+ });
78
+
79
+ graph.dispatch.on('tooltipHide', function(e) {
80
+ nv.tooltip.cleanup();
81
+ });
82
+
83
+
84
+
85
+ window.onresize = function() {
86
+ var width = nv.utils.windowSize().width - 40,
87
+ height = nv.utils.windowSize().height - 40,
88
+ margin = graph.margin();
89
+
90
+
91
+ if (width < margin.left + margin.right + 20)
92
+ width = margin.left + margin.right + 20;
93
+
94
+ if (height < margin.top + margin.bottom + 20)
95
+ height = margin.top + margin.bottom + 20;
96
+
97
+
98
+ graph
99
+ .width(width)
100
+ .height(height);
101
+
102
+ d3.select('#test1 svg')
103
+ .attr('width', width)
104
+ .attr('height', height)
105
+ .call(graph);
106
+
107
+ };
108
+ }
109
+ });
110
+
111
+
112
+
113
+ function sinAndCos() {
114
+ var sin = [],
115
+ cos = [];
116
+
117
+ for (var i = 0; i < 100; i++) {
118
+ sin.push({x: i, y: Math.sin(i/10)});
119
+ cos.push({x: i, y: .5 * Math.cos(i/10)});
120
+ }
121
+
122
+ return [
123
+ {
124
+ values: sin,
125
+ key: "Sine Wave",
126
+ color: "#ff7f0e"
127
+ },
128
+ {
129
+ values: cos,
130
+ key: "Cosine Wave",
131
+ color: "#2ca02c"
132
+ }
133
+ ];
134
+ }
135
+
136
+
137
+ </script>
@@ -0,0 +1,354 @@
1
+
2
+ nv.models.lineWithFocus = function() {
3
+ var margin = {top: 30, right: 20, bottom: 30, left: 60},
4
+ margin2 = {top: 0, right: 20, bottom: 20, left: 60},
5
+ width = 960,
6
+ height = 500,
7
+ height1 = 400,
8
+ height2 = 100,
9
+ color = d3.scale.category20().range(),
10
+ getX = function(d) { return d.x },
11
+ getY = function(d) { return d.y },
12
+ id = Math.floor(Math.random() * 10000); //Create semi-unique ID incase user doesn't select one
13
+
14
+ var x = d3.scale.linear(),
15
+ y = d3.scale.linear(),
16
+ x2 = d3.scale.linear(),
17
+ y2 = d3.scale.linear(),
18
+ xAxis = nv.models.axis().scale(x).orient('bottom'),
19
+ yAxis = nv.models.axis().scale(y).orient('left'),
20
+ xAxis2 = nv.models.axis().scale(x2).orient('bottom'),
21
+ yAxis2 = nv.models.axis().scale(y2).orient('left'),
22
+ legend = nv.models.legend().height(30),
23
+ focus = nv.models.line().clipEdge(true),
24
+ context = nv.models.line().interactive(false),
25
+ dispatch = d3.dispatch('tooltipShow', 'tooltipHide'),
26
+ brush = d3.svg.brush()
27
+ .x(x2);
28
+
29
+
30
+ //var wrap, gEnter, g, focus, focusLines, contextWrap, focusWrap, contextLines; //brought all variables to this scope for use within brush function... is this a bad idea?
31
+
32
+ //var seriesData; //Temporarily bringing this data to this scope.... may be bad idea (same with above).. may need to rethink brushing
33
+
34
+ function chart(selection) {
35
+ selection.each(function(data) {
36
+ var seriesData = data.filter(function(d) { return !d.disabled })
37
+ .map(function(d) { return d.values }),
38
+ availableWidth = width - margin.left - margin.right,
39
+ availableHeight1 = height1 - margin.top - margin.bottom,
40
+ availableHeight2 = height2 - margin2.top - margin2.bottom;
41
+
42
+ x2 .domain(d3.extent(d3.merge(seriesData), getX ))
43
+ .range([0, availableWidth]);
44
+ y2 .domain(d3.extent(d3.merge(seriesData), getY ))
45
+ .range([availableHeight2, 0]);
46
+
47
+ x .domain(brush.empty() ? x2.domain() : brush.extent())
48
+ .range([0, availableWidth]);
49
+ y .domain(y2.domain())
50
+ .range([availableHeight1, 0]);
51
+
52
+ brush.on('brush', onBrush);
53
+
54
+ focus
55
+ .width(availableWidth)
56
+ .height(availableHeight1)
57
+ .color(data.map(function(d,i) {
58
+ return d.color || color[i % 10];
59
+ }).filter(function(d,i) { return !data[i].disabled }))
60
+
61
+ context
62
+ .width(availableWidth)
63
+ .height(availableHeight2)
64
+ .color(data.map(function(d,i) {
65
+ return d.color || color[i % 10];
66
+ }).filter(function(d,i) { return !data[i].disabled }))
67
+
68
+
69
+ updateFocus();
70
+
71
+
72
+ var wrap = d3.select(this).selectAll('g.wrap').data([data]);
73
+ var gEnter = wrap.enter().append('g').attr('class', 'wrap nvd3 lineWithFocus').append('g');
74
+
75
+ gEnter.append('g').attr('class', 'focus');
76
+ gEnter.append('g').attr('class', 'context');
77
+ gEnter.append('g').attr('class', 'legendWrap');
78
+
79
+
80
+
81
+ var g = wrap.select('g')
82
+ //.attr('transform', 'translate(0,0)');
83
+
84
+
85
+
86
+
87
+ // ********** LEGEND **********
88
+
89
+ legend.width(width/2 - margin.right);
90
+
91
+ g.select('.legendWrap')
92
+ .datum(data)
93
+ .attr('transform', 'translate(' + (availableWidth / 2) + ',0)')
94
+ .call(legend);
95
+
96
+
97
+ //TODO: margins should be adjusted based on what components are used: axes, axis labels, legend
98
+ margin.top = legend.height();
99
+
100
+
101
+
102
+
103
+ // ********** FOCUS **********
104
+
105
+ var focusWrap = g.select('.focus')
106
+ .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
107
+
108
+ gEnter.select('.focus').append('g').attr('class', 'x axis');
109
+ gEnter.select('.focus').append('g').attr('class', 'y axis');
110
+ gEnter.select('.focus').append('g').attr('class', 'focusLines');
111
+
112
+
113
+ var focusLines = focusWrap.select('.focusLines')
114
+ .datum(data.filter(function(d) { return !d.disabled }))
115
+
116
+ d3.transition(focusLines).call(focus);
117
+
118
+
119
+ xAxis
120
+ .domain(x.domain())
121
+ .range(x.range())
122
+ .ticks( width / 100 )
123
+ .tickSize(-(availableHeight1), 0);
124
+
125
+ focusWrap.select('.x.axis')
126
+ .attr('transform', 'translate(0,' + y.range()[0] + ')');
127
+ d3.transition(g.select('.x.axis'))
128
+ .call(xAxis);
129
+
130
+ yAxis
131
+ .domain(y.domain())
132
+ .range(y.range())
133
+ .ticks( height / 36 )
134
+ .tickSize(-(availableWidth), 0);
135
+
136
+ d3.transition(g.select('.y.axis'))
137
+ .call(yAxis);
138
+
139
+
140
+
141
+
142
+ // ********** CONTEXT **********
143
+
144
+ var contextWrap = g.select('.context')
145
+ .attr('transform', 'translate(' + margin2.left + ',' + height1 + ')');
146
+
147
+ gEnter.select('.context').append('g').attr('class', 'x2 axis');
148
+ gEnter.select('.context').append('g').attr('class', 'y2 axis');
149
+ gEnter.select('.context').append('g').attr('class', 'contextLines');
150
+ gEnter.select('.context').append('g').attr('class', 'x brush')
151
+ .attr('class', 'x brush')
152
+ .call(brush)
153
+ .selectAll('rect')
154
+ .attr('y', -5)
155
+ .attr('height', height2 + 4);
156
+
157
+ var contextLines = contextWrap.select('.contextLines')
158
+ .datum(data.filter(function(d) { return !d.disabled }))
159
+
160
+ d3.transition(contextLines).call(context);
161
+
162
+
163
+ xAxis2
164
+ .domain(x2.domain())
165
+ .range(x2.range())
166
+ .ticks( width / 100 )
167
+ .tickSize(-(availableHeight2), 0);
168
+
169
+ contextWrap.select('.x2.axis')
170
+ .attr('transform', 'translate(0,' + y2.range()[0] + ')');
171
+ d3.transition(contextWrap.select('.x2.axis'))
172
+ .call(xAxis2);
173
+
174
+
175
+ yAxis2
176
+ .domain(y2.domain())
177
+ .range(y2.range())
178
+ .ticks( availableHeight2 / 24 )
179
+ .tickSize(-(availableWidth), 0);
180
+
181
+ contextWrap.select('.y2.axis');
182
+
183
+ d3.transition(contextWrap.select('.y2.axis'))
184
+ .call(yAxis2);
185
+
186
+
187
+
188
+
189
+
190
+
191
+ // ********** EVENT LISTENERS **********
192
+
193
+ legend.dispatch.on('legendClick', function(d,i) {
194
+ d.disabled = !d.disabled;
195
+
196
+ if (!data.filter(function(d) { return !d.disabled }).length) {
197
+ data.map(function(d) {
198
+ d.disabled = false;
199
+ wrap.selectAll('.series').classed('disabled', false);
200
+ return d;
201
+ });
202
+ }
203
+
204
+ selection.transition().call(chart);
205
+ });
206
+
207
+ /*
208
+ legend.dispatch.on('legendMouseover', function(d, i) {
209
+ d.hover = true;
210
+ selection.transition().call(chart)
211
+ });
212
+ legend.dispatch.on('legendMouseout', function(d, i) {
213
+ d.hover = false;
214
+ selection.transition().call(chart)
215
+ });
216
+ */
217
+
218
+ focus.dispatch.on('elementMouseover.tooltip', function(e) {
219
+ dispatch.tooltipShow({
220
+ point: e.point,
221
+ series: e.series,
222
+ pos: [e.pos[0] + margin.left, e.pos[1] + margin.top],
223
+ seriesIndex: e.seriesIndex,
224
+ pointIndex: e.pointIndex
225
+ });
226
+ });
227
+ focus.dispatch.on('elementMouseout.tooltip', function(e) {
228
+ dispatch.tooltipHide(e);
229
+ });
230
+
231
+
232
+
233
+
234
+
235
+ function onBrush() {
236
+ updateFocus();
237
+
238
+ focusLines.call(focus)
239
+ wrap.select('.x.axis').call(xAxis);
240
+ wrap.select('.y.axis').call(yAxis);
241
+ }
242
+
243
+ function updateFocus() {
244
+ var yDomain = brush.empty() ? y2.domain() : d3.extent(d3.merge(seriesData).filter(function(d) {
245
+ return getX(d) >= brush.extent()[0] && getX(d) <= brush.extent()[1];
246
+ }), getY); //This doesn't account for the 1 point before and the 1 point after the domain. Would fix, but likely need to change entire methodology here
247
+
248
+ if (typeof yDomain[0] == 'undefined') yDomain = y2.domain(); //incase the brush doesn't cover a single point
249
+
250
+
251
+ x.domain(brush.empty() ? x2.domain() : brush.extent());
252
+ y.domain(yDomain);
253
+
254
+ //TODO: Rethink this... performance is horrible, likely need to cut off focus data to within the range
255
+ // If I limit the data for focusLines would want to include 1 point before and after the extent,
256
+ // Need to figure out an optimized way to accomplish this.
257
+ // ***One concern is to try not to make the assumption that all lines are of the same length, and
258
+ // points with the same index have the same x value (while this is true in our test cases, may
259
+ // not always be)
260
+
261
+ focus.xDomain(x.domain());
262
+ focus.yDomain(y.domain());
263
+ }
264
+
265
+
266
+ });
267
+
268
+ return chart;
269
+ }
270
+
271
+
272
+
273
+ // ********** FUNCTIONS **********
274
+
275
+
276
+
277
+
278
+ // ********** PUBLIC ACCESSORS **********
279
+
280
+ chart.dispatch = dispatch;
281
+
282
+ chart.x = function(_) {
283
+ if (!arguments.length) return getX;
284
+ getX = _;
285
+ focus.x(_);
286
+ context.x(_);
287
+ return chart;
288
+ };
289
+
290
+ chart.y = function(_) {
291
+ if (!arguments.length) return getY;
292
+ getY = _;
293
+ focus.y(_);
294
+ context.y(_);
295
+ return chart;
296
+ };
297
+
298
+ chart.margin = function(_) {
299
+ if (!arguments.length) return margin;
300
+ margin = _;
301
+ return chart;
302
+ };
303
+
304
+ chart.width = function(_) {
305
+ if (!arguments.length) return width;
306
+ width = _;
307
+ return chart;
308
+ };
309
+
310
+ chart.height = function(_) {
311
+ if (!arguments.length) return height;
312
+ height = _;
313
+ height1 = _ - height2;
314
+ return chart;
315
+ };
316
+
317
+ chart.contextHeight = function(_) {
318
+ if (!arguments.length) return height2;
319
+ height2 = _;
320
+ height1 = height - _;
321
+ return chart;
322
+ };
323
+
324
+ chart.id = function(_) {
325
+ if (!arguments.length) return id;
326
+ id = _;
327
+ return chart;
328
+ };
329
+
330
+
331
+ // Chart has multiple similar Axes, to prevent code duplication, probably need to link all axis functions manually like below
332
+ chart.xTickFormat = function(_) {
333
+ if (!arguments.length) return x.tickFormat();
334
+ xAxis.tickFormat(_);
335
+ xAxis2.tickFormat(_);
336
+ return chart;
337
+ };
338
+
339
+ chart.yTickFormat = function(_) {
340
+ if (!arguments.length) return y.tickFormat();
341
+ yAxis.tickFormat(_);
342
+ yAxis2.tickFormat(_);
343
+ return chart;
344
+ };
345
+
346
+
347
+
348
+ //TODO: allow for both focus and context axes to be linked
349
+ chart.xAxis = xAxis;
350
+ chart.yAxis = yAxis;
351
+
352
+
353
+ return chart;
354
+ }