rails_notebook 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +22 -0
  4. data/app/assets/javascripts/rails_notebook/application.js +13 -0
  5. data/app/assets/stylesheets/rails_notebook/application.css +15 -0
  6. data/app/controllers/rails_notebook/application_controller.rb +4 -0
  7. data/app/helpers/rails_notebook/application_helper.rb +4 -0
  8. data/app/views/layouts/rails_notebook/application.html.erb +14 -0
  9. data/config/routes.rb +2 -0
  10. data/lib/rails_notebook.rb +14 -0
  11. data/lib/rails_notebook/assets/d3.js +9553 -0
  12. data/lib/rails_notebook/assets/dagre-d3.js +17572 -0
  13. data/lib/rails_notebook/assets/jquery.jsonview.css +52 -0
  14. data/lib/rails_notebook/assets/jquery.jsonview.js +284 -0
  15. data/lib/rails_notebook/assets/jquery.qtip.min.css +2 -0
  16. data/lib/rails_notebook/assets/jquery.qtip.min.js +3 -0
  17. data/lib/rails_notebook/assets/jquery.tipsy.js +288 -0
  18. data/lib/rails_notebook/assets/kernel.css +7 -0
  19. data/lib/rails_notebook/assets/kernel.js +18 -0
  20. data/lib/rails_notebook/assets/kernel.json +1 -0
  21. data/lib/rails_notebook/assets/logo-32x32.png +0 -0
  22. data/lib/rails_notebook/assets/logo-64x64.png +0 -0
  23. data/lib/rails_notebook/assets/nv.d3.css +641 -0
  24. data/lib/rails_notebook/assets/nv.d3.js +13298 -0
  25. data/lib/rails_notebook/assets/rails_notebook.css +136 -0
  26. data/lib/rails_notebook/assets/rails_notebook.js +548 -0
  27. data/lib/rails_notebook/assets/tipsy.css +25 -0
  28. data/lib/rails_notebook/command.rb +104 -0
  29. data/lib/rails_notebook/engine.rb +9 -0
  30. data/lib/rails_notebook/profiler.rb +111 -0
  31. data/lib/rails_notebook/renderers.rb +121 -0
  32. data/lib/rails_notebook/route.rb +121 -0
  33. data/lib/rails_notebook/schemaTable.rb +27 -0
  34. data/lib/rails_notebook/serializers.rb +92 -0
  35. data/lib/rails_notebook/table.rb +28 -0
  36. data/lib/rails_notebook/version.rb +3 -0
  37. data/lib/tasks/rails_notebook_tasks.rake +8 -0
  38. metadata +196 -0
