diff options
-rw-r--r-- | web/i18n/en.yml | 12 | ||||
-rw-r--r-- | web/lib/reports.rb | 5 | ||||
-rw-r--r-- | web/lib/sql.rb | 1 | ||||
-rw-r--r-- | web/views/reports/historic_development.erb | 24 | ||||
-rw-r--r-- | web/viewsjs/reports/historic_development.js.erb | 95 |
5 files changed, 135 insertions, 2 deletions
diff --git a/web/i18n/en.yml b/web/i18n/en.yml index 8c9103d..b9fbcdb 100644 --- a/web/i18n/en.yml +++ b/web/i18n/en.yml @@ -627,4 +627,16 @@ reports: count_common: Count count_rare: Count similarity: Similarity + historic_development: + name: Historic development + intro: | + Development of some important statistics over time. This data has + been collected by taginfo, gaps are possible when taginfo did't run + on a day for some reason. + keys: + title: Unique keys + tags: + title: Unique tags + relation_types: + title: Unique relation types diff --git a/web/lib/reports.rb b/web/lib/reports.rb index a822476..0412181 100644 --- a/web/lib/reports.rb +++ b/web/lib/reports.rb @@ -59,6 +59,7 @@ Report.new 'Key lengths', :db Report.new 'Language comparison table for keys in the wiki', :wiki Report.new 'Languages', :wiki Report.new 'Wiki pages about non-existing keys', :db, :wiki -Report.new 'Name tags' -#Report.new 'Similar keys', :db +Report.new 'Name tags' #disabled +Report.new 'Similar keys' #disabled, :db +Report.new 'Historic development', :db diff --git a/web/lib/sql.rb b/web/lib/sql.rb index 2845858..030cf37 100644 --- a/web/lib/sql.rb +++ b/web/lib/sql.rb @@ -38,6 +38,7 @@ module SQL @db.execute("ATTACH DATABASE ? AS ?", "#{ @@dir }/#{ source.dbname }", source.id.to_s) end @db.execute("ATTACH DATABASE ? AS search", "#{ @@dir }/taginfo-search.db") + @db.execute("ATTACH DATABASE ? AS history", "#{ @@dir }/taginfo-history.db") self end diff --git a/web/views/reports/historic_development.erb b/web/views/reports/historic_development.erb new file mode 100644 index 0000000..d1763b0 --- /dev/null +++ b/web/views/reports/historic_development.erb @@ -0,0 +1,24 @@ +<div class="pre"> + <h1><%= t.reports.historic_development.name %></h1> + <%= t.reports.historic_development.intro %> +</div> +<div id="tabs"> + <ul> + <li><a href="#num_keys"><%= t.osm.keys %></a></li> + <li><a href="#num_tags"><%= t.osm.tags %></a></li> + <li><a href="#relation_types"><%= t.osm.relation_types %></a></li> + </ul> + <div id="num_keys"> + <h2><%= t.reports.historic_development.keys.title %></h2> + <div class="canvas" id="canvas_num_keys"></div> + </div> + <div id="num_tags"> + <h2><%= t.reports.historic_development.tags.title %></h2> + <div class="canvas" id="canvas_num_tags"></div> + </div> + <div id="relation_types"> + <h2><%= t.reports.historic_development.relation_types.title %></h2> + <div class="canvas" id="canvas_relation_types"></div> + </div> +</div> +<% javascript_for(:d3) %> diff --git a/web/viewsjs/reports/historic_development.js.erb b/web/viewsjs/reports/historic_development.js.erb new file mode 100644 index 0000000..05ca6ae --- /dev/null +++ b/web/viewsjs/reports/historic_development.js.erb @@ -0,0 +1,95 @@ +<% +page = @trans.t.reports.historic_development + +data = {} +['num_keys', 'num_tags', 'relation_types'].each do |key| + data[key] = @db.execute("SELECT udate, value FROM history.history_stats WHERE key=? ORDER BY udate", key).map do |row| + [ row['udate'], row['value'].to_i ] + end +end +%> + +var create_flexigrid_for = { +} + +function init_stat(key, data) { + var radius = 1.5, + w = 900, + h = 400, + margin = { top: 10, right: 15, bottom: 60, left: 80 }; + + data.forEach(function(d) { + d[0] = new Date(d[0]); + }); + + var t0 = data[0][0]; + t1 = data[data.length - 1][0]; + + var max = d3.max(data, function(d) { + return d[1]; + }); + + var scale_x = d3.time.scale() + .domain([t0, t1]) + .range([0, w]); + + var axis_x = d3.svg.axis() + .scale(scale_x) + .orient('bottom') + .tickFormat(d3.time.format('%b %Y')); + + var scale_y = d3.scale.linear() + .domain([0, max]) + .range([h, 0]); + + var axis_y = d3.svg.axis() + .scale(scale_y) + .orient('left'); + + var chart = d3.select('#canvas_' + key).append('svg') + .attr('width', w + margin.left + margin.right) + .attr('height', h + margin.top + margin.bottom) + .append('g') + .attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')') + .call(function(c) { + c.append('rect') + .attr('width', w + 10) + .attr('height', h + 10) + .attr('x', -5) + .attr('y', -5) + .style('fill', 'white') + .style('stroke', '#d0d0c8') + }); + + chart.append('g') + .attr('class', 'x axis') + .attr('transform', 'translate(0, ' + (h + 5) + ')') + .call(axis_x); + + chart.append('g') + .attr('class', 'y axis') + .attr('transform', 'translate(-5, 0)') + .call(axis_y); + + chart.selectAll('circle') + .data(data) + .enter() + .append('circle') + .style('fill', '#083e76') + .attr('cx', function(d, i) { return scale_x(d[0]); }) + .attr('cy', function(d) { return scale_y(d[1]); }) + .attr('r', radius) + .attr('title', function(d, i) { return d3.time.format('%Y-%m-%d')(d[0]) + ': ' + d[1]; }); + +} + +function page_init() { + up = function() { window.location = '/reports'; }; + init_tabs([]); + var data = <%= data.to_json %>; + + Object.keys(data).forEach(function(key) { + init_stat(key, data[key]); + }); +} + |