aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--web/i18n/en.yml12
-rw-r--r--web/lib/reports.rb5
-rw-r--r--web/lib/sql.rb1
-rw-r--r--web/views/reports/historic_development.erb24
-rw-r--r--web/viewsjs/reports/historic_development.js.erb95
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]);
+ });
+}
+