giblish 0.8.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/unit_tests.yml +30 -0
  3. data/.gitignore +7 -3
  4. data/.ruby-version +1 -1
  5. data/Changelog.adoc +59 -0
  6. data/README.adoc +261 -0
  7. data/docs/concepts/text_search.adoc +213 -0
  8. data/docs/concepts/text_search_im/cgi-search_request.puml +35 -0
  9. data/docs/concepts/text_search_im/cgi-search_request.svg +397 -0
  10. data/docs/concepts/text_search_im/search_request.puml +40 -0
  11. data/docs/concepts/text_search_im/search_request.svg +408 -0
  12. data/docs/howtos/trigger_generation.adoc +180 -0
  13. data/docs/{setup_server_assets → howtos/trigger_generation_im}/Render Documents.png +0 -0
  14. data/docs/{setup_server_assets → howtos/trigger_generation_im}/View Documents.png +0 -0
  15. data/docs/{setup_server_assets → howtos/trigger_generation_im}/deploy_with_hooks.graphml +0 -0
  16. data/docs/{setup_server_assets → howtos/trigger_generation_im}/deploy_with_hooks.svg +0 -0
  17. data/docs/{setup_server_assets → howtos/trigger_generation_im}/deploy_with_jenkins.graphml +0 -0
  18. data/docs/{setup_server_assets → howtos/trigger_generation_im}/deploy_with_jenkins.svg +0 -0
  19. data/docs/howtos/trigger_generation_im/docgen_github.puml +51 -0
  20. data/docs/{setup_server_assets → howtos/trigger_generation_im}/giblish_deployment.graphml +0 -0
  21. data/docs/howtos/trigger_generation_im/post-receive-example.sh +50 -0
  22. data/docs/reference/box_flow_spec.adoc +22 -0
  23. data/docs/reference/search_spec.adoc +185 -0
  24. data/giblish.gemspec +50 -29
  25. data/lib/giblish/adocsrc_providers.rb +23 -0
  26. data/lib/giblish/application.rb +214 -41
  27. data/lib/giblish/cmdline.rb +273 -259
  28. data/lib/giblish/config_utils.rb +41 -0
  29. data/lib/giblish/configurator.rb +163 -0
  30. data/lib/giblish/conversion_info.rb +120 -0
  31. data/lib/giblish/docattr_providers.rb +125 -0
  32. data/lib/giblish/docid/docid.rb +181 -0
  33. data/lib/giblish/github_trigger/webhook_manager.rb +64 -0
  34. data/lib/giblish/gitrepos/checkoutmanager.rb +124 -0
  35. data/lib/giblish/{gititf.rb → gitrepos/gititf.rb} +30 -4
  36. data/lib/giblish/gitrepos/gitsummary.erb +61 -0
  37. data/lib/giblish/gitrepos/gitsummaryprovider.rb +78 -0
  38. data/lib/giblish/gitrepos/history_pb.rb +41 -0
  39. data/lib/giblish/indexbuilders/d3treegraph.rb +88 -0
  40. data/lib/giblish/indexbuilders/depgraphbuilder.rb +109 -0
  41. data/lib/giblish/indexbuilders/dotdigraphadoc.rb +174 -0
  42. data/lib/giblish/indexbuilders/standard_index.erb +10 -0
  43. data/lib/giblish/indexbuilders/subtree_indices.rb +132 -0
  44. data/lib/giblish/indexbuilders/templates/circles.html.erb +111 -0
  45. data/lib/giblish/indexbuilders/templates/flame.html.erb +61 -0
  46. data/lib/giblish/indexbuilders/templates/tree.html.erb +366 -0
  47. data/lib/giblish/indexbuilders/templates/treemap.html.erb +127 -0
  48. data/lib/giblish/indexbuilders/verbatimtree.rb +94 -0
  49. data/lib/giblish/pathtree.rb +473 -74
  50. data/lib/giblish/resourcepaths.rb +150 -0
  51. data/lib/giblish/search/expand_adoc.rb +55 -0
  52. data/lib/giblish/search/headingindexer.rb +312 -0
  53. data/lib/giblish/search/request_manager.rb +110 -0
  54. data/lib/giblish/search/searchquery.rb +68 -0
  55. data/lib/giblish/search/textsearcher.rb +349 -0
  56. data/lib/giblish/subtreeinfobuilder.rb +77 -0
  57. data/lib/giblish/treeconverter.rb +272 -0
  58. data/lib/giblish/utils.rb +142 -294
  59. data/lib/giblish/version.rb +1 -1
  60. data/lib/giblish.rb +10 -7
  61. data/scripts/hooks/post-receive.example +66 -0
  62. data/{docgen/scripts/githook_examples → scripts/hooks}/post-update.example +0 -0
  63. data/{docgen → scripts}/resources/css/adoc-colony.css +0 -0
  64. data/scripts/resources/css/giblish-serif.css +419 -0
  65. data/scripts/resources/css/giblish.css +1979 -419
  66. data/{docgen → scripts}/resources/fonts/Ubuntu-B.ttf +0 -0
  67. data/{docgen → scripts}/resources/fonts/Ubuntu-BI.ttf +0 -0
  68. data/{docgen → scripts}/resources/fonts/Ubuntu-R.ttf +0 -0
  69. data/{docgen → scripts}/resources/fonts/Ubuntu-RI.ttf +0 -0
  70. data/{docgen → scripts}/resources/fonts/mplus1p-regular-fallback.ttf +0 -0
  71. data/{docgen → scripts}/resources/images/giblish_logo.png +0 -0
  72. data/{docgen → scripts}/resources/images/giblish_logo.svg +0 -0
  73. data/{docgen → scripts}/resources/themes/giblish.yml +0 -0
  74. data/scripts/wserv_development.rb +32 -0
  75. data/web_apps/cgi_search/gibsearch.rb +43 -0
  76. data/web_apps/gh_webhook_trigger/config.ru +2 -0
  77. data/web_apps/gh_webhook_trigger/gh_webhook_trigger.rb +73 -0
  78. data/web_apps/gh_webhook_trigger/public/dummy.txt +3 -0
  79. data/web_apps/sinatra_search/config.ru +2 -0
  80. data/web_apps/sinatra_search/public/dummy.txt +3 -0
  81. data/web_apps/sinatra_search/sinatra_search.rb +34 -0
  82. data/web_apps/sinatra_search/tmp/restart.txt +0 -0
  83. metadata +180 -71
  84. data/.rubocop.yml +0 -7
  85. data/.travis.yml +0 -3
  86. data/Changelog +0 -16
  87. data/Gemfile +0 -4
  88. data/README.adoc +0 -1
  89. data/Rakefile +0 -41
  90. data/bin/console +0 -14
  91. data/bin/setup +0 -8
  92. data/data/testdocs/malformed/no_header.adoc +0 -5
  93. data/data/testdocs/toplevel.adoc +0 -19
  94. data/data/testdocs/wellformed/adorned_purpose.adoc +0 -17
  95. data/data/testdocs/wellformed/docidtest/docid_1.adoc +0 -24
  96. data/data/testdocs/wellformed/docidtest/docid_2.adoc +0 -8
  97. data/data/testdocs/wellformed/simple.adoc +0 -14
  98. data/data/testdocs/wellformed/source_highlighting/highlight_source.adoc +0 -38
  99. data/docgen/resources/css/giblish.css +0 -1979
  100. data/docgen/scripts/Jenkinsfile +0 -18
  101. data/docgen/scripts/gen_adoc_org.sh +0 -58
  102. data/docs/README.adoc +0 -387
  103. data/docs/setup_server.adoc +0 -202
  104. data/lib/giblish/buildgraph.rb +0 -216
  105. data/lib/giblish/buildindex.rb +0 -459
  106. data/lib/giblish/core.rb +0 -451
  107. data/lib/giblish/docconverter.rb +0 -308
  108. data/lib/giblish/docid.rb +0 -180
  109. data/lib/giblish/docinfo.rb +0 -75
  110. data/lib/giblish/indexheadings.rb +0 -251
  111. data/lib/giblish-search.cgi +0 -459
  112. data/scripts/hooks/post-receive +0 -57
  113. data/scripts/publish_html.sh +0 -99
