publish_my_data 0.0.32 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (182) hide show
  1. data/app/assets/images/publish_my_data/small-spinner.gif +0 -0
  2. data/app/assets/images/publish_my_data/sort-asc.gif +0 -0
  3. data/app/assets/images/publish_my_data/sort-desc.gif +0 -0
  4. data/app/assets/javascripts/bootstrap/affix.js +126 -0
  5. data/app/assets/javascripts/bootstrap/alert.js +98 -0
  6. data/app/assets/javascripts/bootstrap/button.js +109 -0
  7. data/app/assets/javascripts/bootstrap/carousel.js +217 -0
  8. data/app/assets/javascripts/bootstrap/collapse.js +179 -0
  9. data/app/assets/javascripts/bootstrap/dropdown.js +154 -0
  10. data/app/assets/javascripts/bootstrap/modal.js +246 -0
  11. data/app/assets/javascripts/bootstrap/popover.js +117 -0
  12. data/app/assets/javascripts/bootstrap/scrollspy.js +158 -0
  13. data/app/assets/javascripts/bootstrap/tab.js +135 -0
  14. data/app/assets/javascripts/bootstrap/tooltip.js +386 -0
  15. data/app/assets/javascripts/bootstrap/transition.js +56 -0
  16. data/app/assets/javascripts/publish_my_data/grid/10_data-loader.js +142 -0
  17. data/app/assets/javascripts/publish_my_data/grid/20_cube-grid.js +512 -0
  18. data/app/assets/javascripts/publish_my_data/grid/30_cube-dimension.js +77 -0
  19. data/app/assets/javascripts/publish_my_data/grid/40_cube-dimension-dropdown.js +87 -0
  20. data/app/assets/javascripts/publish_my_data/grid/45_cube-dimension-label.js +58 -0
  21. data/app/assets/javascripts/publish_my_data/grid/50_cube-dimensions-controls.js +336 -0
  22. data/app/assets/javascripts/publish_my_data/grid/60_dataset_cube_grid.js +187 -0
  23. data/app/assets/javascripts/publish_my_data/grid/70_sparql_results_grid.js +135 -0
  24. data/app/assets/javascripts/publish_my_data/select_text.js +27 -0
  25. data/app/assets/javascripts/publish_my_data.js +3 -0
  26. data/app/assets/javascripts/slick_grid/10_event-drag.js +402 -0
  27. data/app/assets/javascripts/slick_grid/20_slick-core.js +458 -0
  28. data/app/assets/javascripts/slick_grid/30_slick-grid.js +3295 -0
  29. data/app/assets/stylesheets/bootstrap/_alerts.scss +67 -0
  30. data/app/assets/stylesheets/bootstrap/_badges.scss +51 -0
  31. data/app/assets/stylesheets/bootstrap/_breadcrumbs.scss +23 -0
  32. data/app/assets/stylesheets/bootstrap/_button-groups.scss +248 -0
  33. data/app/assets/stylesheets/bootstrap/_buttons.scss +160 -0
  34. data/app/assets/stylesheets/bootstrap/_carousel.scss +209 -0
  35. data/app/assets/stylesheets/bootstrap/_close.scss +33 -0
  36. data/app/assets/stylesheets/bootstrap/_code.scss +56 -0
  37. data/app/assets/stylesheets/bootstrap/_component-animations.scss +29 -0
  38. data/app/assets/stylesheets/bootstrap/_dropdowns.scss +194 -0
  39. data/app/assets/stylesheets/bootstrap/_forms.scss +350 -0
  40. data/app/assets/stylesheets/bootstrap/_glyphicons.scss +232 -0
  41. data/app/assets/stylesheets/bootstrap/_grid.scss +346 -0
  42. data/app/assets/stylesheets/bootstrap/_input-groups.scss +127 -0
  43. data/app/assets/stylesheets/bootstrap/_jumbotron.scss +40 -0
  44. data/app/assets/stylesheets/bootstrap/_labels.scss +58 -0
  45. data/app/assets/stylesheets/bootstrap/_list-group.scss +88 -0
  46. data/app/assets/stylesheets/bootstrap/_media.scss +56 -0
  47. data/app/assets/stylesheets/bootstrap/_mixins.scss +728 -0
  48. data/app/assets/stylesheets/bootstrap/_modals.scss +145 -0
  49. data/app/assets/stylesheets/bootstrap/_navbar.scss +625 -0
  50. data/app/assets/stylesheets/bootstrap/_navs.scss +229 -0
  51. data/app/assets/stylesheets/bootstrap/_normalize.scss +396 -0
  52. data/app/assets/stylesheets/bootstrap/_pager.scss +55 -0
  53. data/app/assets/stylesheets/bootstrap/_pagination.scss +83 -0
  54. data/app/assets/stylesheets/bootstrap/_panels.scss +148 -0
  55. data/app/assets/stylesheets/bootstrap/_popovers.scss +133 -0
  56. data/app/assets/stylesheets/bootstrap/_print.scss +100 -0
  57. data/app/assets/stylesheets/bootstrap/_progress-bars.scss +95 -0
  58. data/app/assets/stylesheets/bootstrap/_responsive-utilities.scss +209 -0
  59. data/app/assets/stylesheets/bootstrap/_scaffolding.scss +130 -0
  60. data/app/assets/stylesheets/bootstrap/_tables.scss +236 -0
  61. data/app/assets/stylesheets/bootstrap/_theme.scss +232 -0
  62. data/app/assets/stylesheets/bootstrap/_thumbnails.scss +31 -0
  63. data/app/assets/stylesheets/bootstrap/_tooltip.scss +95 -0
  64. data/app/assets/stylesheets/bootstrap/_type.scss +238 -0
  65. data/app/assets/stylesheets/bootstrap/_utilities.scss +42 -0
  66. data/app/assets/stylesheets/bootstrap/_variables.scss +620 -0
  67. data/app/assets/stylesheets/bootstrap/_wells.scss +29 -0
  68. data/app/assets/stylesheets/bootstrap/bootstrap.scss +59 -0
  69. data/app/assets/stylesheets/publish_my_data/core.scss +244 -0
  70. data/app/assets/stylesheets/publish_my_data/data_grid.scss +103 -0
  71. data/app/assets/stylesheets/publish_my_data/variables.scss +1 -0
  72. data/app/assets/stylesheets/{publish_my_data.css → publish_my_data.scss} +13 -2
  73. data/app/assets/stylesheets/slick_grid/slick_grid.scss +155 -0
  74. data/app/assets/stylesheets/slick_grid/slick_grid_default_theme.scss +97 -0
  75. data/app/controllers/concerns/publish_my_data/data_cube.rb +42 -0
  76. data/app/controllers/publish_my_data/data_cube/dimensions_controller.rb +58 -0
  77. data/app/controllers/publish_my_data/data_cube/observations_controller.rb +54 -0
  78. data/app/controllers/publish_my_data/datasets_controller.rb +0 -11
  79. data/app/controllers/publish_my_data/example_resources_controller.rb +11 -0
  80. data/app/controllers/publish_my_data/home_controller.rb +4 -0
  81. data/app/controllers/publish_my_data/information_resources_controller.rb +0 -13
  82. data/app/helpers/publish_my_data/application_helper.rb +66 -0
  83. data/app/helpers/publish_my_data/crumb_helper.rb +61 -0
  84. data/app/helpers/publish_my_data/datasets_helper.rb +31 -0
  85. data/app/helpers/publish_my_data/resources_helper.rb +24 -0
  86. data/app/models/concerns/publish_my_data/cube_results.rb +51 -0
  87. data/app/models/concerns/publish_my_data/dataset_powers.rb +13 -0
  88. data/app/models/publish_my_data/data_cube/cube.rb +358 -0
  89. data/app/models/publish_my_data/data_cube/dimension.rb +58 -0
  90. data/app/models/publish_my_data/vocabulary.rb +0 -4
  91. data/app/views/layouts/publish_my_data/application.html.haml +18 -0
  92. data/app/views/layouts/publish_my_data/error.html.haml +21 -0
  93. data/app/views/publish_my_data/classes/show.html.haml +28 -0
  94. data/app/views/publish_my_data/concept_schemes/show.html.haml +79 -0
  95. data/app/views/publish_my_data/concepts/show.html.haml +28 -0
  96. data/app/views/publish_my_data/data_cube/_controls.html.haml +19 -0
  97. data/app/views/publish_my_data/data_cube/_grid.html.haml +37 -0
  98. data/app/views/publish_my_data/datasets/_example_resources.html.haml +47 -0
  99. data/app/views/publish_my_data/datasets/_types_table.html.erb +33 -0
  100. data/app/views/publish_my_data/datasets/index.html.haml +32 -0
  101. data/app/views/publish_my_data/datasets/show.html.haml +186 -0
  102. data/app/views/publish_my_data/errors/not_found.html.haml +18 -0
  103. data/app/views/publish_my_data/errors/response_too_large.html.haml +16 -0
  104. data/app/views/publish_my_data/errors/timeout.html.haml +16 -0
  105. data/app/views/publish_my_data/errors/uncaught.html.haml +16 -0
  106. data/app/views/publish_my_data/example_resources/index.js.erb +1 -0
  107. data/app/views/publish_my_data/home/accessibility.html.haml +1 -0
  108. data/app/views/publish_my_data/home/docs.html.haml +1 -0
  109. data/app/views/publish_my_data/home/home.html.haml +5 -0
  110. data/app/views/publish_my_data/home/privacy.html.haml +1 -0
  111. data/app/views/publish_my_data/ontologies/show.html.haml +100 -0
  112. data/app/views/publish_my_data/properties/show.html.haml +28 -0
  113. data/app/views/publish_my_data/resources/_resource_data.html.haml +16 -0
  114. data/app/views/publish_my_data/resources/_sparql_section.html.haml +22 -0
  115. data/app/views/publish_my_data/resources/index.html.haml +37 -0
  116. data/app/views/publish_my_data/resources/show.html.haml +36 -0
  117. data/app/views/publish_my_data/shared/_browser_warning.html.haml +4 -0
  118. data/app/views/publish_my_data/shared/_deprecation_notice.html.haml +8 -0
  119. data/app/views/publish_my_data/shared/_footer.html.haml +11 -0
  120. data/app/views/publish_my_data/shared/_google_analytics.html.haml +11 -0
  121. data/app/views/publish_my_data/shared/_logo.html.haml +1 -0
  122. data/app/views/publish_my_data/shared/_meta_title.html.haml +2 -0
  123. data/app/views/publish_my_data/sparql/_form.html.haml +28 -0
  124. data/app/views/publish_my_data/sparql/_formats_dropdown.html.haml +11 -0
  125. data/app/views/publish_my_data/sparql/endpoint.html.haml +125 -0
  126. data/app/views/publish_my_data/sparql/formats_dropdowns/_ask.html.haml +7 -0
  127. data/app/views/publish_my_data/sparql/formats_dropdowns/_construct.html.haml +7 -0
  128. data/app/views/publish_my_data/sparql/formats_dropdowns/_describe.html.haml +1 -0
  129. data/app/views/publish_my_data/sparql/formats_dropdowns/_select.html.haml +9 -0
  130. data/app/views/publish_my_data/themes/index.html.haml +30 -0
  131. data/app/views/publish_my_data/themes/show.html.haml +43 -0
  132. data/config/routes.rb +20 -5
  133. data/lib/publish_my_data/version.rb +1 -1
  134. data/lib/publish_my_data.rb +7 -12
  135. data/spec/controllers/publish_my_data/datasets_controller_spec.rb +0 -75
  136. data/spec/controllers/publish_my_data/information_resources_controller_spec.rb +2 -11
  137. data/spec/dummy/config/environments/development.rb +0 -4
  138. data/spec/dummy/config/environments/test.rb +0 -4
  139. data/spec/dummy/log/test.log +62962 -0
  140. data/spec/dummy/tmp/cache/sass/e509ccd4d793d2c162d70125e9f3656b6c28f357/(__TEMPLATE__)c +0 -0
  141. data/spec/features/running_a_sparql_query_spec.rb +1 -1
  142. data/spec/features/uri_dereferencing_spec.rb +1 -1
  143. metadata +200 -58
  144. data/app/controllers/concerns/publish_my_data/data_download.rb +0 -22
  145. data/app/controllers/publish_my_data/vocabularies_controller.rb +0 -18
  146. data/app/views/layouts/publish_my_data/application.html.erb +0 -13
  147. data/app/views/layouts/publish_my_data/error.html.erb +0 -13
  148. data/app/views/publish_my_data/classes/show.html.erb +0 -3
  149. data/app/views/publish_my_data/concept_schemes/_concepts.html.erb +0 -18
  150. data/app/views/publish_my_data/concept_schemes/show.html.erb +0 -11
  151. data/app/views/publish_my_data/concepts/show.html.erb +0 -3
  152. data/app/views/publish_my_data/datasets/index.html.erb +0 -20
  153. data/app/views/publish_my_data/datasets/show.html.erb +0 -18
  154. data/app/views/publish_my_data/errors/not_found.html.erb +0 -1
  155. data/app/views/publish_my_data/errors/response_too_large.html.erb +0 -1
  156. data/app/views/publish_my_data/errors/timeout.html.erb +0 -1
  157. data/app/views/publish_my_data/errors/uncaught.html.erb +0 -6
  158. data/app/views/publish_my_data/ontologies/show.html.erb +0 -17
  159. data/app/views/publish_my_data/properties/show.html.erb +0 -3
  160. data/app/views/publish_my_data/resources/_predicates_table.html.erb +0 -30
  161. data/app/views/publish_my_data/resources/_predicates_table_head.html.erb +0 -6
  162. data/app/views/publish_my_data/resources/_resource_formats.html.erb +0 -4
  163. data/app/views/publish_my_data/resources/_summaries.html.erb +0 -18
  164. data/app/views/publish_my_data/resources/_uri_and_label.html.erb +0 -3
  165. data/app/views/publish_my_data/resources/index.html.erb +0 -40
  166. data/app/views/publish_my_data/resources/show.html.erb +0 -3
  167. data/app/views/publish_my_data/sparql/_ask_formats.html.erb +0 -3
  168. data/app/views/publish_my_data/sparql/_construct_formats.html.erb +0 -3
  169. data/app/views/publish_my_data/sparql/_describe_formats.html.erb +0 -1
  170. data/app/views/publish_my_data/sparql/_error_message.html.erb +0 -3
  171. data/app/views/publish_my_data/sparql/_form.html.erb +0 -4
  172. data/app/views/publish_my_data/sparql/_formats.html.erb +0 -6
  173. data/app/views/publish_my_data/sparql/_pagination.html.erb +0 -6
  174. data/app/views/publish_my_data/sparql/_results.html.erb +0 -5
  175. data/app/views/publish_my_data/sparql/_results_data.html.erb +0 -4
  176. data/app/views/publish_my_data/sparql/_select_formats.html.erb +0 -3
  177. data/app/views/publish_my_data/sparql/endpoint.html.erb +0 -10
  178. data/app/views/publish_my_data/themes/index.html.erb +0 -13
  179. data/app/views/publish_my_data/themes/show.html.erb +0 -15
  180. data/config/initializers/20_s3_setup.rb +0 -4
  181. data/spec/controllers/publish_my_data/vocabularies_controller_spec.rb +0 -14
  182. data/spec/support/data_download.rb +0 -60
