rack-mini-profiler 0.1.30 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rack-mini-profiler might be problematic. Click here for more details.

Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +149 -0
  3. data/README.md +271 -0
  4. data/{Ruby/lib → lib}/html/includes.css +0 -0
  5. data/{Ruby/lib → lib}/html/includes.js +9 -8
  6. data/{Ruby/lib → lib}/html/includes.less +0 -0
  7. data/{Ruby/lib → lib}/html/includes.tmpl +1 -1
  8. data/{Ruby/lib → lib}/html/jquery.1.7.1.js +0 -0
  9. data/{Ruby/lib → lib}/html/jquery.tmpl.js +0 -0
  10. data/{Ruby/lib → lib}/html/list.css +2 -2
  11. data/{Ruby/lib → lib}/html/list.js +1 -1
  12. data/{Ruby/lib → lib}/html/list.tmpl +2 -2
  13. data/lib/html/profile_handler.js +1 -0
  14. data/{Ruby/lib → lib}/html/share.html +2 -2
  15. data/{Ruby/lib → lib}/mini_profiler/client_settings.rb +0 -0
  16. data/{Ruby/lib → lib}/mini_profiler/client_timer_struct.rb +0 -0
  17. data/{Ruby/lib → lib}/mini_profiler/config.rb +11 -4
  18. data/{Ruby/lib → lib}/mini_profiler/context.rb +1 -1
  19. data/{Ruby/lib → lib}/mini_profiler/custom_timer_struct.rb +0 -0
  20. data/lib/mini_profiler/gc_profiler.rb +181 -0
  21. data/{Ruby/lib → lib}/mini_profiler/page_timer_struct.rb +0 -0
  22. data/{Ruby/lib → lib}/mini_profiler/profiler.rb +108 -123
  23. data/{Ruby/lib → lib}/mini_profiler/profiling_methods.rb +0 -0
  24. data/{Ruby/lib → lib}/mini_profiler/request_timer_struct.rb +0 -0
  25. data/{Ruby/lib → lib}/mini_profiler/sql_timer_struct.rb +0 -0
  26. data/{Ruby/lib → lib}/mini_profiler/storage/abstract_store.rb +0 -0
  27. data/{Ruby/lib → lib}/mini_profiler/storage/file_store.rb +26 -4
  28. data/{Ruby/lib → lib}/mini_profiler/storage/memcache_store.rb +0 -0
  29. data/{Ruby/lib → lib}/mini_profiler/storage/memory_store.rb +25 -4
  30. data/{Ruby/lib → lib}/mini_profiler/storage/redis_store.rb +0 -0
  31. data/{Ruby/lib → lib}/mini_profiler/timer_struct.rb +0 -0
  32. data/lib/mini_profiler/version.rb +5 -0
  33. data/{Ruby/lib → lib}/mini_profiler_rails/railtie.rb +23 -6
  34. data/{Ruby/lib → lib}/patches/net_patches.rb +0 -0
  35. data/{Ruby/lib → lib}/patches/sql_patches.rb +15 -8
  36. data/{Ruby/lib → lib}/rack-mini-profiler.rb +0 -0
  37. data/rack-mini-profiler.gemspec +24 -16
  38. metadata +163 -53
  39. data/Ruby/CHANGELOG +0 -156
  40. data/Ruby/README.md +0 -172
  41. data/Ruby/lib/html/flamegraph.html +0 -351
  42. data/Ruby/lib/html/profile_handler.js +0 -1
  43. data/Ruby/lib/mini_profiler/flame_graph.rb +0 -54
  44. data/Ruby/lib/mini_profiler/gc_profiler.rb +0 -107
  45. data/Ruby/lib/mini_profiler/version.rb +0 -5