@@ -0,0 +1,136 @@
1
+ /*General css*/
2
+
3
+ body {
4
+ font-family: Avenir,Helvetica Neue,Helvetica,Arial,sans-serif;
5
+ line-height: 1.4;
6
+ }
7
+
8
+ div.text_cell_render {
9
+ font-size: 16px;
10
+ font-weight: lighter;
11
+ }
12
+
13
+ text {
14
+ font-weight: 300;
15
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serf;
16
+ font-size: 14px;
17
+ color: black;
18
+ }
19
+
20
+
21
+
22
+ /* Rails.applicaiton.routes*/
23
+ g.type-hasDisplay > rect {
24
+ fill: #b3ffb3;
25
+ }
26
+ g.type-noDisplay > rect {
27
+ fill: #eee;
28
+ }
29
+
30
+ table, th, td {
31
+ font-size: 14px;
32
+ border: 2px solid white;
33
+ border-collapse: collapse;
34
+ padding: 8px;
35
+ }
36
+
37
+ .toolTipTable h4 {
38
+ font-size: 16px;
39
+ font-weight:normal;
40
+ text-align: center;
41
+ }
42
+
43
+ .activeRecordSchema h3 {
44
+ font-size: 16px;
45
+ font-weight:normal;
46
+ text-align: center;
47
+ }
48
+
49
+
50
+ /*Render Schema Table*/
51
+ .activeRecordSchema {
52
+ color:black;
53
+ }
54
+ table.activeRecordSchemaTable{
55
+ background: #f2f2f2;
56
+ border-collapse:collapse;
57
+ }
58
+ table.activeRecordSchemaTable tr, table.activeRecordSchemaTable td{
59
+ border:0;
60
+ }
61
+ table.activeRecordSchemaTable th{
62
+ border:0;
63
+ font-weight: bold;
64
+ }
65
+
66
+
67
+
68
+ /*Flamechart*/
69
+ .job_chart .chart:hover {
70
+ cursor: pointer;
71
+ }
72
+
73
+ .job_chart .axis text {
74
+ font-size: 0.85em;
75
+ }
76
+
77
+ .job_chart .axis path,
78
+ .job_chart .axis line {
79
+ fill: none;
80
+ stroke: #000;
81
+ shape-rendering: crispEdges;
82
+ }
83
+
84
+ .table.table-striped{
85
+ border-collapse: collapse;
86
+ margin:2px;
87
+ }
88
+
89
+ .table.table-striped tr, .table.table-striped td , .table.table-striped th{
90
+ font-size: 12px;
91
+ padding: 2px 4px 2px 4px;
92
+ }
93
+
94
+ .domain{
95
+ fill: none;
96
+ stroke: #000;
97
+ stroke-width: 2px
98
+ }
99
+
100
+ /*.table.table-striped tr:nth-child(even) {background: #e6e6e6}
101
+ .table.table-striped tr:nth-child(odd) {background: #f2f2f2}
102
+ */
103
+ .rendered_html h1,.rendered_html h2,.rendered_html h3,.rendered_html h4,.rendered_html h5{
104
+ font-weight:normal;
105
+ text-align: center;
106
+ }
107
+
108
+
109
+ div.cell.selected {
110
+ background: #FDFCF8;
111
+ }
112
+
113
+ .rendered_html code {
114
+ border: 1px solid #ddd;
115
+ background: #F5F5F5;
116
+ padding: 1px;
117
+ font-size: 85%;
118
+ }
119
+
120
+
121
+
122
+ /*For Dagre-d3 graph rendering*/
123
+ .node rect {
124
+ stroke: #999;
125
+ fill: #fff;
126
+ stroke-width: 1.5px;
127
+ }
128
+
129
+ .edgePath path {
130
+ stroke: #333;
131
+ stroke-width: 1.5px;
132
+ }
133
+
134
+ .edgeLabel rect {
135
+ fill: #fff;
136
+ }
@@ -0,0 +1,548 @@
1
+ !function() {
2
+
3
+ var railsNB = {
4
+ version: "0.0.1"
5
+ };
6
+
7
+ // Margin values are standard for all elements
8
+ var margin = { left: 45, top: 10, right: 5, bottom: 60 };
9
+
10
+ railsNB.renderFlamechart = function ( _data , _element ){
11
+ require( [ "/kernelspecs/rails_notebook/dagre-d3.js", "/kernelspecs/rails_notebook/d3.js", "jquery", "/kernelspecs/rails_notebook/jquery.tipsy.js" ] , function ( dagreD3, d3, $, tipsy ) {
12
+
13
+ // Initialize
14
+ var SAMPLE_TIME = _data.sampleTime;
15
+ var element = $(_element);
16
+ var data = _data.data;
17
+ var self = this;
18
+
19
+ var getGemName = function(frame) {
20
+ var split = frame.split('/gems/');
21
+ if(split.length == 1) {
22
+ split = frame.split('/app/');
23
+ if(split.length == 1) { split = frame.split('/lib/'); }
24
+ split = split[ Math.max( split.length-2,0 ) ].split('/');
25
+ return split[split.length-1].split(':')[0];
26
+ }
27
+ else {
28
+ return split[split.length -1].split('/')[0];
29
+ }
30
+ };
31
+
32
+ var getMethodName = function(frame) {
33
+ var split = frame.split('`');
34
+ if(split.length == 2) {
35
+ var fullMethod = split[1].split("'")[0];
36
+ split = fullMethod.split("#");
37
+ if(split.length == 2) { return split[1]; }
38
+ return split[0];
39
+ }
40
+ return '';
41
+ };
42
+
43
+ var generate_flamechart = function myself() {
44
+ var bar_height = 20;
45
+ // Generate color from data. The color palette is based on warm colors i.e.
46
+ // from red to orange which have a hue of 0 to around 40. The step taken to
47
+ // increment the hue from 0 to 40 is a function of the step or depth level.
48
+ var color = function(d) {
49
+ var hue_min = 0,
50
+ hue_max = 40,
51
+ hue = null,
52
+ saturation = 80,
53
+ luminosity = 60,
54
+ hues = [],
55
+ step = (hue_max - hue_min)/Math.max.apply(Math,y_values);
56
+ for (var h = 0; h < hue_max; h+=step) { hues.push(h) };
57
+ hue = hues[d.y - 1];
58
+ return d3.hsl("hsl(" + hue + "," + saturation + "%," + luminosity + "%)");
59
+ };
60
+
61
+ var guessGem = function(frame)
62
+ {
63
+ var split = frame.split('/gems/');
64
+ if(split.length == 1) {
65
+ split = frame.split('/app/');
66
+ if(split.length == 1) {
67
+ split = frame.split('/lib/');
68
+ }
69
+ split = split[Math.max(split.length-2,0)].split('/');
70
+ return split[split.length-1].split(':')[0];
71
+ }
72
+ else
73
+ {
74
+ return split[split.length -1].split('/')[0];
75
+ }
76
+ }
77
+
78
+ var guessMethod = function(frame) {
79
+ var split = frame.split('`');
80
+ if(split.length == 2) {
81
+ var fullMethod = split[1].split("'")[0];
82
+ split = fullMethod.split("#");
83
+ if(split.length == 2) {
84
+ return split[1];
85
+ }
86
+ return split[0];
87
+ }
88
+ return '?';
89
+ }
90
+
91
+ // Format the data into formats that make it easier to generate the chart.
92
+ // For example ... convert the UNIX timestamps into Date objects for a more
93
+ // meaningful x-axis. To note is that UNIX timestamps are seconds while
94
+ // JavaScript Date objects expect milliseconds.
95
+ var chart_data = $.map(data, function(d, i) {
96
+ var entry = {}
97
+ entry['x_start'] = d.x * SAMPLE_TIME;
98
+ entry['x_end'] = ( d.x + d.width ) * SAMPLE_TIME;
99
+ entry['y'] = d.y;
100
+ entry['width'] = d.width * SAMPLE_TIME;
101
+ entry['methodDescription'] = d.frame;
102
+ entry['step'] = i;
103
+ d.index = i;
104
+ return entry;
105
+ });
106
+
107
+ // D3 orders the drawing of elements stacked on each other so we reverse the
108
+ // order by steps to hack in some form of z-index-ness.
109
+ //chart_data.sort(function(a, b) { return b.step - a.step });
110
+
111
+ // Determine the chart width (minus axis y-axis and its label).
112
+ var width = function() {
113
+ return element.width() - margin.left - margin.right;
114
+ };
115
+
116
+ // Determine the position of the bar which represents each entry i.e. each
117
+ // bar.
118
+ var bar_y_position = function(d) {
119
+ return bar_height * (d.y - 1)
120
+ };
121
+
122
+ var x_values = function() {
123
+ var start_time_values = $.map(chart_data, function(v, i) { return v.x_start }),
124
+ end_time_values = $.map(chart_data, function(v, i) { return v.x_end });
125
+ return start_time_values.concat(end_time_values);
126
+ };
127
+ // Get the y-domain possible values ... depending on the mode.
128
+ var y_values = $.map( chart_data, function(d){ return d.y });
129
+
130
+ var max_y_value = Math.max.apply( Math,y_values );
131
+ var max_x_value = Math.max.apply( Math,x_values() );
132
+
133
+ // Determine the chart height (minus axis x-axis and its label).
134
+ var height = bar_height * Math.max.apply(Math,y_values);
135
+
136
+ // Define the limits/scale of the x-axis from it's maximum and minimum points.
137
+ var xScale = d3.scale.linear()
138
+ .domain(d3.extent(x_values() ) )
139
+ .range([ 0, width() ]);
140
+
141
+ // Define the limits/scale of the y-axis from it's maximum and minimum points.
142
+ var yScale = d3.scale.ordinal()
143
+ .domain(y_values)
144
+ .rangeBands([0, height ]);
145
+
146
+ // Create x-axis.
147
+ var xAxis = d3.svg.axis()
148
+ .scale(xScale)
149
+ .orient("bottom");
150
+
151
+ // Create y-axis.
152
+ var yAxis = d3.svg.axis()
153
+ .scale(yScale)
154
+ .orient("left");
155
+
156
+ // Get the SVG element.
157
+ element.append('<svg class="chart" id='+element.context.id+'></svg>');
158
+
159
+ var svg = d3.select( "#"+element.context.id+".chart" )
160
+ .attr("width", width() + margin.left + margin.right)
161
+ .attr("height", height + margin.top + margin.bottom);
162
+
163
+ // Add the chart area.
164
+ var chart = svg
165
+ .append("g")
166
+ .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
167
+
168
+ // Create entries from data
169
+ var entries = chart.selectAll("g")
170
+ .data(chart_data)
171
+ .enter()
172
+
173
+ // Create the bars that represent each entry of data.
174
+ var bar = entries.append("g")
175
+ .attr("transform", function (d) { return "translate(0," + bar_y_position(d) + ")" })
176
+ .on("mouseover", function (d) {
177
+ $("table tr." + d.step, element).addClass("info");
178
+ })
179
+ .on("mouseout", function (d) {
180
+ $("table tr." + d.step, element).removeClass("info");
181
+ })
182
+
183
+ var e_sub_bar = bar.append("rect")
184
+ .attr("id", function (d) {return d.step})
185
+ .attr("width", function (d) { return xScale(d.width) })
186
+ .attr("height", bar_height - 1)
187
+ .attr("fill", function (d) { return color(d).toString(); })
188
+ .attr("storedfill", function (d) { return color(d).toString(); }) //for reverting color after cell highlight
189
+ .attr("class", "flamechart-bar")
190
+ .attr("transform", function (d) { return "translate(" + xScale(d.x_start) + ",0)"; });
191
+
192
+
193
+ // Add the x-axis.
194
+ var xAxisScale = chart.append("g")
195
+ .attr("class", "x axis")
196
+ .attr("transform", "translate(0," + height + ")")
197
+ .call(xAxis);
198
+
199
+ // Add the y-axis.
200
+ var yAxisScale = chart.append("g")
201
+ .attr("class", "y axis")
202
+ .call(yAxis);
203
+
204
+ // Add label to the x-axis
205
+ var xAxisLabel = xAxisScale.append("text")
206
+ .attr("class", "label")
207
+ .attr("x", width()/2)
208
+ .attr("y", 30)
209
+ .attr("dy", ".71em")
210
+ .style("text-anchor", "middle")
211
+ .text("Duration (s)");
212
+
213
+ // Add label to the y-axis
214
+ var yAxisLabel = yAxisScale.append("text")
215
+ .attr("class", "label")
216
+ .attr("x", height/2 * -1)
217
+ .attr("transform", "rotate(-90)")
218
+ .attr("y", margin.left * -0.85)
219
+ .attr("dy", ".71em")
220
+ .style("text-anchor", "middle")
221
+ .text("Depth");
222
+
223
+ // Add the time taken for the expression to execute.
224
+ var bar_time = bar.append("text")
225
+ .attr("x", function (d) { return xScale( d.x_end ) - 3; })
226
+ .attr("y", bar_height/2)
227
+ .attr("fill", "black")
228
+ .attr("dy", ".35em")
229
+ .attr("text-anchor", "end")
230
+ .attr("style", "font: 0.8em sans-serif;")
231
+ .text(function(d) {
232
+ if ( d.width > ( max_x_value/15) ) {
233
+ return ( d.width ).toFixed(2) + 'ms'
234
+ }
235
+ });
236
+
237
+ var bar_text = bar.append("text")
238
+ .attr("x", function (d) { return xScale( d.x_start ) + 3; })
239
+ .attr("y", bar_height/2)
240
+ .attr("fill", "black")
241
+ .attr("dy", ".35em")
242
+ .attr("style", "font: 0.8em sans-serif;")
243
+ .text(function(d) {
244
+ if ( d.width > ( max_x_value/5) ) {
245
+ return ( getMethodName( d.methodDescription ) )
246
+ }
247
+ });
248
+ };
249
+
250
+ // Load results in a table.
251
+ var load_analysis_table = function() {
252
+ // Create table that will hold our data.
253
+ var empty_table_structure = '<table class="table table-striped">' +
254
+ '<thead>' +
255
+ '<tr>' +
256
+ '<th>Depth</th>' +
257
+ '<th>Method Name</th>' +
258
+ '<th>Gem Name</th>' +
259
+ '<th>Time Taken</th>' +
260
+ '<th>% Total Time</th>' +
261
+ '</tr>' +
262
+ '</thead>' +
263
+ '<tbody></tbody>' +
264
+ '</table>';
265
+ $(element).append(empty_table_structure);
266
+
267
+ var widths = $.map( data, function(d){ return d.width });
268
+ var max_entry_time = Math.max.apply( Math, widths );
269
+
270
+ // Populate the empty table we just created.
271
+ $.each( data, function( index , entry ) {
272
+ var table_row = '<tr class="' + entry.index + '">'
273
+ table_row += '<td>' + entry.y + '</td>';
274
+ table_row += '<td>' + getMethodName(entry.frame).replace("<","&lt;").replace(">","&gt;") + '</td>';
275
+ table_row += '<td>' + getGemName(entry.frame) + '</td>';
276
+ table_row += '<td>' + ( (entry.width * SAMPLE_TIME) ).toFixed(3) + ' ms' + '</td>';
277
+ table_row += '<td>' + (entry.width / max_entry_time * 100).toFixed(3) + '%' + '</td>';
278
+ table_row += '</tr>';
279
+ $('table', element).append(table_row);
280
+ $("table tr." + index, element)
281
+ .on("mouseover", function (d) {
282
+ $( "rect#" + index + ".flamechart-bar", element ).attr("fill","#eee")
283
+ })
284
+ .on("mouseout", function (d) {
285
+ $("rect#" + index + ".flamechart-bar", element)
286
+ .attr("fill",
287
+ $("rect#" + index + ".flamechart-bar", element).attr("storedfill")
288
+ )
289
+ });
290
+ });
291
+ };
292
+
293
+ // Draw chart.
294
+ generate_flamechart();
295
+ load_analysis_table();
296
+
297
+ });
298
+ };
299
+
300
+ railsNB.renderRoutes = function( tree , _element ){
301
+ require( ["/kernelspecs/rails_notebook/dagre-d3.js", "/kernelspecs/rails_notebook/d3.js", "/kernelspecs/rails_notebook/jquery.tipsy.js", "jquery" ] , function ( dagreD3, d3, tipsy ,$ ) {
302
+
303
+ var element = $(_element);
304
+ var routeTree = tree;
305
+
306
+ var g = new dagreD3.graphlib.Graph().setGraph({}).setDefaultEdgeLabel(function() { return {}; });
307
+
308
+ // Rendering the graph
309
+ var buildOutput = function myself( g, thisNode, parent ){
310
+ g.setNode( thisNode.id , {
311
+ label: ( parent ? thisNode.nodeUri + "/" : "/" + thisNode.nodeUri ),
312
+ class: ( thisNode.verbs.length > 0 && thisNode.verbs[0] != "" ? "type-hasDisplay" : "type-noDisplay" ),
313
+ uriPattern: thisNode.uriPattern,
314
+ controller: thisNode.controller,
315
+ verbs: thisNode.verbs,
316
+ actions: thisNode.actions,
317
+ });
318
+ if ( parent ){
319
+ g.setEdge( parent.id , thisNode.id );
320
+ }
321
+ for ( c in thisNode.childrenNodes ){
322
+ child = thisNode.childrenNodes[c];
323
+ myself( g , child, thisNode );
324
+ }
325
+ }
326
+ buildOutput( g , routeTree.headNode, null)
327
+
328
+ // DagreD3 code to display graph
329
+ var render = new dagreD3.render(); // Create the renderer
330
+ g.nodes().forEach(function(v) {
331
+ var node = g.node(v);
332
+ node.rx = node.ry = 5;
333
+ });
334
+
335
+ // Set up an SVG group so that we can translate the final graph.
336
+ element.append('<svg class="routes" id='+element.context.id+'><g></g></svg>');
337
+ var width = function() {
338
+ return element.width() - margin.left - margin.right;
339
+ };
340
+
341
+ var svg = d3.select( "#"+element.context.id+".routes" )
342
+ .attr("width", width() + margin.left + margin.right)
343
+ .attr("height", 400 + margin.top + margin.bottom);
344
+ var inner = svg.select("g");
345
+
346
+ // Set up zoom support
347
+ var zoom = d3.behavior.zoom().on("zoom", function() {
348
+ inner.attr("transform", "translate(" + d3.event.translate + ")" + "scale(" + d3.event.scale + ")");
349
+ });
350
+ svg.call(zoom);
351
+
352
+ // Simple function to style the tooltip for the given node.
353
+ var styleTooltip = function( node ) {
354
+ return(
355
+ node.verbs.length > 0?
356
+ "<div class='toolTipTable'><h4>"+node.uriPattern.slice(0, -1)+"</h4>" +
357
+ "<table border=1 align='center'>" +
358
+ (node.controller? "<tr><th>Controller:</th><td>"+node.controller+"</td></tr>":"")+
359
+ "<tr><th>Verbs: </th>" +
360
+ "<td>"+node.verbs.join("</td><td>")+"</td>"+
361
+ "</tr>" +
362
+ "<tr><th>Actions: </th>" +
363
+ "<td>"+node.actions.join("</td><td>")+"</td>"+
364
+ "</tr>" +
365
+ "</table></div>"
366
+ :
367
+ null
368
+ )
369
+ };
370
+
371
+ // Run the renderer. This is what draws the final graph.
372
+ render(inner, g);
373
+ inner.selectAll("g.node")
374
+ .attr("title", function(v) {
375
+ return styleTooltip( g.node(v) )
376
+ })
377
+ .each(function(v) {
378
+ $(this).tipsy({ gravity: "w", opacity: 1, html: true });
379
+ });
380
+ // Center the graph
381
+ var initialScale = 0.70;
382
+ zoom
383
+ .translate([(svg.attr("width") - g.graph().width * initialScale) / 2, 20])
384
+ .scale(initialScale)
385
+ .event(svg);
386
+ svg.attr('height', g.graph().height * initialScale + 40);
387
+
388
+ });
389
+ };
390
+
391
+ railsNB.renderSchema = function( tables, _element ){
392
+ require( ["/kernelspecs/rails_notebook/dagre-d3.js", "/kernelspecs/rails_notebook/d3.js", "jquery" ] , function ( dagreD3, d3, $ ) {
393
+
394
+ var element = $(_element);
395
+ var tablesVar = tables;
396
+
397
+ function capitalizeFirstLetter(string) {
398
+ return string.charAt(0).toUpperCase() + string.slice(1);
399
+ }
400
+
401
+ // Lets start by creating something simple and add lables to them
402
+ var g = new dagreD3.graphlib.Graph().setGraph({});
403
+
404
+ //Create rectangles for each of the tables
405
+ var tablesVarLangth = tablesVar.length;
406
+ for (var i=tablesVarLangth-1; i >= 0; i--)
407
+ {
408
+ var rows = tablesVar[i].columns.map( function( r ){
409
+ var name = r[0].indexOf("id") > -1? "<th>" + r[0] + "</th>" : "<td>" + r[0] + "</td>";
410
+ return "<tr>" + name + "<td>" + r[1] + "</td></tr>";
411
+ });
412
+ var buildHtmlOutput = "<div class='activeRecordSchema'><h3>" + capitalizeFirstLetter(tablesVar[i].table_name) + "</h3>";
413
+ buildHtmlOutput += "<table class='activeRecordSchemaTable'>";
414
+ buildHtmlOutput += rows.join("");
415
+ buildHtmlOutput += "</table>";
416
+ buildHtmlOutput += "</div>";
417
+ g.setNode(tablesVar[i].table_name, { shape: "rect", labelType: "html", label: buildHtmlOutput});
418
+ } // End of loop i, but not end of scope for i
419
+
420
+ // Now we want to populate the rectangles with column information
421
+ // TODO
422
+
423
+ // Now we want to make the arrows from the arrowsTo array
424
+ for (var i=0; i < tablesVarLangth; i++)
425
+ {
426
+ if (tablesVar[i].arrowsTo.length != 0)
427
+ {
428
+ tablesVar[i].arrowsTo.forEach(function(arrow) {
429
+ g.setEdge(tablesVar[i].table_name, arrow, {
430
+ arrowhead: "normal",
431
+ label: "belongs to"
432
+ });
433
+ });// For each arrow in table
434
+ } // If there are arrows
435
+ } // End of loop i, but not end of scope for i
436
+
437
+
438
+ // Set up an SVG group so that we can translate the final graph.
439
+ element.append('<svg class="schema" id='+element.context.id+'><g></g></svg>');
440
+ var width = function() {
441
+ return element.width() - margin.left - margin.right;
442
+ };
443
+
444
+ var svg = d3.select( "#"+element.context.id+".schema" )
445
+ .attr("width", width() + margin.left + margin.right)
446
+ .attr("height", 400 + margin.top + margin.bottom);
447
+ var inner = svg.select("g");
448
+
449
+ // Set up zoom support
450
+ var zoom = d3.behavior.zoom().on("zoom", function() {
451
+ inner.attr("transform", "translate(" + d3.event.translate + ")" +
452
+ "scale(" + d3.event.scale + ")");
453
+ });
454
+
455
+ svg.call(zoom);
456
+
457
+ // Create the renderer
458
+ var render = new dagreD3.render();
459
+
460
+ // Run the renderer. This is what draws the final graph.
461
+ render(inner, g);
462
+
463
+ // Center the graph
464
+ var initialScale = 0.60;
465
+ zoom
466
+ .translate([(svg.attr("width") - g.graph().width * initialScale) / 2, 20])
467
+ .scale(initialScale)
468
+ .event(svg);
469
+ svg.attr('height', g.graph().height * initialScale + 40);
470
+
471
+ });
472
+ };
473
+
474
+ railsNB.renderTableData = function( tableData, element ){
475
+ require( ["jquery"] , function ( $ ) {
476
+
477
+ var rows = tableData[1].map( function( rowElem , i ){
478
+ var cellTypeOpen = i == 0 ? "<th>" : "<td>";
479
+ var cellTypeClose = i == 0 ? "</th>" : "</td>";
480
+ var row = "<tr>";
481
+ for ( var j = 1 ; j <= tableData.slice(1).length ; j ++ ) {
482
+ row += cellTypeOpen+ tableData[j][i] + cellTypeClose;
483
+ }
484
+ row += "</tr>"
485
+ return ( row );
486
+ });
487
+
488
+ $(element).append( "<table>" + rows.join("") + "</table>" );
489
+
490
+ });
491
+ };
492
+
493
+ railsNB.renderBarChart = function( hash, _element ){
494
+ require(["jquery", "/kernelspecs/rails_notebook/nv.d3.js", "/kernelspecs/rails_notebook/d3.js"], function ( $, nvd3, d3 ) {
495
+ console.log( "nvd3" , nvd3 );
496
+ console.log( "nv", nv );
497
+ var element = $(_element);
498
+
499
+ var width = function() {
500
+ return element.width() - margin.left - margin.right;
501
+ };
502
+
503
+ element.append('<svg class="barChart" id='+element.context.id+'></svg>');
504
+
505
+ var barData = [];
506
+ var hashVar = hash;
507
+
508
+ for (var key in hashVar)
509
+ {
510
+ barData.push({
511
+ "label": key,
512
+ "value": hashVar[key]
513
+ })
514
+ }
515
+
516
+ var object = [{
517
+ key: "This Chart",
518
+ values: barData
519
+ }];
520
+
521
+ nv.addGraph(function() {
522
+ var chart = nv.models.discreteBarChart()
523
+ .x(function(d) { return d.label }) //Specify the data accessors.
524
+ .y(function(d) { return d.value })
525
+ .staggerLabels(true) //Too many bars and not enough room? Try staggering labels.
526
+ .showValues(true); //...instead, show the bar value right on top of each bar.
527
+
528
+
529
+ d3.select("#"+element.context.id+".barChart")
530
+ .attr("width", width() + margin.left + margin.right)
531
+ .attr("height", 300 + margin.top + margin.bottom)
532
+ .datum(object)
533
+ .call(chart);
534
+ // .selectAll("text")
535
+ // .style("text-anchor", "end")
536
+ // .attr("dx", "-.8em")
537
+ // .attr("dy", ".15em")
538
+ // .attr("transform", function(d) {
539
+ // return "rotate(-65)"
540
+ // });
541
+
542
+ nv.utils.windowResize(chart.update);
543
+ }); // nv add graph end
544
+ }); // Require end
545
+ }; // RenderBarChart end
546
+
547
+ if (typeof define === "function" && define.amd) this.railsNB = railsNB, define(railsNB); else if (typeof module === "object" && module.exports) module.exports = railsNB; else this.railsNB = railsNB;
548
+ }();