@@ -0,0 +1,358 @@
1
+ module PublishMyData
2
+ module DataCube
3
+
4
+ class Cube
5
+
6
+ include PublishMyData::CubeResults
7
+
8
+ attr_reader :dataset
9
+
10
+ def initialize(dataset)
11
+ @dataset = dataset
12
+ end
13
+
14
+ def recommended_dimensions
15
+
16
+ dim_objs = dimensions.map { |d| PublishMyData::DataCube::Dimension.new(d[:uri], self) }
17
+
18
+ sorted_dims = dim_objs.sort{ |x,y| y.size <=> x.size } # ordered by size desc
19
+
20
+ largest_dimension = sorted_dims.first
21
+ second_largest_dimension = sorted_dims[1]
22
+
23
+ locked_dims = {}
24
+
25
+ # other dims
26
+ (2...sorted_dims.length).each do |i|
27
+ dim = sorted_dims[i]
28
+ locked_dims[dim.uri] = dim.values.first[:uri]
29
+ end
30
+
31
+ {
32
+ rows_dimension: largest_dimension.uri,
33
+ columns_dimension: second_largest_dimension.uri,
34
+ locked_dimensions: locked_dims
35
+ }
36
+ end
37
+
38
+ # a collection of dimension properties for this cube
39
+ def dimensions
40
+
41
+ query = "PREFIX qb: <http://purl.org/linked-data/cube#>
42
+ PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
43
+
44
+ SELECT DISTINCT ?uri ?label WHERE {
45
+ ?uri a qb:DimensionProperty .
46
+ OPTIONAL {
47
+ ?uri rdfs:label ?label .
48
+ }
49
+ GRAPH <#{dataset.data_graph_uri}> {
50
+ ?s ?uri ?o .
51
+ }
52
+ }"
53
+
54
+ uris_and_labels_only(Tripod::SparqlClient::Query.select(query))
55
+ end
56
+
57
+ # the (one and only) measure property for this cube.
58
+ def measure_property
59
+
60
+ query = "PREFIX qb: <http://purl.org/linked-data/cube#>
61
+ PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
62
+
63
+ SELECT DISTINCT ?uri ?label WHERE {
64
+ ?uri a qb:MeasureProperty .
65
+ OPTIONAL {
66
+ ?uri rdfs:label ?label .
67
+ }
68
+ GRAPH <#{dataset.data_graph_uri}> {
69
+ ?s ?uri ?o .
70
+ }
71
+ }"
72
+
73
+ uris_and_labels_only(Tripod::SparqlClient::Query.select(query)).first
74
+ end
75
+
76
+ # For a given row and column dimension,
77
+ # and a hash of locked dimensions {dimension uri => value}
78
+ # Returns an arry of hashes for the page, with one row per item in the array.
79
+ def grid_observations(page, per_page, rows_dimension_uri, columns_dimension_uri, locked_dimensions={}, order_desc=false, order_by_column_uri=nil)
80
+ measure_property_uri = measure_property[:uri].to_s
81
+ sparql = grid_rows_observations_sparql(page, per_page, rows_dimension_uri, columns_dimension_uri, measure_property_uri, locked_dimensions, order_desc, order_by_column_uri)
82
+ results = Tripod::SparqlClient::Query.select(sparql)
83
+ grid_data(results, rows_dimension_uri, columns_dimension_uri)
84
+ end
85
+
86
+ # For a given row and column dimension,
87
+ # and a hash of locked dimensions {dimension uri => value}
88
+ def csv_observations(rows_dimension_uri, columns_dimension_uri, locked_dimensions={}, order_desc=false, order_by_column_uri=nil)
89
+ measure_property_uri = measure_property[:uri].to_s
90
+
91
+ page = 1
92
+ per_page = 5000
93
+ page_of_results = nil
94
+ results = []
95
+
96
+ while page == 1 || page_of_results.size == per_page
97
+ sparql = paged_observations_sparql(page, per_page, rows_dimension_uri, columns_dimension_uri, measure_property_uri, locked_dimensions, order_desc, order_by_column_uri)
98
+ page_of_results = Tripod::SparqlClient::Query.select(sparql)
99
+ results += page_of_results
100
+ page += 1
101
+ end
102
+
103
+ csv_data(results, rows_dimension_uri, columns_dimension_uri, locked_dimensions)
104
+ end
105
+
106
+ private
107
+
108
+ # convert the results in to a csv format.
109
+ def csv_data(sparql_results, rows_dimension_uri, columns_dimension_uri, locked_dimensions)
110
+
111
+ grid_data_results = grid_data(sparql_results, rows_dimension_uri, columns_dimension_uri)
112
+
113
+ # start the headers off with just the rows dimension label
114
+ header_uris = [nil, nil]
115
+ header_labels = [rows_dimension_uri, (Resource.find(rows_dimension_uri).label || rows_dimension_uri)]
116
+
117
+ columns = PublishMyData::DataCube::Dimension.new(columns_dimension_uri, self).values
118
+
119
+ columns.each do |col|
120
+ header_uris << col[:uri]
121
+ header_labels << (col[:label].present? ? col[:label] : col[:uri])
122
+ end
123
+
124
+ CSV.generate() do |csv|
125
+
126
+ csv << ["Generated by #{PublishMyData.local_domain}", Time.now.iso8601]
127
+ csv << [dataset.uri, dataset.title]
128
+
129
+ locked_dimensions.each_pair do |dimension_uri, dimension_value_uri|
130
+ dimension_res = Resource.find(dimension_uri) rescue nil
131
+ dimension_value_res = Resource.find(dimension_value_uri) rescue nil
132
+ csv << [((dimension_res && dimension_res.label) || dimension_uri),
133
+ ((dimension_value_res && dimension_value_res.label) || dimension_value_uri)]
134
+ end
135
+
136
+ csv << []
137
+
138
+ # add another row, with the column header URIs.
139
+ csv << header_uris
140
+ csv << header_labels
141
+
142
+ grid_data_results.each do |row|
143
+
144
+ row_array = []
145
+ row_array << ( row[rows_dimension_uri] ) # the row uri
146
+ row_array << ( row["rowlabel"].present? ? row["rowlabel"] : row[rows_dimension_uri] ) # the row label
147
+
148
+ header_uris[2,header_uris.length-1].each do |h|
149
+ if row[h]
150
+ row_array << row[h][:val]
151
+ else
152
+ row_array << nil
153
+ end
154
+ end
155
+
156
+ csv << row_array
157
+ end
158
+
159
+ end
160
+
161
+ end
162
+
163
+
164
+ # convert the sparql results into a grid format (array of hashes)
165
+ def grid_data(sparql_results, rows_dimension_uri, columns_dimension_uri)
166
+
167
+ rows_hash = {}
168
+
169
+ sparql_results.each do |result|
170
+ row_uri = result["row"]["value"]
171
+ column_uri = result["column"]["value"]
172
+ val = result["val"]["value"]
173
+ obs = result["obs"]["value"]
174
+ row_label = result["rowlabel"]["value"] if result["rowlabel"]
175
+ rows_hash[row_uri] ||= {}
176
+ rows_hash[row_uri]["rowlabel"] = row_label
177
+ rows_hash[row_uri][column_uri] = {val: val, obs: obs}
178
+ end
179
+
180
+ # we now have a fully popluated rows_hash.
181
+ # {
182
+ # "row-1-uri": {"col-1-uri": {val: blah, obs: obs-uri}, "col-2-uri": {val: blah, obs: obs-uri},
183
+ # "row-2-uri": ....
184
+ # }
185
+
186
+ # now build the actual rows to return
187
+ rows = []
188
+ rows_hash.each_pair do |row_uri, row_data|
189
+
190
+ # init the results row with just the row uri
191
+ row = {}
192
+ row[rows_dimension_uri] = row_uri
193
+
194
+ row_data.each_pair do |column_uri, column_value|
195
+ row[column_uri] = column_value
196
+ end
197
+
198
+ rows << row
199
+ end
200
+
201
+ rows
202
+ end
203
+
204
+ # build up a sparql query which gets a page observations (not based on grid rows).
205
+ # this is much quicker than the grid-paged version below.
206
+ def paged_observations_sparql(page, per_page, rows_dimension_uri, columns_dimension_uri, measure_property_uri, locked_dimensions={}, order_desc=false, order_by_column_uri=nil)
207
+ offset = (page-1) * per_page
208
+ order_dir = order_desc ? "DESC" : "ASC"
209
+
210
+ sparql = sparql_prefixes
211
+
212
+ sparql += "
213
+ SELECT ?row (?firstrowlabel as ?rowlabel) ?column ?obs ?val {
214
+
215
+ SELECT ?row (MIN(?rowlabel) as ?firstrowlabel) ?column ?obs ?val WHERE {
216
+
217
+ SELECT ?row ?rowlabel ?column ?obs ?val WHERE {
218
+ GRAPH <#{dataset.data_graph_uri.to_s}> {
219
+ ?obs <#{rows_dimension_uri.to_s}> ?row .
220
+ ?obs <#{columns_dimension_uri.to_s}> ?column .
221
+ ?obs <#{measure_property_uri.to_s}> ?val ."
222
+
223
+ locked_dimensions.each_pair do |dimension_uri, dimension_value|
224
+ sparql += "
225
+ ?obs <#{dimension_uri.to_s}> <#{dimension_value.to_s}> . "
226
+ end
227
+ sparql += "
228
+ }
229
+ "
230
+ if order_by_column_uri
231
+ sparql += optional_column_ordering_clauses(order_by_column_uri, rows_dimension_uri, columns_dimension_uri, measure_property_uri, locked_dimensions)
232
+ end
233
+
234
+ sparql += "
235
+ OPTIONAL {
236
+ ?row rdfs:label ?rowlabel .
237
+ }
238
+ }
239
+
240
+ }
241
+ GROUP BY ?row ?column ?obs ?val
242
+ }
243
+ "
244
+ if order_by_column_uri
245
+ sparql += "
246
+ ORDER BY #{order_dir}(?val) "
247
+ else
248
+ sparql += "
249
+ ORDER BY #{order_dir}(?firstrowlabel)" # order by the row labels by default
250
+ end
251
+
252
+ sparql += "LIMIT #{per_page} OFFSET #{offset}"
253
+
254
+ end
255
+
256
+ # build up a sparql query which gets the observations for a set of rows of the cube grid
257
+ def grid_rows_observations_sparql(page, per_page, rows_dimension_uri, columns_dimension_uri, measure_property_uri, locked_dimensions={}, order_desc=false, order_by_column_uri=nil)
258
+
259
+ offset = (page-1) * per_page
260
+ order_dir = order_desc ? "DESC" : "ASC"
261
+
262
+ sparql = sparql_prefixes
263
+ sparql += "
264
+ SELECT ?row (?firstrowlabel as ?rowlabel) ?column (?o2 as ?obs) (?val2 as ?val)
265
+ WHERE {
266
+ {
267
+ SELECT ?row (MIN(?rowlabel) as ?firstrowlabel) WHERE {
268
+ {
269
+ SELECT DISTINCT ?row
270
+ WHERE {
271
+ GRAPH <#{dataset.data_graph_uri.to_s}> {
272
+ ?o <#{rows_dimension_uri.to_s}> ?row . "
273
+
274
+ # add the locked dimensions here so that we get the right limited set of rows (the ref dimensions etc might change between years etc).
275
+ locked_dimensions.each_pair do |dimension_uri, dimension_value|
276
+ sparql += "
277
+ ?o <#{dimension_uri.to_s}> <#{dimension_value.to_s}> . "
278
+ end
279
+
280
+ sparql += " }
281
+ }
282
+ }"
283
+
284
+ # only need to add these clauses if ordering by a column
285
+ if order_by_column_uri
286
+ sparql += optional_column_ordering_clauses(order_by_column_uri, rows_dimension_uri, columns_dimension_uri, measure_property_uri, locked_dimensions)
287
+ end
288
+
289
+ # put the row label constraint in its own optional block
290
+ sparql += "
291
+ OPTIONAL {
292
+ ?row rdfs:label ?rowlabel .
293
+ }
294
+ }
295
+
296
+ # group by rows so we can get the first label
297
+ GROUP BY ?row
298
+ "
299
+
300
+ if order_by_column_uri
301
+ sparql += "
302
+ ?val # this is an extra group by
303
+ ORDER BY #{order_dir}(?val) "
304
+ else
305
+ sparql += "
306
+ ORDER BY #{order_dir}(?firstrowlabel) " # order by the row labels by default
307
+ end
308
+
309
+ sparql += "
310
+ LIMIT #{per_page} OFFSET #{offset}
311
+ }
312
+
313
+ GRAPH <#{dataset.data_graph_uri.to_s}> {
314
+ ?o2 <#{rows_dimension_uri.to_s}> ?row .
315
+ ?o2 <#{columns_dimension_uri.to_s}> ?column .
316
+ ?o2 <#{measure_property_uri.to_s}> ?val2 .
317
+ "
318
+
319
+ locked_dimensions.each_pair do |dimension_uri, dimension_value|
320
+ sparql += "
321
+ ?o2 <#{dimension_uri.to_s}> <#{dimension_value.to_s}> . "
322
+ end
323
+
324
+ sparql += "
325
+ }
326
+ } "
327
+ sparql
328
+ end
329
+
330
+ def sparql_prefixes
331
+ "PREFIX qb: <http://purl.org/linked-data/cube#>
332
+ PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
333
+ "
334
+ end
335
+
336
+ def optional_column_ordering_clauses(order_by_column_uri, rows_dimension_uri, columns_dimension_uri, measure_property_uri, locked_dimensions)
337
+ sparql = "
338
+ OPTIONAL {
339
+ GRAPH <#{dataset.data_graph_uri.to_s}> {
340
+ ?o3 <#{rows_dimension_uri.to_s}> ?row .
341
+ ?o3 <#{columns_dimension_uri.to_s}> <#{order_by_column_uri.to_s}> .
342
+ ?o3 <#{measure_property_uri.to_s}> ?val . "
343
+
344
+ locked_dimensions.each_pair do |dimension_uri, dimension_value|
345
+ sparql += "
346
+ ?o3 <#{dimension_uri.to_s}> <#{dimension_value.to_s}> . "
347
+ end
348
+
349
+ sparql += " }
350
+ } "
351
+
352
+ return sparql
353
+ end
354
+
355
+ end
356
+
357
+ end
358
+ end
@@ -0,0 +1,58 @@
1
+ module PublishMyData
2
+ module DataCube
3
+
4
+ class Dimension
5
+
6
+ include PublishMyData::CubeResults
7
+
8
+ attr_reader :uri
9
+ attr_reader :cube
10
+
11
+ PAGE_SIZE = 5000
12
+
13
+ def initialize(uri, cube)
14
+ @uri = uri
15
+ @cube = cube
16
+ end
17
+
18
+ # get all the possible values (uris and labels) for this dimension in the dataset passed in.
19
+ # paginates internally if necessary.
20
+ def values
21
+ sparql = values_sparql(labels:true)
22
+ results = loop_and_page_sparql_query(sparql) # by default this tries 5000 rows at a time.
23
+ uris_and_labels_only(results)
24
+ end
25
+
26
+ def size
27
+ # don't get labels and don't paginate.
28
+ sparql = values_sparql({labels:false})
29
+ sq = Tripod::SparqlQuery.new(sparql)
30
+ count_sparql = sq.as_count_query_str
31
+ result = Tripod::SparqlClient::Query.select(count_sparql)
32
+ result[0]["tripod_count_var"]["value"].to_i
33
+ end
34
+
35
+ private
36
+
37
+ def values_sparql(opts={})
38
+ labels = opts[:labels]
39
+
40
+ sparql = "PREFIX qb: <http://purl.org/linked-data/cube#>
41
+ PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
42
+ SELECT DISTINCT ?uri #{labels ? '?label' : ""} WHERE {
43
+ GRAPH <#{cube.dataset.data_graph_uri.to_s}> {
44
+ ?obs qb:dataSet <#{cube.dataset.uri.to_s}> .
45
+ ?obs <#{self.uri.to_s}> ?uri .
46
+ }
47
+ "
48
+ sparql += "OPTIONAL { ?uri rdfs:label ?label . } " if labels
49
+ sparql += " } "
50
+ sparql += " ORDER BY #{labels ? '?label' : ''} ?uri"
51
+ sparql
52
+ end
53
+
54
+
55
+
56
+ end
57
+ end
58
+ end
@@ -4,10 +4,6 @@ module PublishMyData
4
4
  include Tripod::Resource