@@ -0,0 +1,174 @@
1
+ require_relative "../utils"
2
+
3
+ module Giblish
4
+ # Provides a graphviz-formatted digraph of the provided node<->id ref map.
5
+ #
6
+ # See https://graphviz.gitlab.io/doc/conv_info/lang.html for one definition of the
7
+ # language.
8
+ #
9
+ # A short example:
10
+ #
11
+ # [graphviz,target="docdeps",format="svg",svg-type="inline"]
12
+ # ....
13
+ # digraph document_deps {
14
+ # bgcolor="#33333310"
15
+ # node [shape=note,
16
+ # fillcolor="#ebf26680",
17
+ # style="filled,solid"
18
+ # ]
19
+ #
20
+ # rankdir="LR"
21
+ #
22
+ #
23
+ # "D-3"[label="D-3\n Doc 3", URL="file3.html" ]
24
+ # "D-2"[label="D-2\n Doc 2", URL="my/file2.html" ]
25
+ # "D-1"[label="D-1\n Doc 1", URL="my/subdir/file1.html" ]
26
+ # "D-1" -> { "D-2" "D-3"}
27
+ # "D-2" -> { "D-1"}
28
+ # "D-3"
29
+ # }
30
+ # ....
31
+ class DotDigraphAdoc
32
+ # info_2_ids:: A {ConversionInfo => [doc id refs]} hash.
33
+ #
34
+ # The following properties are expected from the ConversionInfo:
35
+ # title:: String
36
+ # doc_id:: String
37
+ # dst_rel_path:: String - the relative path from a the repo top to a doc
38
+ # in the dst tree
39
+ #
40
+ # target::
41
+ # format::
42
+ # opts:: additional options {"opt" => "value"}. Currently supported:
43
+ #
44
+ # cachedir:: the directory to use for storing files produced during diagram generation.
45
+ # svg-type:: how to embed svg images
46
+ #
47
+ def initialize(info_2_ids:, target: "gibgraph", format: "svg", opts: {"svg-type" => "inline"})
48
+ @info_2_ids = info_2_ids
49
+ @target = target
50
+ @format = format
51
+ @opts = opts
52
+
53
+ @noid_docs = {}
54
+ @next_id = 0
55
+ end
56
+
57
+ def source
58
+ <<~DOC_STR
59
+ #{graph_header}
60
+ #{generate_labels}
61
+ #{generate_deps}
62
+ #{graph_footer}
63
+ DOC_STR
64
+ end
65
+
66
+ private
67
+
68
+ def graph_header
69
+ opt_str = @opts.collect { |key, value| "#{key}=\"#{value}\"" }.join(",")
70
+ <<~DOC_STR
71
+ [graphviz,target="#{@target}",format="#{@format}",#{opt_str}]
72
+ ....
73
+ digraph document_deps {
74
+ bgcolor="#33333310"
75
+ labeljust=l
76
+ node [shape=note,
77
+ fillcolor="#ebf26680",
78
+ style="filled,solid"
79
+ ]
80
+
81
+ rankdir="LR"
82
+
83
+ DOC_STR
84
+ end
85
+
86
+ def graph_footer
87
+ <<~DOC_STR
88
+ }
89
+ ....
90
+ DOC_STR
91
+ end
92
+
93
+ def make_dot_entry(doc_dict, conv_info)
94
+ title = if conv_info&.title.nil?
95
+ ""
96
+ else
97
+ # remove html markup in the title for displaying in the tree
98
+ stripped_title = conv_info.title.gsub(/<.*?>/, "")
99
+ stripped_title.tr!('"', "'")
100
+ Giblish.break_line(stripped_title, 16).join("\n")
101
+ end
102
+
103
+ # title = conv_info&.title.nil? ? "" : Giblish.break_line(conv_info.title, 16).join("\n")
104
+ # create the label used to display the node in the graph
105
+ dot_entry = if conv_info.docid.nil?
106
+ doc_id = next_fake_id
107
+ @noid_docs[conv_info] = doc_id
108
+ "\"#{doc_id}\"[label=\"-\n#{title}\""
109
+ else
110
+ doc_id = conv_info.docid
111
+ "\"#{conv_info.docid}\"[label=\"#{conv_info.docid}\n#{title}\""
112
+ end
113
+
114
+ # add clickable links in the case of html output (this is not supported
115
+ # out-of-the-box for pdf).
116
+ rp = conv_info.dst_rel_path
117
+ dot_entry += case rp.extname
118
+ when ".html"
119
+ ", URL=\"#{rp}\" ]"
120
+ else
121
+ " ]"
122
+ end
123
+ doc_dict[doc_id] = dot_entry
124
+ end
125
+
126
+ # create an entry in the 'dot' description for each
127
+ # document, sort them according to descending doc id to
128
+ # get them displayed in the opposite order in the graph
129
+ def generate_labels
130
+ node_dict = {}
131
+ @info_2_ids.each_key do |conv_info|
132
+ next unless conv_info.converted
133
+
134
+ make_dot_entry node_dict, conv_info
135
+ end
136
+ # sort the nodes by reverse doc id
137
+ node_dict = node_dict.sort.reverse.to_h
138
+
139
+ # produce the string with all node entries
140
+ node_dict.map do |_k, v|
141
+ v
142
+ end.join("\n")
143
+ end
144
+
145
+ def generate_deps
146
+ dep_str = ""
147
+ @info_2_ids.each do |conv_info, targets|
148
+ # set either the real or the generated id as source
149
+ src_part = if conv_info.docid.nil?
150
+ "\"#{@noid_docs[conv_info]}\""
151
+ else
152
+ "\"#{conv_info.docid}\""
153
+ end
154
+
155
+ if targets.length.zero?
156
+ dep_str += "#{src_part}\n"
157
+ next
158
+ end
159
+
160
+ dep_str += "#{src_part} -> {" + targets.reduce("") do |acc, target|
161
+ acc + " \"#{target}\""
162
+ end
163
+ # replace last comma with newline
164
+ dep_str += "}\n"
165
+ end
166
+ dep_str
167
+ end
168
+
169
+ def next_fake_id
170
+ @next_id += 1
171
+ "_generated_id_#{@next_id.to_s.rjust(4, "0")}"
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,10 @@
1
+ = Documents under '<%= @title %>'
2
+ Generated at: <%= Time.now.strftime("%Y-%m-%d %H:%M") %>
3
+ :icons: font
4
+
5
+ <%= tree_summary %>
6
+
7
+ == Document Details
8
+
9
+ <%= document_details %>
10
+
@@ -0,0 +1,132 @@
1
+ require "erb"
2
+ require_relative "verbatimtree"
3
+ require_relative "d3treegraph"
4
+
5
+ module Giblish
6
+ class SubtreeIndexBase < SubtreeSrcItf
7
+ attr_reader :src_location
8
+
9
+ DEFAULT_INDEX_ERB = "/standard_index.erb"
10
+
11
+ def initialize(pathtree, output_basename)
12
+ @pathtree = pathtree
13
+ @output_basename = output_basename
14
+ @src_location = pathtree.pathname.dirname
15
+ @title = pathtree.segment
16
+ end
17
+
18
+ def adoc_source
19
+ erb_template = File.read(__dir__ + DEFAULT_INDEX_ERB)
20
+ ERB.new(erb_template, trim_mode: "<>").result(binding)
21
+ end
22
+
23
+ def tree_summary
24
+ VerbatimTree.new(@pathtree.sort_leaf_first!, {dir_index_base_name: @output_basename}).source
25
+ # str = "++++\n"
26
+ # str += D3TreeGraph.new(tree: @pathtree, options: {dir_index_base_name: @output_basename}).source
27
+ # str += "\n++++"
28
+ # str
29
+ end
30
+
31
+ def document_details
32
+ details_str = ""
33
+
34
+ @pathtree.traverse_preorder do |_level, node|
35
+ next unless node.leaf?
36
+
37
+ d = node.data
38
+ details_str << (d.converted ? document_detail(node) : document_detail_fail(d))
39
+ end
40
+ details_str
41
+ end
42
+
43
+ protected
44
+
45
+ def document_detail_fail(node_data)
46
+ <<~FAIL_INFO
47
+ === #{node_data.src_basename}
48
+
49
+ Source file::
50
+ #{node_data.src_node.segment}
51
+
52
+ Error detail::
53
+ #{node_data.error_msg}
54
+
55
+ ''''
56
+
57
+ FAIL_INFO
58
+ end
59
+
60
+ # Show some details about file content
61
+ def document_detail(node)
62
+ node_data = node.data
63
+ <<~DETAIL_SRC
64
+ [[#{Giblish.to_valid_id(node.pathname.to_s, "_", "_", true)}]]
65
+ === pass:[#{node_data.title.encode("utf-8")}]
66
+
67
+ #{"Doc id::\n_#{node_data.docid}_" unless node_data.docid.nil?}
68
+
69
+ #{"Purpose::\n#{node_data.purpose_str}" unless node_data.purpose_str.to_s.empty?}
70
+
71
+ #{if node_data.stderr.empty?
72
+ ""
73
+ else
74
+ "Conversion issues::\n"\
75
+ "#{node_data.stderr.gsub(/^/, " * ")}"
76
+ end
77
+ }
78
+
79
+ Source file::
80
+ #{node_data.src_node.segment}
81
+
82
+ '''
83
+
84
+ DETAIL_SRC
85
+ end
86
+ end
87
+
88
+ # Generates a directory index with history info for all files under the
89
+ # given subdir node.
90
+ class SubtreeIndexGit < SubtreeIndexBase
91
+ # The fixed heading of the table used to display file history
92
+ HISTORY_TABLE_HEADING = <<~HISTORY_HEADER
93
+ File history::
94
+
95
+ [cols=\"2,3,8,3\",options=\"header\"]
96
+ |===
97
+ |Date |Author |Message |Sha1
98
+ HISTORY_HEADER
99
+
100
+ HISTORY_TABLE_FOOTING = <<~HIST_FOOTER
101
+
102
+ |===\n\n
103
+ HIST_FOOTER
104
+
105
+ def subtitle(dst_node)
106
+ "from #{dst_node.data.branch}"
107
+ end
108
+
109
+ def document_detail_fail(node_data)
110
+ super(node_data) + generate_history_info(node_data)
111
+ end
112
+
113
+ def document_detail(node_data)
114
+ super(node_data) + generate_history_info(node_data)
115
+ end
116
+
117
+ def generate_history_info(node_data)
118
+ return "Could not find history information\n\n" unless node_data.respond_to?(:history)
119
+
120
+ # Generate table rows of history information
121
+ rows = node_data.history.collect do |h|
122
+ <<~HISTORY_ROW
123
+ |#{h.date.strftime("%Y-%m-%d")}
124
+ |#{h.author}
125
+ |#{h.message}
126
+ |#{h.sha1[0..7]} ...
127
+ HISTORY_ROW
128
+ end.join("\n\n")
129
+ HISTORY_TABLE_HEADING + rows + HISTORY_TABLE_FOOTING
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,111 @@
1
+ <!DOCTYPE html>
2
+ <meta charset="utf-8">
3
+ <style>
4
+
5
+ html, body{
6
+ height: 100%;
7
+ margin: 0;
8
+ padding: 0;
9
+ }
10
+
11
+ .node {
12
+ cursor: pointer;
13
+ }
14
+
15
+ .node:hover {
16
+ stroke: #000;
17
+ stroke-width: 1.5px;
18
+ }
19
+
20
+ .node--leaf {
21
+ fill: white;
22
+ }
23
+
24
+ .label {
25
+ font: 11px "Helvetica Neue", Helvetica, Arial, sans-serif;
26
+ text-anchor: middle;
27
+ text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff, 0 -1px 0 #fff;
28
+ }
29
+
30
+ .label,
31
+ .node--root,
32
+ .node--leaf {
33
+ pointer-events: none;
34
+ }
35
+
36
+ </style>
37
+ <svg width="100%" height="100%"></svg>
38
+ <script src="https://d3js.org/d3.v4.min.js"></script>
39
+ <script>
40
+ // Copied from https://bl.ocks.org/mbostock/7607535
41
+ var width = window.innerWidth,
42
+ height = window.innerHeight;
43
+ var svg = d3.select("svg"),
44
+ margin = 20,
45
+ diameter = Math.min(width, height),
46
+ g = svg.append("g").attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")");
47
+
48
+ var color = d3.scaleLinear()
49
+ .domain([-1, 5])
50
+ .range(["hsl(152,80%,80%)", "hsl(228,30%,40%)"])
51
+ .interpolate(d3.interpolateHcl);
52
+
53
+ var pack = d3.pack()
54
+ .size([diameter - margin, diameter - margin])
55
+ .padding(2);
56
+
57
+ root = <%= tree.to_json %>;
58
+ root = d3.hierarchy(root)
59
+ .sum(function(d) { return d.children.length + 1; })
60
+ .sort(function(a, b) { return b.value - a.value; });
61
+
62
+ var focus = root,
63
+ nodes = pack(root).descendants(),
64
+ view;
65
+
66
+ var circle = g.selectAll("circle")
67
+ .data(nodes)
68
+ .enter().append("circle")
69
+ .attr("class", function(d) { return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root"; })
70
+ .style("fill", function(d) { return d.children ? color(d.depth) : null; })
71
+ .on("click", function(d) { if (focus !== d) zoom(d), d3.event.stopPropagation(); });
72
+
73
+ var text = g.selectAll("text")
74
+ .data(nodes)
75
+ .enter().append("text")
76
+ .attr("class", "label")
77
+ .style("fill-opacity", function(d) { return d.parent === root ? 1 : 0; })
78
+ .style("display", function(d) { return d.parent === root ? "inline" : "none"; })
79
+ .text(function(d) { return d.data.name; });
80
+
81
+ var node = g.selectAll("circle,text");
82
+
83
+ svg
84
+ .style("background", color(-1))
85
+ .on("click", function() { zoom(root); });
86
+
87
+ zoomTo([root.x, root.y, root.r * 2 + margin]);
88
+
89
+ function zoom(d) {
90
+ var focus0 = focus; focus = d;
91
+
92
+ var transition = d3.transition()
93
+ .duration(d3.event.altKey ? 7500 : 750)
94
+ .tween("zoom", function(d) {
95
+ var i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2 + margin]);
96
+ return function(t) { zoomTo(i(t)); };
97
+ });
98
+
99
+ transition.selectAll("text")
100
+ .filter(function(d) { return d.parent === focus || this.style.display === "inline"; })
101
+ .style("fill-opacity", function(d) { return d.parent === focus ? 1 : 0; })
102
+ .on("start", function(d) { if (d.parent === focus) this.style.display = "inline"; })
103
+ .on("end", function(d) { if (d.parent !== focus) this.style.display = "none"; });
104
+ }
105
+
106
+ function zoomTo(v) {
107
+ var k = diameter / v[2]; view = v;
108
+ node.attr("transform", function(d) { return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")"; });
109
+ circle.attr("r", function(d) { return d.r * k; });
110
+ }
111
+ </script>
@@ -0,0 +1,61 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+
5
+ <meta charset="utf-8">
6
+ <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/spiermar/d3-flame-graph@1.0.4/dist/d3.flameGraph.min.css">
7
+ <style>
8
+ html, body{
9
+ height: 100%;
10
+ margin: 0;
11
+ padding: 0;
12
+ font-size: 14px;
13
+ }
14
+ </style>
15
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
16
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.7.1/d3-tip.min.js"></script>
17
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/gh/spiermar/d3-flame-graph@1.0.4/dist/d3.flameGraph.min.js"></script>
18
+
19
+ </head>
20
+ <body>
21
+
22
+ <div class="container">
23
+ <div id="chart">
24
+ </div>
25
+ </div>
26
+ <script>
27
+ // Uses D3js flamegraph: https://github.com/spiermar/d3-flame-graph
28
+ var flameGraph = d3.flameGraph()
29
+ .width(window.innerWidth)
30
+ .cellHeight(18)
31
+ .transitionDuration(750)
32
+ .transitionEase(d3.easeCubic)
33
+ .sort(true)
34
+ .title("");
35
+
36
+ var tip = d3.tip()
37
+ .direction("s")
38
+ .offset([8, 0])
39
+ .attr('class', 'd3-flame-graph-tip')
40
+ .html(function(d) { return "name: " + d.data.name + ", value: " + d.data.value; });
41
+
42
+ flameGraph.tooltip(tip);
43
+
44
+ function setValue(d) {
45
+ var val = 0;
46
+ for( var i=0; i<d.children.length; i++){
47
+ setValue(d.children[i]);
48
+ val += d.children[i].value;
49
+ }
50
+ d.value = val == 0 ? 1 : val;
51
+ }
52
+
53
+ root = <%= tree.to_json %>;
54
+ setValue(root)
55
+ d3.select("#chart")
56
+ .datum(root)
57
+ .call(flameGraph);
58
+ </script>
59
+
60
+ </body>
61
+ </html>