@@ -1,156 +0,0 @@
1
- 28-June-2012 - Sam
2
-
3
- * Started change log
4
- * Corrected profiler so it properly captures POST requests (was supressing non 200s)
5
- * Amended Rack.MiniProfiler.config[:user_provider] to use ip addres for identity
6
- * Fixed bug where unviewed missing ids never got cleared
7
- * Supress all '/assets/' in the rails tie (makes debugging easier)
8
- * record_sql was mega buggy
9
- * added MemcacheStore
10
-
11
- 9-July-2012 - Sam
12
-
13
- * Cleaned up mechanism for profiling in production, all you need to do now
14
- is call Rack::MiniProfiler.authorize_request to get profiling working in
15
- production
16
- * Added option to display full backtraces pp=full-backtrace
17
- * Cleaned up railties, got rid of the post authorize callback
18
- * Version 0.1.3
19
-
20
- 12-July-2012 - Sam
21
-
22
- * Fixed incorrect profiling steps (was not indenting or measuring start time right
23
- * Implemented native PG and MySql2 interceptors, this gives way more accurate times
24
- * Refactored context so its a proper class and not a hash
25
- * Added some more client probing built in to rails
26
- * More tests
27
-
28
- 18-July-2012 - Sam
29
-
30
- * Added First Paint time for chrome
31
- * Bug fix to ensure non Rails installs have mini profiler
32
- * Version 0.1.7
33
-
34
- 30-July-2012 - Sam
35
-
36
- * Made compliant with ancient versions of Rack (including Rack used by Rails2)
37
- * Fixed broken share link
38
- * Fixed crashes on startup (in MemoryStore and FileStore)
39
- * Version 0.1.8
40
- * Unicode fix
41
- * Version 0.1.9
42
-
43
- 7-August-2012 - Sam
44
-
45
- * Added option to disable profiler for the current session (pp=disable / pp=enable)
46
- * yajl compatability contributed by Sven Riedel
47
-
48
- 10-August-2012 - Sam
49
-
50
- * Added basic prepared statement profiling for postgres
51
-
52
- 20-August-2012 - Sam
53
-
54
- * 1.12.pre
55
- * Cap X-MiniProfiler-Ids at 10, otherwise the header can get killed
56
-
57
- 3-September-2012 - Sam
58
-
59
- * 1.13.pre
60
- * pg gem prepared statements were not being logged correctly
61
- * added setting config.backtrace_ignores = [] - an array of regexes that match on caller lines that get ignored
62
- * added setting config.backtrace_includes = [] - an array of regexes that get included in the trace by default
63
- * cleaned up the way client settings are stored
64
- * made pp=full-backtrace "sticky"
65
- * added pp=normal-backtrace to clear the "sticky" state
66
- * change "pp=sample" to work with "caller" no need for stack trace gem
67
-
68
- 4-September-2012 - Sam
69
-
70
- * 1.15.pre
71
- * fixed annoying bug where client settings were not sticking
72
- * fixed long standing issue with Rack::ConditionalGet stopping MiniProfiler from working properly
73
-
74
- 5-September-2012 - Sam
75
-
76
- * 1.16
77
- * fixed long standing problem specs (issue with memory store)
78
- * fixed issue where profiler would be dumped when you got a 404 in production (and any time rails is bypassed)
79
- * implemented stacktrace properly
80
-
81
- 9-September-2012 - Sam
82
-
83
- * 1.17
84
- * pp=sample was bust unless stacktrace was installed
85
-
86
- 10-September-2012 - Sam
87
-
88
- * 1.19
89
- * fix compat issue with 1.8.7
90
-
91
- 12-September-2012 - Sam
92
-
93
- * 1.20
94
- * Added pp=profile-gc , it allows you to profile the GC in Ruby 1.9.3
95
-
96
- 17-September-2012
97
- * 1.21
98
- * New MemchacedStore
99
- * Rails 4 support
100
-
101
- 17-September-2012
102
- * Allow rack-mini-profiler to be sourced from github
103
- * Extracted the pp=profile-gc-time out, the object space profiler needs to disable gc
104
-
105
- 20-September-2012
106
- * 1.22
107
- * Fix permission issue in the gem
108
-
109
- 8-April-2013
110
- * 1.24
111
- * Flame Graph Support see: http://samsaffron.com/archive/2013/03/19/flame-graphs-in-ruby-miniprofiler
112
- * Fix file retention leak in file_store
113
- * New toggle_shortcut and start_hidden options
114
- * Fix for AngularJS support and MooTools
115
- * More robust gc profiling
116
- * Mongoid support
117
- * Fix for html5 implicit body tags
118
- * script tag initialized via data-attributes
119
- * new - Rack::MiniProfiler.counter counter_name {}
120
- * Allow usage of existing jQuery if its already loaded
121
- * Fix pp=enable
122
- * 1.8.7 support ... grrr
123
- * Net:HTTP profiling
124
- * pre authorize to run in all non development? and production? modes
125
-
126
- 8-April-2013
127
- * 1.25
128
- * Missed flamegraph.html from build
129
-
130
- 11-April-2013
131
- * 1.26
132
- * (minor) allow Rack::MiniProfilerRails.initialize!(Rails.application), for post config intialization
133
-
134
- 26-June-2013
135
- * 1.27
136
- * Disable global ajax handlers on MP requests @JP
137
- * Add Rack::MiniProfiler.config.backtrace_threshold_ms
138
- * jQuery 2.0 support
139
-
140
- 18-July-2013
141
- * 1.28
142
- * diagnostics in abstract storage was raising not implemented killing
143
- ?pp=env and others
144
- * SOLR xml unescaped by mistake
145
-
146
- 20-August-2013
147
- * 1.29
148
- * Bugfix: SOLR patching had an incorrect monkey patch
149
- * Implemented exception tracing using TracePoint see pp=trace-exceptions
150
-
151
- 30-August-2013
152
-
153
- * 1.30
154
- * Feature: Added Rack::MiniProfiler.counter_method(klass,name) for injecting counters
155
- * Bug: Counters were not shifting the table correctly
156
-
@@ -1,172 +0,0 @@
1
- # rack-mini-profiler
2
-
3
- Middleware that displays speed badge for every html page. Designed to work both in production and in development.
4
-
5
- ## Using rack-mini-profiler in your app
6
-
7
- Install/add to Gemfile
8
-
9
- ```ruby
10
- gem 'rack-mini-profiler'
11
- ```
12
- Using Rails:
13
-
14
- All you have to do is include the Gem and you're good to go in development.
15
-
16
- rack-mini-profiler is designed with production profiling in mind. To enable that just run `Rack::MiniProfiler.authorize_request` once you know a request is allowed to profile.
17
-
18
- Using Rails:
19
-
20
- ```ruby
21
- # A hook in your ApplicationController
22
- def authorize
23
- if current_user.is_admin?
24
- Rack::MiniProfiler.authorize_request
25
- end
26
- end
27
- ````
28
-
29
-
30
- Using Builder:
31
-
32
- ```ruby
33
- require 'rack-mini-profiler'
34
- builder = Rack::Builder.new do
35
- use Rack::MiniProfiler
36
-
37
- map('/') { run get }
38
- end
39
- ```
40
-
41
- Using Sinatra:
42
-
43
- ```ruby
44
- require 'rack-mini-profiler'
45
- class MyApp < Sinatra::Base
46
- use Rack::MiniProfiler
47
- end
48
- ```
49
-
50
- ## Database profiling
51
-
52
- Currently supports Mysql2, Postgres, and Mongoid3 (with fallback support to ActiveRecord)
53
-
54
- ## Storage
55
-
56
- rack-mini-profiler stores it's results so they can be shared later and aren't lost at the end of the request.
57
-
58
- There are 4 storage options: `MemoryStore`, `RedisStore`, `MemcacheStore`, and `FileStore`.
59
-
60
- `FileStore` is the default in Rails environments and will write files to `tmp/miniprofiler/*`. `MemoryStore` is the default otherwise.
61
-
62
- To change the default you can create a file in `config/initializers/mini_profiler.rb`
63
-
64
- ```ruby
65
- # set MemoryStore
66
- Rack::MiniProfiler.config.storage = Rack::MiniProfiler::MemoryStore
67
-
68
- # set RedisStore
69
- if Rails.env.production?
70
- uri = URI.parse(ENV["REDIS_SERVER_URL"])
71
- Rack::MiniProfiler.config.storage_options = { :host => uri.host, :port => uri.port, :password => uri.password }
72
- Rack::MiniProfiler.config.storage = Rack::MiniProfiler::RedisStore
73
- end
74
- ```
75
-
76
- MemoryStore stores results in a processes heap - something that does not work well in a multi process environment.
77
- FileStore stores results in the file system - something that may not work well in a multi machine environment.
78
- RedisStore/MemcacheStore work in multi process and multi machine environments (RedisStore only saves results for up to 24 hours so it won't continue to fill up Redis).
79
-
80
- Additionally you may implement an AbstractStore for your own provider.
81
-
82
- ## User result segregation
83
-
84
- MiniProfiler will attempt to keep all user results isolated, out-of-the-box the user provider uses the ip address:
85
-
86
- ```ruby
87
- Rack::MiniProfiler.config.user_provider = Proc.new{|env| Rack::Request.new(env).ip}
88
- ```
89
-
90
- You can override (something that is very important in a multi-machine production setup):
91
-
92
- ```ruby
93
- Rack::MiniProfiler.config.user_provider = Proc.new{ |env| CurrentUser.get(env) }
94
- ```
95
-
96
- The string this function returns should be unique for each user on the system (for anonymous you may need to fall back to ip address)
97
-
98
- ## Running the Specs
99
-
100
- ```
101
- $ rake build
102
- $ rake spec
103
- ```
104
-
105
- Additionally you can also run `autotest` if you like.
106
-
107
- ## Configuration Options
108
-
109
- You can set configuration options using the configuration accessor on Rack::MiniProfiler:
110
-
111
- ```
112
- # Have Mini Profiler show up on the right
113
- Rack::MiniProfiler.config.position = 'right'
114
- # Have Mini Profiler start in hidden mode - display with short cut (defaulted to 'Alt+P')
115
- Rack::MiniProfiler.config.start_hidden = true
116
- # Don't collect backtraces on SQL queries that take less than 5 ms to execute
117
- # (necessary on Rubies earlier than 2.0)
118
- Rack::MiniProfiler.config.backtrace_threshold_ms = 5
119
- ```
120
-
121
-
122
- In a Rails app, this can be done conveniently in an initializer such as config/initializers/mini_profiler.rb.
123
-
124
- ## Rails 2.X support
125
-
126
- To get MiniProfiler working with Rails 2.3.X you need to do the initialization manually as well as monkey patch away an incompatibility between activesupport and json_pure.
127
-
128
- Add the following code to your environment.rb (or just in a specific environment such as development.rb) for initialization and configuration of MiniProfiler.
129
-
130
- ```ruby
131
- # configure and initialize MiniProfiler
132
- require 'rack-mini-profiler'
133
- c = ::Rack::MiniProfiler.config
134
- c.pre_authorize_cb = lambda { |env|
135
- Rails.env.development? || Rails.env.production?
136
- }
137
- tmp = Rails.root.to_s + "/tmp/miniprofiler"
138
- FileUtils.mkdir_p(tmp) unless File.exists?(tmp)
139
- c.storage_options = {:path => tmp}
140
- c.storage = ::Rack::MiniProfiler::FileStore
141
- config.middleware.use(::Rack::MiniProfiler)
142
- ::Rack::MiniProfiler.profile_method(ActionController::Base, :process) {|action| "Executing action: #{action}"}
143
- ::Rack::MiniProfiler.profile_method(ActionView::Template, :render) {|x,y| "Rendering: #{@virtual_path}"}
144
-
145
- # monkey patch away an activesupport and json_pure incompatability
146
- # http://pivotallabs.com/users/alex/blog/articles/1332-monkey-patch-of-the-day-activesupport-vs-json-pure-vs-ruby-1-8
147
- if JSON.const_defined?(:Pure)
148
- class JSON::Pure::Generator::State
149
- include ActiveSupport::CoreExtensions::Hash::Except
150
- end
151
- end
152
- ```
153
-
154
- ## Notes
155
-
156
- - Be sure to require rack_mini_profiler last in your Gemfile, when it is required it will monkey patch pg and mysql gems to insert instrumentation. If included too early no SQL will show up.
157
-
158
- ## Available Options
159
-
160
- * pre_authorize_cb - A lambda callback you can set to determine whether or not mini_profiler should be visible on a given request. Default in a Rails environment is only on in development mode. If in a Rack app, the default is always on.
161
- * position - Can either be 'right' or 'left'. Default is 'left'.
162
- * skip_schema_queries - Whether or not you want to log the queries about the schema of your tables. Default is 'false', 'true' in rails development.
163
- * auto_inject (default true) - when false the miniprofiler script is not injected in the page
164
- * backtrace_filter - a regex you can use to filter out unwanted lines from the backtraces
165
- * toggle_shortcut (default Alt+P) - a jquery.hotkeys.js-style keyboard shortcut, used to toggle the mini_profiler's visibility. See http://code.google.com/p/js-hotkeys/ for more info.
166
- * start_hidden (default false) - Whether or not you want the mini_profiler to be visible when loading a page
167
- * backtrace_threshold_ms (default zero) - Minimum SQL query elapsed time before a backtrace is recorded. Backtrace recording can take a couple of milliseconds on rubies earlier than 2.0, impacting performance for very small queries.
168
-
169
- ## Special query strings
170
-
171
- If you include the query string `pp=help` at the end of your request you will see the various options available. You can use these options to extend or contract the amount of diagnostics rack-mini-profiler gathers.
172
-
@@ -1,351 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
5
- <script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.0.8/d3.min.js"></script>
6
- <!-- <script src="http://cdnjs.cloudflare.com/ajax/libs/sugar/1.3.8/sugar.min.js"></script> -->
7
- <meta charset=utf-8 />
8
- <title>Flame Graph of Page</title>
9
- <style>
10
- .info {height: 40px;}
11
- .legend div {
12
- display: block;
13
- float: left;
14
- width: 150px;
15
- margin: 0 8px 8px;
16
- padding: 4px;
17
- height: 50px;
18
- }
19
- </style>
20
- </head>
21
- <body>
22
- <div class="graph"></div>
23
- <div class="info"></div>
24
- <div class="legend"></div>
25
-
26
- <script>
27
-
28
- var data = /*DATA*/;
29
- var maxX = 0;
30
- var maxY = 0;
31
-
32
- debounce = function(func, wait, trickle) {
33
- var timeout;
34
-
35
- timeout = null;
36
- return function() {
37
- var args, context, currentWait, later;
38
- context = this;
39
- args = arguments;
40
- later = function() {
41
- timeout = null;
42
- return func.apply(context, args);
43
- };
44
-
45
- if (timeout && trickle) {
46
- // already queued, let it through
47
- return;
48
- }
49
-
50
- if (typeof wait === "function") {
51
- currentWait = wait();
52
- } else {
53
- currentWait = wait;
54
- }
55
-
56
- if (timeout) {
57
- clearTimeout(timeout);
58
- }
59
-
60
- timeout = setTimeout(later, currentWait);
61
- return timeout;
62
- };
63
- };
64
-
65
-
66
- var guessGem = function(frame)
67
- {
68
- var split = frame.split('/gems/');
69
- if(split.length == 1) {
70
- split = frame.split('/app/');
71
- if(split.length == 1) {
72
- split = frame.split('/lib/');
73
- }
74
-
75
- split = split[Math.max(split.length-2,0)].split('/');
76
- return split[split.length-1];
77
- }
78
- else
79
- {
80
- return split[split.length -1].split('/')[0];
81
- }
82
- }
83
-
84
- var guessMethod = function(frame) {
85
- var split = frame.split('`');
86
- if(split.length == 2) {
87
- return split[1].split("'")[0];
88
- }
89
- return '?';
90
- }
91
-
92
- var guessFile = function(frame) {
93
- var split = frame.split(".rb:");
94
- if(split.length == 2) {
95
- split = split[0].split('/');
96
- return split[split.length - 1];
97
- }
98
- return "";
99
- }
100
-
101
- $.each(data, function(){
102
- maxX = Math.max(maxX, this.x + this.width);
103
- maxY = Math.max(maxY, this.y);
104
- this.shortName = /* guessGem(this.frame) + " " + guessFile(this.frame) + " " */ guessMethod(this.frame);
105
- });
106
-
107
- var width = $(window).width();
108
- var height = $(window).height() / 1.2;
109
-
110
- $('.graph').width(width).height(height);
111
-
112
- var xScale = d3.scale.linear()
113
- .domain([0, maxX])
114
- .range([0, width]);
115
-
116
- var yScale = d3.scale.linear()
117
- .domain([0, maxY])
118
- .range([0,height]);
119
-
120
- var realHeight = 0;
121
- var debouncedHeightCheck = debounce(function(){
122
- if (realHeight > 15) {
123
- svg.selectAll('text').attr('display','show');
124
- } else {
125
- svg.selectAll('text').attr('display','none');
126
- }
127
- }, 200);
128
-
129
- function zoom()
130
- {
131
- svg.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")");
132
-
133
- realHeight = yScale(1) * d3.event.scale;
134
- debouncedHeightCheck();
135
- }
136
-
137
- var svg = d3.select(".graph")
138
- .append("svg")
139
- .attr("width", "100%")
140
- .attr("height", "100%")
141
- .attr("pointer-events", "all")
142
- .append('svg:g')
143
- .call(d3.behavior.zoom().on("zoom", zoom))
144
- .append('svg:g');
145
-
146
-
147
- // so zoom works everywhere
148
- svg.append("rect")
149
- .attr("x",function(d) { return xScale(0); })
150
- .attr("y",function(d) { return yScale(0);})
151
- .attr("width", function(d){return xScale(maxX);})
152
- .attr("height", yScale(maxY))
153
- .attr("fill", "white");
154
-
155
- var color = function() {
156
- var r = parseInt(205 + Math.random() * 50);
157
- var g = parseInt(Math.random() * 230);
158
- var b = parseInt(Math.random() * 55);
159
- return "rgb(" + r + "," + g + "," + b + ")";
160
- }
161
- var info = {};
162
-
163
- // http://stackoverflow.com/questions/1960473/unique-values-in-an-array
164
- Array.prototype.getUnique = function() {
165
- var o = {}, a = []
166
- for (var i = 0; i < this.length; i++) o[this[i]] = 1
167
- for (var e in o) a.push(e)
168
- return a
169
- }
170
-
171
- var samplePercent = function(samples, exclusive){
172
- var info = " (" + samples +
173
- " sample" + (samples == 1 ? "" : "s") + " - " +
174
- ((samples / maxX) * 100).toFixed(2) + "%) ";
175
- if (exclusive) {
176
- info += " (" + exclusive +
177
- " exclusive - " +
178
- ((exclusive / maxX) * 100).toFixed(2) + "%) ";
179
- }
180
- return info;
181
- }
182
-
183
- var mouseover = function(d) {
184
- var i = info[d.frame];
185
- $('.info').text( d.frame + " " + samplePercent(i.samples.length, d.topFrame ? d.topFrame.exclusiveCount : 0));
186
- d3.selectAll(i.nodes)
187
- .attr('opacity',0.5);
188
- };
189
-
190
- var mouseout = function(d) {
191
- var i = info[d.frame];
192
- $('.info').text("");
193
- d3.selectAll(i.nodes)
194
- .attr('opacity',1);
195
- };
196
-
197
- // http://stackoverflow.com/a/7419630
198
- var rainbow = function(numOfSteps, step) {
199
- // This function generates vibrant, "evenly spaced" colours (i.e. no clustering). This is ideal for creating easily distiguishable vibrant markers in Google Maps and other apps.
200
- // Adam Cole, 2011-Sept-14
201
- // HSV to RBG adapted from: http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
202
- var r, g, b;
203
- var h = step / numOfSteps;
204
- var i = ~~(h * 6);
205
- var f = h * 6 - i;
206
- var q = 1 - f;
207
- switch(i % 6){
208
- case 0: r = 1, g = f, b = 0; break;
209
- case 1: r = q, g = 1, b = 0; break;
210
- case 2: r = 0, g = 1, b = f; break;
211
- case 3: r = 0, g = q, b = 1; break;
212
- case 4: r = f, g = 0, b = 1; break;
213
- case 5: r = 1, g = 0, b = q; break;
214
- }
215
- var c = "#" + ("00" + (~ ~(r * 255)).toString(16)).slice(-2) + ("00" + (~ ~(g * 255)).toString(16)).slice(-2) + ("00" + (~ ~(b * 255)).toString(16)).slice(-2);
216
- return (c);
217
- }
218
-
219
- // assign some colors, analyze samples per gem
220
- var gemStats = {}
221
- var topFrames = {}
222
- var lastFrame = {frame: 'd52e04d-df28-41ed-a215-b6ec840a8ea5', x: -1}
223
-
224
- $.each(data, function(){
225
-
226
- var gem = guessGem(this.frame);
227
- var stat = gemStats[gem];
228
-
229
- if(!stat) {
230
- gemStats[gem] = stat = {samples: [], frames: []};
231
- }
232
-
233
- stat.frames.push(this.frame);
234
- for(var j=0; j < this.width; j++){
235
- stat.samples.push(this.x + j);
236
- }
237
- // This assumes the traversal is in order
238
- if (lastFrame.x != this.x) {
239
- var topFrame = topFrames[lastFrame.frame]
240
- if (!topFrame) {
241
- topFrames[lastFrame.frame] = topFrame = {exclusiveCount: 0}
242
- }
243
- topFrame.exclusiveCount += 1;
244
- lastFrame.topFrame = topFrame;
245
- }
246
- lastFrame = this;
247
-
248
- });
249
-
250
- var topFrame = topFrames[lastFrame.frame]
251
- if (!topFrame) {
252
- topFrames[lastFrame.frame] = topFrame = {exclusiveCount: 0}
253
- }
254
- topFrame.exclusiveCount += 1;
255
- lastFrame.topFrame = topFrame;
256
-
257
- var totalGems = 0;
258
- $.each(gemStats, function(){totalGems++;});
259
-
260
-
261
- var currentIndex = 0;
262
- $.each(gemStats, function(k,stat){
263
-
264
- stat.color = rainbow(totalGems, currentIndex);
265
- stat.samples = stat.samples.getUnique();
266
-
267
- for(var x=0; x < stat.frames.length; x++) {
268
- info[stat.frames[x]] = {nodes: [], samples: [], color: stat.color};
269
- }
270
-
271
- currentIndex += 1;
272
- });
273
-
274
-
275
- // see: http://bl.ocks.org/mundhradevang/1387786
276
- function fontSize(d,i) {
277
- var size = yScale(1) / 3;
278
- // var words = d.shortName.split(' ');
279
- var word = d.shortName; // words[0];
280
- var width = xScale(d.width+100);
281
- var height = yScale(1);
282
- var length = 0;
283
- d3.select(this).style("font-size", size + "px").text(word);
284
- while(((this.getBBox().width >= width) || (this.getBBox().height >= height)) && (size > 12))
285
- {
286
- size -= 0.1;
287
- d3.select(this).style("font-size", size + "px");
288
- }
289
-
290
- d3.select(this).attr("dy", size);
291
- }
292
-
293
- svg.selectAll("g")
294
- .data(data)
295
- .enter()
296
- .append("g")
297
- .each(function(){
298
- d3.select(this)
299
- .append("rect")
300
- .attr("x",function(d) { return xScale(d.x-1); })
301
- .attr("y",function(d) { return yScale(maxY - d.y);})
302
- .attr("width", function(d){return xScale(d.width);})
303
- .attr("height", yScale(1))
304
- .attr("fill", function(d){
305
- var i = info[d.frame];
306
- if(!i) {
307
- info[d.frame] = i = {nodes: [], samples: [], color: color()};
308
- }
309
- i.nodes.push(this);
310
- for(var j=0; j < d.width; j++){
311
- i.samples.push(d.x + j);
312
- }
313
- return i.color;
314
- })
315
- .on("mouseover", mouseover)
316
- .on("mouseout", mouseout);
317
-
318
- d3.select(this)
319
- .append("text")
320
- .attr("x",function(d) { return xScale(d.x - 0.98); })
321
- .attr("y",function(d) { return yScale(maxY - d.y);})
322
- .on("mouseover", mouseover)
323
- .on("mouseout", mouseout)
324
- .each(fontSize)
325
- .attr("display", "none");
326
-
327
- });
328
-
329
-
330
- // Samples may overlap on the same line
331
- for (var r in info) {
332
- if (info[r].samples) {
333
- info[r].samples = info[r].samples.getUnique();
334
- }
335
- };
336
-
337
-
338
- // render the legend
339
- $.each(gemStats, function(k,v){
340
- var node = $("<div></div>")
341
- .css("background-color", v.color)
342
- .text(k + " " + samplePercent(v.samples.length)) ;
343
- $('.legend').append(node);
344
- });
345
-
346
-
347
-
348
- </script>
349
- </body>
350
- </html>
351
-