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.
- data/app/assets/images/publish_my_data/small-spinner.gif +0 -0
- data/app/assets/images/publish_my_data/sort-asc.gif +0 -0
- data/app/assets/images/publish_my_data/sort-desc.gif +0 -0
- data/app/assets/javascripts/bootstrap/affix.js +126 -0
- data/app/assets/javascripts/bootstrap/alert.js +98 -0
- data/app/assets/javascripts/bootstrap/button.js +109 -0
- data/app/assets/javascripts/bootstrap/carousel.js +217 -0
- data/app/assets/javascripts/bootstrap/collapse.js +179 -0
- data/app/assets/javascripts/bootstrap/dropdown.js +154 -0
- data/app/assets/javascripts/bootstrap/modal.js +246 -0
- data/app/assets/javascripts/bootstrap/popover.js +117 -0
- data/app/assets/javascripts/bootstrap/scrollspy.js +158 -0
- data/app/assets/javascripts/bootstrap/tab.js +135 -0
- data/app/assets/javascripts/bootstrap/tooltip.js +386 -0
- data/app/assets/javascripts/bootstrap/transition.js +56 -0
- data/app/assets/javascripts/publish_my_data/grid/10_data-loader.js +142 -0
- data/app/assets/javascripts/publish_my_data/grid/20_cube-grid.js +512 -0
- data/app/assets/javascripts/publish_my_data/grid/30_cube-dimension.js +77 -0
- data/app/assets/javascripts/publish_my_data/grid/40_cube-dimension-dropdown.js +87 -0
- data/app/assets/javascripts/publish_my_data/grid/45_cube-dimension-label.js +58 -0
- data/app/assets/javascripts/publish_my_data/grid/50_cube-dimensions-controls.js +336 -0
- data/app/assets/javascripts/publish_my_data/grid/60_dataset_cube_grid.js +187 -0
- data/app/assets/javascripts/publish_my_data/grid/70_sparql_results_grid.js +135 -0
- data/app/assets/javascripts/publish_my_data/select_text.js +27 -0
- data/app/assets/javascripts/publish_my_data.js +3 -0
- data/app/assets/javascripts/slick_grid/10_event-drag.js +402 -0
- data/app/assets/javascripts/slick_grid/20_slick-core.js +458 -0
- data/app/assets/javascripts/slick_grid/30_slick-grid.js +3295 -0
- data/app/assets/stylesheets/bootstrap/_alerts.scss +67 -0
- data/app/assets/stylesheets/bootstrap/_badges.scss +51 -0
- data/app/assets/stylesheets/bootstrap/_breadcrumbs.scss +23 -0
- data/app/assets/stylesheets/bootstrap/_button-groups.scss +248 -0
- data/app/assets/stylesheets/bootstrap/_buttons.scss +160 -0
- data/app/assets/stylesheets/bootstrap/_carousel.scss +209 -0
- data/app/assets/stylesheets/bootstrap/_close.scss +33 -0
- data/app/assets/stylesheets/bootstrap/_code.scss +56 -0
- data/app/assets/stylesheets/bootstrap/_component-animations.scss +29 -0
- data/app/assets/stylesheets/bootstrap/_dropdowns.scss +194 -0
- data/app/assets/stylesheets/bootstrap/_forms.scss +350 -0
- data/app/assets/stylesheets/bootstrap/_glyphicons.scss +232 -0
- data/app/assets/stylesheets/bootstrap/_grid.scss +346 -0
- data/app/assets/stylesheets/bootstrap/_input-groups.scss +127 -0
- data/app/assets/stylesheets/bootstrap/_jumbotron.scss +40 -0
- data/app/assets/stylesheets/bootstrap/_labels.scss +58 -0
- data/app/assets/stylesheets/bootstrap/_list-group.scss +88 -0
- data/app/assets/stylesheets/bootstrap/_media.scss +56 -0
- data/app/assets/stylesheets/bootstrap/_mixins.scss +728 -0
- data/app/assets/stylesheets/bootstrap/_modals.scss +145 -0
- data/app/assets/stylesheets/bootstrap/_navbar.scss +625 -0
- data/app/assets/stylesheets/bootstrap/_navs.scss +229 -0
- data/app/assets/stylesheets/bootstrap/_normalize.scss +396 -0
- data/app/assets/stylesheets/bootstrap/_pager.scss +55 -0
- data/app/assets/stylesheets/bootstrap/_pagination.scss +83 -0
- data/app/assets/stylesheets/bootstrap/_panels.scss +148 -0
- data/app/assets/stylesheets/bootstrap/_popovers.scss +133 -0
- data/app/assets/stylesheets/bootstrap/_print.scss +100 -0
- data/app/assets/stylesheets/bootstrap/_progress-bars.scss +95 -0
- data/app/assets/stylesheets/bootstrap/_responsive-utilities.scss +209 -0
- data/app/assets/stylesheets/bootstrap/_scaffolding.scss +130 -0
- data/app/assets/stylesheets/bootstrap/_tables.scss +236 -0
- data/app/assets/stylesheets/bootstrap/_theme.scss +232 -0
- data/app/assets/stylesheets/bootstrap/_thumbnails.scss +31 -0
- data/app/assets/stylesheets/bootstrap/_tooltip.scss +95 -0
- data/app/assets/stylesheets/bootstrap/_type.scss +238 -0
- data/app/assets/stylesheets/bootstrap/_utilities.scss +42 -0
- data/app/assets/stylesheets/bootstrap/_variables.scss +620 -0
- data/app/assets/stylesheets/bootstrap/_wells.scss +29 -0
- data/app/assets/stylesheets/bootstrap/bootstrap.scss +59 -0
- data/app/assets/stylesheets/publish_my_data/core.scss +244 -0
- data/app/assets/stylesheets/publish_my_data/data_grid.scss +103 -0
- data/app/assets/stylesheets/publish_my_data/variables.scss +1 -0
- data/app/assets/stylesheets/{publish_my_data.css → publish_my_data.scss} +13 -2
- data/app/assets/stylesheets/slick_grid/slick_grid.scss +155 -0
- data/app/assets/stylesheets/slick_grid/slick_grid_default_theme.scss +97 -0
- data/app/controllers/concerns/publish_my_data/data_cube.rb +42 -0
- data/app/controllers/publish_my_data/data_cube/dimensions_controller.rb +58 -0
- data/app/controllers/publish_my_data/data_cube/observations_controller.rb +54 -0
- data/app/controllers/publish_my_data/datasets_controller.rb +0 -11
- data/app/controllers/publish_my_data/example_resources_controller.rb +11 -0
- data/app/controllers/publish_my_data/home_controller.rb +4 -0
- data/app/controllers/publish_my_data/information_resources_controller.rb +0 -13
- data/app/helpers/publish_my_data/application_helper.rb +66 -0
- data/app/helpers/publish_my_data/crumb_helper.rb +61 -0
- data/app/helpers/publish_my_data/datasets_helper.rb +31 -0
- data/app/helpers/publish_my_data/resources_helper.rb +24 -0
- data/app/models/concerns/publish_my_data/cube_results.rb +51 -0
- data/app/models/concerns/publish_my_data/dataset_powers.rb +13 -0
- data/app/models/publish_my_data/data_cube/cube.rb +358 -0
- data/app/models/publish_my_data/data_cube/dimension.rb +58 -0
- data/app/models/publish_my_data/vocabulary.rb +0 -4
- data/app/views/layouts/publish_my_data/application.html.haml +18 -0
- data/app/views/layouts/publish_my_data/error.html.haml +21 -0
- data/app/views/publish_my_data/classes/show.html.haml +28 -0
- data/app/views/publish_my_data/concept_schemes/show.html.haml +79 -0
- data/app/views/publish_my_data/concepts/show.html.haml +28 -0
- data/app/views/publish_my_data/data_cube/_controls.html.haml +19 -0
- data/app/views/publish_my_data/data_cube/_grid.html.haml +37 -0
- data/app/views/publish_my_data/datasets/_example_resources.html.haml +47 -0
- data/app/views/publish_my_data/datasets/_types_table.html.erb +33 -0
- data/app/views/publish_my_data/datasets/index.html.haml +32 -0
- data/app/views/publish_my_data/datasets/show.html.haml +186 -0
- data/app/views/publish_my_data/errors/not_found.html.haml +18 -0
- data/app/views/publish_my_data/errors/response_too_large.html.haml +16 -0
- data/app/views/publish_my_data/errors/timeout.html.haml +16 -0
- data/app/views/publish_my_data/errors/uncaught.html.haml +16 -0
- data/app/views/publish_my_data/example_resources/index.js.erb +1 -0
- data/app/views/publish_my_data/home/accessibility.html.haml +1 -0
- data/app/views/publish_my_data/home/docs.html.haml +1 -0
- data/app/views/publish_my_data/home/home.html.haml +5 -0
- data/app/views/publish_my_data/home/privacy.html.haml +1 -0
- data/app/views/publish_my_data/ontologies/show.html.haml +100 -0
- data/app/views/publish_my_data/properties/show.html.haml +28 -0
- data/app/views/publish_my_data/resources/_resource_data.html.haml +16 -0
- data/app/views/publish_my_data/resources/_sparql_section.html.haml +22 -0
- data/app/views/publish_my_data/resources/index.html.haml +37 -0
- data/app/views/publish_my_data/resources/show.html.haml +36 -0
- data/app/views/publish_my_data/shared/_browser_warning.html.haml +4 -0
- data/app/views/publish_my_data/shared/_deprecation_notice.html.haml +8 -0
- data/app/views/publish_my_data/shared/_footer.html.haml +11 -0
- data/app/views/publish_my_data/shared/_google_analytics.html.haml +11 -0
- data/app/views/publish_my_data/shared/_logo.html.haml +1 -0
- data/app/views/publish_my_data/shared/_meta_title.html.haml +2 -0
- data/app/views/publish_my_data/sparql/_form.html.haml +28 -0
- data/app/views/publish_my_data/sparql/_formats_dropdown.html.haml +11 -0
- data/app/views/publish_my_data/sparql/endpoint.html.haml +125 -0
- data/app/views/publish_my_data/sparql/formats_dropdowns/_ask.html.haml +7 -0
- data/app/views/publish_my_data/sparql/formats_dropdowns/_construct.html.haml +7 -0
- data/app/views/publish_my_data/sparql/formats_dropdowns/_describe.html.haml +1 -0
- data/app/views/publish_my_data/sparql/formats_dropdowns/_select.html.haml +9 -0
- data/app/views/publish_my_data/themes/index.html.haml +30 -0
- data/app/views/publish_my_data/themes/show.html.haml +43 -0
- data/config/routes.rb +20 -5
- data/lib/publish_my_data/version.rb +1 -1
- data/lib/publish_my_data.rb +7 -12
- data/spec/controllers/publish_my_data/datasets_controller_spec.rb +0 -75
- data/spec/controllers/publish_my_data/information_resources_controller_spec.rb +2 -11
- data/spec/dummy/config/environments/development.rb +0 -4
- data/spec/dummy/config/environments/test.rb +0 -4
- data/spec/dummy/log/test.log +62962 -0
- data/spec/dummy/tmp/cache/sass/e509ccd4d793d2c162d70125e9f3656b6c28f357/(__TEMPLATE__)c +0 -0
- data/spec/features/running_a_sparql_query_spec.rb +1 -1
- data/spec/features/uri_dereferencing_spec.rb +1 -1
- metadata +200 -58
- data/app/controllers/concerns/publish_my_data/data_download.rb +0 -22
- data/app/controllers/publish_my_data/vocabularies_controller.rb +0 -18
- data/app/views/layouts/publish_my_data/application.html.erb +0 -13
- data/app/views/layouts/publish_my_data/error.html.erb +0 -13
- data/app/views/publish_my_data/classes/show.html.erb +0 -3
- data/app/views/publish_my_data/concept_schemes/_concepts.html.erb +0 -18
- data/app/views/publish_my_data/concept_schemes/show.html.erb +0 -11
- data/app/views/publish_my_data/concepts/show.html.erb +0 -3
- data/app/views/publish_my_data/datasets/index.html.erb +0 -20
- data/app/views/publish_my_data/datasets/show.html.erb +0 -18
- data/app/views/publish_my_data/errors/not_found.html.erb +0 -1
- data/app/views/publish_my_data/errors/response_too_large.html.erb +0 -1
- data/app/views/publish_my_data/errors/timeout.html.erb +0 -1
- data/app/views/publish_my_data/errors/uncaught.html.erb +0 -6
- data/app/views/publish_my_data/ontologies/show.html.erb +0 -17
- data/app/views/publish_my_data/properties/show.html.erb +0 -3
- data/app/views/publish_my_data/resources/_predicates_table.html.erb +0 -30
- data/app/views/publish_my_data/resources/_predicates_table_head.html.erb +0 -6
- data/app/views/publish_my_data/resources/_resource_formats.html.erb +0 -4
- data/app/views/publish_my_data/resources/_summaries.html.erb +0 -18
- data/app/views/publish_my_data/resources/_uri_and_label.html.erb +0 -3
- data/app/views/publish_my_data/resources/index.html.erb +0 -40
- data/app/views/publish_my_data/resources/show.html.erb +0 -3
- data/app/views/publish_my_data/sparql/_ask_formats.html.erb +0 -3
- data/app/views/publish_my_data/sparql/_construct_formats.html.erb +0 -3
- data/app/views/publish_my_data/sparql/_describe_formats.html.erb +0 -1
- data/app/views/publish_my_data/sparql/_error_message.html.erb +0 -3
- data/app/views/publish_my_data/sparql/_form.html.erb +0 -4
- data/app/views/publish_my_data/sparql/_formats.html.erb +0 -6
- data/app/views/publish_my_data/sparql/_pagination.html.erb +0 -6
- data/app/views/publish_my_data/sparql/_results.html.erb +0 -5
- data/app/views/publish_my_data/sparql/_results_data.html.erb +0 -4
- data/app/views/publish_my_data/sparql/_select_formats.html.erb +0 -3
- data/app/views/publish_my_data/sparql/endpoint.html.erb +0 -10
- data/app/views/publish_my_data/themes/index.html.erb +0 -13
- data/app/views/publish_my_data/themes/show.html.erb +0 -15
- data/config/initializers/20_s3_setup.rb +0 -4
- data/spec/controllers/publish_my_data/vocabularies_controller_spec.rb +0 -14
- 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
|
@@ -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 & 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
|
+
|
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
|
+
});
|