5
5
  include AllFeatures
6
6
 
7
- def self.find_by_data_dump(data_dump_uri)
8
- all.where("?uri <#{RDF::VOID.dataDump}> <#{data_dump_uri}>").first
9
- end
10
-
11
7
  # override
12
8
  def slug
13
9
  uri_hash(self.uri)
@@ -0,0 +1,18 @@
1
+ !!! 5
2
+ %html
3
+ %head
4
+ %title
5
+ = render 'publish_my_data/shared/meta_title'
6
+ = yield :page_description
7
+ = javascript_include_tag :publish_my_data
8
+ = stylesheet_link_tag :publish_my_data
9
+ %body
10
+ /[if lt IE 8]
11
+ = render 'publish_my_data/shared/browser_warning'
12
+ %header
13
+ %nav
14
+ = render 'publish_my_data/shared/logo'
15
+ = yield :crumbs
16
+ %main= yield
17
+ = render 'publish_my_data/shared/footer'
18
+ = render 'publish_my_data/shared/google_analytics'
@@ -0,0 +1,21 @@
1
+ - # error layout: by default this is the same as application layout
2
+ - # but it's a separate layout for easier custom error pages in your app.
3
+
4
+ !!! 5
5
+ %html
6
+ %head
7
+ %title
8
+ = render 'publish_my_data/shared/meta_title'
9
+ = yield :page_description
10
+ = javascript_include_tag :publish_my_data
11
+ = stylesheet_link_tag :publish_my_data
12
+ %body
13
+ /[if lt IE 8]
14
+ = render 'publish_my_data/shared/browser_warning'
15
+ %header
16
+ %nav
17
+ = render 'publish_my_data/shared/logo'
18
+ = yield :crumbs
19
+ %main= yield
20
+ = render 'publish_my_data/shared/footer'
21
+ = render 'publish_my_data/shared/google_analytics'
@@ -0,0 +1,28 @@
1
+ - page_title "Class: #{ontology_class.label || ontology_class.uri}"
2
+
3
+ - content_for :crumbs do
4
+ %ol.breadcrumb
5
+ %li= link_to_home
6
+ - if ontology_class.defined_by_ontology
7
+ %li= link_to "Ontology: #{ontology_class.defined_by_ontology.label || ontology_class.defined_by_ontology.uri}", resource_path_from_uri(ontology_class.defined_by_ontology.uri)
8
+ %li Class
9
+
10
+ %article#resource
11
+ %header
12
+ %h3 Class
13
+ %h1= ontology_class.label || ontology_class.uri
14
+ %h3 URI
15
+ %h2.click-to-select= ontology_class.uri
16
+
17
+ = render 'publish_my_data/resources/resource_data', resource: ontology_class
18
+
19
+ %footer.alternative-formats
20
+ :markdown
21
+ This **class** is available as:
22
+ %ul
23
+ %li HTML
24
+ %li= link_to("JSON", show_resource_path(:uri => ontology_class.uri, :format => 'json'))
25
+ %li= link_to("RDF/XML", show_resource_path(:uri => ontology_class.uri, :format => 'rdf'))
26
+ %li= link_to("Turtle", show_resource_path(:uri => ontology_class.uri, :format => 'ttl'))
27
+ %li= link_to("N-triples", show_resource_path(:uri => ontology_class.uri, :format => 'nt'))
28
+
@@ -0,0 +1,79 @@
1
+ - page_title("Concept Scheme: #{concept_scheme.label || concept_scheme.uri}")
2
+
3
+ - content_for :crumbs do
4
+ %ol.breadcrumb
5
+ %li= link_to_home
6
+ %li= link_to 'Concept Scheme', resource_path_from_uri(concept_scheme.uri)
7
+
8
+ - if concept_scheme.deprecated?
9
+ = render partial: 'publish_my_data/shared/deprecation_notice', locals: {resource: dataset}
10
+
11
+ %article#concept-scheme
12
+ %header
13
+ %h3= concept_scheme.local? ? 'Concept Scheme' : 'External Concept Scheme'
14
+ %h1= concept_scheme.label || concept_scheme.uri
15
+ %h3 URI
16
+ %h2.click-to-select= concept_scheme.uri
17
+
18
+ %section.metadata
19
+ .primary
20
+ - if concept_scheme.comment.present?
21
+ %h3 Description
22
+ %p= auto_link concept_scheme.comment.to_s
23
+ - if concept_scheme.publisher.present?
24
+ %h3 Publisher
25
+ %p= resource_uri_or_label(concept_scheme, concept_scheme.publisher)
26
+ - if concept_scheme.license.present?
27
+ %h3 Licence
28
+ %p= resource_uri_or_label(concept_scheme, concept_scheme.license)
29
+ - if concept_scheme.contact_email.present?
30
+ %h3 Contact
31
+ %p= auto_link concept_scheme.contact_email.to_s.gsub('mailto:','')
32
+ - if concept_scheme.description.present?
33
+ %h3 Further Information
34
+ .js-only
35
+ #further-information.truncated
36
+ :markdown
37
+ #{concept_scheme.description.to_s}
38
+ .fade-out
39
+ %p
40
+ %a#read-more(href="#") Read more
41
+ %noscript
42
+ :markdown
43
+ #{concept_scheme.description.to_s}
44
+ :css
45
+ .js-only { display: none; }
46
+ :javascript
47
+ $("a#read-more").click(function(e) {
48
+ e.preventDefault();
49
+ $("#further-information").removeClass("truncated");
50
+ $("#further-information .fade-out").hide();
51
+ $("a#read-more").closest('p').hide();
52
+ });
53
+ .secondary
54
+ - if concept_scheme.issued.present?
55
+ %h3 Issued
56
+ %p= formatted_date(concept_scheme.issued.to_s)
57
+ - if concept_scheme.modified.present?
58
+ %h3 Modified
59
+ %p= formatted_date(concept_scheme.modified.to_s)
60
+ - if concept_scheme.tags.try(:any?)
61
+ %h3 Tags
62
+ %p= concept_scheme.tags.join(', ')
63
+
64
+ %ul.tab-links
65
+ %li.active
66
+ %a(href="#concepts" data-toggle="tab") Concepts
67
+ %li
68
+ %a(href="#linked-data" data-toggle="tab") Linked Data &amp; SPARQL
69
+
70
+ .tab-content
71
+ %section#concepts.active
72
+ .content
73
+ %ul
74
+ - concept_scheme.concepts.each do |concept|
75
+ %li
76
+ %h3= resource_uri_or_label(concept, concept.uri)
77
+ %h4.click-to-select= concept.uri
78
+ %p= concept.comment
79
+ = render 'publish_my_data/resources/sparql_section', resource: concept_scheme
@@ -0,0 +1,28 @@
1
+ - page_title "Concept #{concept.label || concept.uri}"
2
+
3
+ - content_for :crumbs do
4
+ %ol.breadcrumb
5
+ %li= link_to_home
6
+ - if concept.concept_scheme
7
+ %li= link_to "Concept Scheme: #{concept.concept_scheme.label || concept.concept_scheme.uri}", resource_path_from_uri(concept.concept_scheme.uri)
8
+ %li Concept
9
+
10
+ %article#resource
11
+ %header
12
+ %h3 Concept
13
+ %h1= concept.label || concept.uri
14
+ %h3 URI
15
+ %h2.click-to-select= concept.uri
16
+
17
+ = render 'publish_my_data/resources/resource_data', resource: concept
18
+
19
+ %footer.alternative-formats
20
+ :markdown
21
+ This **concept** is available as:
22
+ %ul
23
+ %li HTML
24
+ %li= link_to("JSON", show_resource_path(:uri => concept.uri, :format => 'json'))
25
+ %li= link_to("RDF/XML", show_resource_path(:uri => concept.uri, :format => 'rdf'))
26
+ %li= link_to("Turtle", show_resource_path(:uri => concept.uri, :format => 'ttl'))
27
+ %li= link_to("N-triples", show_resource_path(:uri => concept.uri, :format => 'nt'))
28
+
@@ -0,0 +1,19 @@
1
+ #dimensions-controls
2
+ %form(style="margin:0; display:none")
3
+ .rows-and-columns
4
+ %fieldset.rows-and-columns
5
+ %legend Row and Column Headings
6
+
7
+ .field
8
+ %label Column Headings
9
+ %div#columns-dimension-container.picker
10
+
11
+ .field
12
+ %label Rows (values in first column)
13
+ %div#rows-dimension-container.picker
14
+
15
+ .other-options
16
+ %fieldset
17
+ %legend Other Options
18
+ .locked-dimensions
19
+ No other options for this dataset
@@ -0,0 +1,37 @@
1
+ .content
2
+ .grid-intro
3
+ :markdown
4
+ This dataset contains multidimensional data (a _data cube_). This grid allows you to view two dimensions at a time.
5
+
6
+ Use the drop-downs below the grid to choose which dimensions to use for the rows and columns.
7
+
8
+ .grid-header
9
+ .grid-title
10
+ %h3#cube-grid-title
11
+ &nbsp;
12
+ .grid-status
13
+ .status-value
14
+ = image_tag("publish_my_data/small-spinner.gif", alt: "busy", style: "display:none", class: "busy")
15
+
16
+ #data-cube-grid.data-grid
17
+ .grid-footer
18
+ .footer-content
19
+
20
+ .controls-wrapper
21
+ = render 'publish_my_data/data_cube/controls'
22
+
23
+ .content
24
+ %h3 Help
25
+ .docs(style="padding-top:7px")
26
+ %ul
27
+ %li
28
+ To view the information held in our database for a column or individual cell, just click the blue links in the grid.
29
+ %li
30
+ You can re-order a column's contents by clicking on its header (anywhere except the links themselves), or resize it by dragging the column boundaries.
31
+ %li
32
+ The entire contents of grid (based on the currently selected options and ordering) can be downloaded in CSV format via the link in the grid footer.
33
+
34
+ :javascript
35
+ $(function() {
36
+ new Swirrl.DatasetCubeGrid(window.location.host, '#{dataset.slug}', "#{dataset.title}", "#data-cube-grid");
37
+ });