jekyll-open-sdg-plugins 1.1.0 → 1.2.0.pre.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6e6f79d3292ae608202621743899fe24604ee67fc7bcc9ca90d26e91bf18e8d6
4
- data.tar.gz: e09f66ec6f34a74e8b29d07f9dc75dcd2c3a4484daa3d02db45eb5140f2fd637
3
+ metadata.gz: 714570ee0a7ab38905c524b6fad9c1590340e09052778c82adc543574d11e7ac
4
+ data.tar.gz: ed6ee32ba2cb547dd8f46159fb133197b044fc101c0d00af12662cf78a245872
5
5
  SHA512:
6
- metadata.gz: d217ea0ac1fecaaf2e4d83f7d39d094be1f6d34277a52b5c34c0aa369effefb7589ec44e76d41d87ce437c84f0d1a6bcb47c657c04db751dac93fdbcb586bc19
7
- data.tar.gz: 94d80452821f6793932b5be5342d6d99814caf52dd27cd5b27e000fe67b1893364d6da9c47bc1327743125e5b01c2a49431d4405f0c075a62dd77ff182a25819
6
+ metadata.gz: 2c5862fc0ffd6241ef72f92d15e72f5a0dc4fe682a8b0a9cfe80e418968b1eadfa0aa5fa7c5ea83e82b2ebe441535d3c8e77283b7925d9ce83f491b7bcf7f99d
7
+ data.tar.gz: 789bb89817ceb676ab5eaac06411435030a6fcdf24dd4ad5c0529fa7cfadac27d5dcd91670f5894fdc983220e9cd6a04324309fee46bb747c93996e561a79821
@@ -14,4 +14,5 @@ Gem::Specification.new do |spec|
14
14
  spec.require_paths = ["lib"]
15
15
  spec.add_dependency "jekyll", "~> 3.0"
16
16
  spec.add_dependency "deep_merge", "~> 1.2"
17
+ spec.add_dependency "json_schemer", "~> 0.2"
17
18
  end
@@ -1,5 +1,6 @@
1
1
  require_relative "jekyll-open-sdg-plugins/version"
2
2
  require_relative "jekyll-open-sdg-plugins/site_configuration"
3
+ require_relative "jekyll-open-sdg-plugins/validate_site_config"
3
4
  require_relative "jekyll-open-sdg-plugins/fetch_remote_data"
4
5
  require_relative "jekyll-open-sdg-plugins/translate_key"
5
6
  require_relative "jekyll-open-sdg-plugins/translate_date"
@@ -9,6 +10,7 @@ require_relative "jekyll-open-sdg-plugins/create_goals"
9
10
  require_relative "jekyll-open-sdg-plugins/create_pages"
10
11
  require_relative "jekyll-open-sdg-plugins/sdg_variables"
11
12
  require_relative "jekyll-open-sdg-plugins/search_index"
13
+ require_relative "jekyll-open-sdg-plugins/validate_indicator_config"
12
14
 
13
15
  module JekyllOpenSdgPlugins
14
16
  end
@@ -43,6 +43,37 @@ module JekyllOpenSdgPlugins
43
43
  site.collections['indicators'].docs << IndicatorPage.new(site, site.source, dir, inid, language, layout)
44
44
  end
45
45
  end
46
+ # Create the indicator configuration pages.
47
+ metadata = {}
48
+ if opensdg_translated_builds(site)
49
+ if site.data.has_key?('untranslated')
50
+ metadata = site.data['untranslated']['meta']
51
+ else
52
+ default_language = site.config['languages'][0]
53
+ metadata = site.data[default_language]['meta']
54
+ end
55
+ else
56
+ metadata = site.data['meta']
57
+ end
58
+ # Loop through the indicators (using metadata as a list).
59
+ if !metadata.empty?
60
+ site.config['show_indicator_config_forms'] = true
61
+ # Loop through the languages.
62
+ site.config['languages'].each_with_index do |language, index|
63
+ # Get the "public language" (for URLs) which may be different.
64
+ language_public = language
65
+ if languages_public[language]
66
+ language_public = languages_public[language]
67
+ end
68
+ metadata.each do |inid, meta|
69
+ dir = File.join('config', inid)
70
+ if index != 0
71
+ dir = File.join(language_public, 'config', inid)
72
+ end
73
+ site.collections['pages'].docs << IndicatorConfigPage.new(site, site.source, dir, inid, language, meta)
74
+ end
75
+ end
76
+ end
46
77
  end
47
78
  end
48
79
  end
@@ -64,4 +95,24 @@ module JekyllOpenSdgPlugins
64
95
  self.data['indicator'] = self.data['indicator_number']
65
96
  end
66
97
  end
98
+
99
+ # A Page subclass used in the `CreateIndicators` class.
100
+ class IndicatorConfigPage < Jekyll::Page
101
+ def initialize(site, base, dir, inid, language, meta)
102
+ @site = site
103
+ @base = base
104
+ @dir = dir
105
+ @name = 'index.html'
106
+
107
+ self.process(@name)
108
+ self.data = {}
109
+ self.data['language'] = language
110
+ self.data['indicator_number'] = inid.gsub('-', '.')
111
+ self.data['config_type'] = 'indicator'
112
+ self.data['layout'] = 'config-builder'
113
+ self.data['meta'] = meta
114
+ self.data['title'] = 'Open SDG indicator configuration: ' + self.data['indicator_number']
115
+ self.data['config_filename'] = inid + '.yml'
116
+ end
117
+ end
67
118
  end
@@ -61,6 +61,21 @@ module JekyllOpenSdgPlugins
61
61
  pages = site.config['create_pages']
62
62
  end
63
63
 
64
+ # Clone pages so that we don't edit the original.
65
+ pages = pages.clone
66
+
67
+ # Hardcode the site configuration page if it's not already there.
68
+ config_page = pages.find { |page| page['layout'] == 'config-builder' }
69
+ if config_page == nil
70
+ pages.push({
71
+ 'folder' => '/config',
72
+ 'layout' => 'config-builder',
73
+ 'title' => 'Open SDG site configuration',
74
+ 'config_type' => 'site',
75
+ 'config_filename' => 'site_config.yml'
76
+ })
77
+ end
78
+
64
79
  # See if we need to "map" any language codes.
65
80
  languages_public = Hash.new
66
81
  if site.config['languages_public']
@@ -22,20 +22,17 @@ module JekyllOpenSdgPlugins
22
22
  'headlines' => 'headline/all.json',
23
23
  'schema' => 'meta/schema.json',
24
24
  'reporting' => 'stats/reporting.json',
25
+ 'disaggregation' => 'stats/disaggregation.json',
25
26
  'translations' => 'translations/translations.json',
26
- 'zip' => 'zip/all_indicators.json'
27
+ 'zip' => 'zip/all_indicators.json',
28
+ 'indicator_downloads' => 'downloads/indicator-downloads.json'
27
29
  }
28
30
  end
29
31
 
30
- # Is this path a remote path?
31
- def is_path_remote(path)
32
- return path.start_with?('http')
33
- end
34
-
35
32
  # Get a build from a local folder on disk or a remote URL on the Internet.
36
33
  def fetch_build(path)
37
34
 
38
- is_remote = is_path_remote(path)
35
+ is_remote = opensdg_is_path_remote(path)
39
36
  build = {}
40
37
  get_endpoints().each do |key, value|
41
38
  endpoint = is_remote ? path + '/' + value : File.join(path, fix_path(value))
@@ -44,8 +41,14 @@ module JekyllOpenSdgPlugins
44
41
  json_file = is_remote ? open(endpoint) : File.open(endpoint)
45
42
  build[key] = JSON.load(json_file)
46
43
  rescue StandardError => e
47
- # For backwards compatibility, we allow 'translations' to be missing.
48
- if key != 'translations'
44
+ # For backwards compatibility, forego the exception in some cases.
45
+ abort_build = true
46
+ if ['translations', 'indicator_downloads', 'disaggregation'].include? key
47
+ abort_build = false
48
+ elsif endpoint.include? '/untranslated/'
49
+ abort_build = false
50
+ end
51
+ if abort_build
49
52
  puts e.message
50
53
  abort 'Unable to read data from: ' + endpoint
51
54
  end
@@ -59,7 +62,7 @@ module JekyllOpenSdgPlugins
59
62
  # translated builds or not.
60
63
  def site_uses_translated_builds(path)
61
64
 
62
- is_remote = is_path_remote(path)
65
+ is_remote = opensdg_is_path_remote(path)
63
66
  endpoints = get_endpoints()
64
67
  # For a quick test, we just use 'meta'.
65
68
  meta = endpoints['meta']
@@ -88,23 +91,30 @@ module JekyllOpenSdgPlugins
88
91
  local = site.config['local_data_folder']
89
92
 
90
93
  if !remote && !local
91
- abort 'Site config must include either "remote_data_prefix" or "local_data_folder".'
94
+ abort 'Site config must include "remote_data_prefix".'
92
95
  end
93
96
 
94
- build_location = remote ? remote : File.join(Dir.pwd, local)
97
+ build_location = remote ? remote : local
98
+ is_remote = opensdg_is_path_remote(build_location)
99
+
100
+ build_location = is_remote ? build_location : File.join(Dir.pwd, build_location)
95
101
  translated_builds = site_uses_translated_builds(build_location)
96
102
 
97
103
  if translated_builds
98
104
  # For translated builds, we get a build for each language, and
99
105
  # place them in "subfolders" (so to speak) of site.data.
100
- site.config['languages'].each do |language|
106
+ subfolders = site.config['languages'].clone
107
+ subfolders.append('untranslated')
108
+ subfolders.each do |language|
101
109
  data_target = site.data[language]
102
- translated_build = remote ? build_location + '/' + language : File.join(build_location, language)
110
+ translated_build = is_remote ? build_location + '/' + language : File.join(build_location, language)
103
111
  data_source = fetch_build(translated_build)
104
- if data_target
105
- data_target.deep_merge(data_source)
106
- else
107
- site.data[language] = data_source
112
+ if !data_source.empty?
113
+ if data_target
114
+ data_target.deep_merge(data_source)
115
+ else
116
+ site.data[language] = data_source
117
+ end
108
118
  end
109
119
  end
110
120
  # We move the language-specific translations to the
@@ -129,7 +139,9 @@ module JekyllOpenSdgPlugins
129
139
  # in the "root" (so to speak) of site.data. Nothing else is needed.
130
140
  target = site.data
131
141
  source = fetch_build(build_location)
132
- target.deep_merge(source)
142
+ if !source.empty?
143
+ target.deep_merge(source)
144
+ end
133
145
  end
134
146
 
135
147
  # Finally support the deprecated 'remote_translations' option.
@@ -162,6 +174,14 @@ module JekyllOpenSdgPlugins
162
174
  source = File.join(Dir.pwd, site.config['local_data_folder'], '.')
163
175
  destination = site.config['destination']
164
176
  FileUtils.cp_r(source, destination)
177
+ # Do the same in the case that "remote_data_prefix" is being used for a local
178
+ # data folder (since "local_data_folder" is deprecated and undocumented).
179
+ elsif site.config['remote_data_prefix']
180
+ if !opensdg_is_path_remote(site.config['remote_data_prefix'])
181
+ source = File.join(Dir.pwd, site.config['remote_data_prefix'], '.')
182
+ destination = site.config['destination']
183
+ FileUtils.cp_r(source, destination)
184
+ end
165
185
  end
166
186
  end
167
187
  end
@@ -92,3 +92,41 @@ def opensdg_languages_public(site)
92
92
  # since the deprecated structure is exactly what this function wants.
93
93
  return languages_public
94
94
  end
95
+
96
+ # Print notices about a validation error.
97
+ def opensdg_validation_error(error)
98
+ if error['type'] == 'required'
99
+ missing = []
100
+ error['schema']['required'].each do |required_property|
101
+ unless error['data'].has_key?(required_property)
102
+ message = 'Missing configuration setting: ' + required_property
103
+ if error['schema'].has_key?('title')
104
+ message += ' (' + error['schema']['title'] + ')'
105
+ end
106
+ opensdg_notice(message)
107
+ end
108
+ end
109
+ else
110
+ message = 'Validation error of type: ' + error['type']
111
+ if error['schema'] && error['schema'].has_key?('title')
112
+ message += ' (' + error['schema']['title'] + ')'
113
+ end
114
+ opensdg_notice(message)
115
+ if error['schema']
116
+ opensdg_notice('Expected schema:')
117
+ puts error['schema'].inspect
118
+ end
119
+ if error['data']
120
+ opensdg_notice('Actual data:')
121
+ puts error['data'].inspect
122
+ end
123
+ end
124
+ end
125
+
126
+ # Is this path a remote path?
127
+ def opensdg_is_path_remote(path)
128
+ if path.nil?
129
+ return false
130
+ end
131
+ return path.start_with?('http')
132
+ end
@@ -0,0 +1,516 @@
1
+ {
2
+ "type": "object",
3
+ "title": "Open SDG indicator configuration",
4
+ "description": "This form will produce an indicator's configuration for your Open SDG implementation.",
5
+ "properties": {
6
+ "computation_units": {
7
+ "type": "string",
8
+ "title": "Unit of measurement",
9
+ "description": "Unit of measurement which displays below the indicator chart.",
10
+ "links": [
11
+ {
12
+ "rel": "More information",
13
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#recommended-special-fields"
14
+ }
15
+ ]
16
+ },
17
+ "copyright": {
18
+ "type": "string",
19
+ "title": "Copyright",
20
+ "description": "Copyright which displays below the indicator chart.",
21
+ "links": [
22
+ {
23
+ "rel": "More information",
24
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#footer"
25
+ }
26
+ ]
27
+ },
28
+ "data_footnote": {
29
+ "type": "string",
30
+ "format": "markdown",
31
+ "title": "Footnote",
32
+ "description": "Footnote which displays below the indicator chart.",
33
+ "links": [
34
+ {
35
+ "rel": "More information",
36
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#footer"
37
+ }
38
+ ]
39
+ },
40
+ "data_non_statistical": {
41
+ "title": "Non-statistical data",
42
+ "type": "boolean",
43
+ "description": "Whether the indicator is statistical (can be charted/graphed) or not.",
44
+ "format": "checkbox",
45
+ "links": [
46
+ {
47
+ "rel": "More information",
48
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#mandatory-fields"
49
+ }
50
+ ]
51
+ },
52
+ "data_notice_class": {
53
+ "title": "Data notice - class",
54
+ "type": "string",
55
+ "description": "A CSS class to apply to the data notice for this indicator.",
56
+ "links": [
57
+ {
58
+ "rel": "More information",
59
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#data-notice"
60
+ }
61
+ ]
62
+ },
63
+ "data_notice_heading": {
64
+ "title": "Data notice - heading",
65
+ "type": "string",
66
+ "description": "A title to display above the data notice for this indicator.",
67
+ "links": [
68
+ {
69
+ "rel": "More information",
70
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#data-notice"
71
+ }
72
+ ]
73
+ },
74
+ "data_notice_text": {
75
+ "title": "Data notice - text",
76
+ "type": "string",
77
+ "format": "markdown",
78
+ "description": "Text to display as a data notice for this indicator, intended to contain very important information which site viewers must keep in mind when using the data provided.",
79
+ "links": [
80
+ {
81
+ "rel": "More information",
82
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#data-notice"
83
+ }
84
+ ]
85
+ },
86
+ "data_show_map": {
87
+ "title": "Show map",
88
+ "type": "boolean",
89
+ "description": "Whether the indicator should display a Map tab.",
90
+ "format": "checkbox",
91
+ "links": [
92
+ {
93
+ "rel": "More information",
94
+ "href": "https://open-sdg.readthedocs.io/en/latest/maps/#metadata-field-data_show_map"
95
+ }
96
+ ]
97
+ },
98
+ "data_start_values": {
99
+ "options": {"collapsed": true},
100
+ "format": "table",
101
+ "type": "array",
102
+ "title": "Starting values",
103
+ "description": "Disaggregation values for a an indicator to start with already selected",
104
+ "items": {
105
+ "type": "object",
106
+ "title": "Starting value",
107
+ "properties": {
108
+ "field": {
109
+ "type": "string",
110
+ "minLength": 1,
111
+ "title": "Field",
112
+ "description": "The field (column) name."
113
+ },
114
+ "value": {
115
+ "type": "string",
116
+ "minLength": 1,
117
+ "title": "Value",
118
+ "description": "The value in that field to pre-select."
119
+ }
120
+ }
121
+ },
122
+ "links": [
123
+ {
124
+ "rel": "More information",
125
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#starting-values"
126
+ }
127
+ ]
128
+ },
129
+ "embedded_feature_footer": {
130
+ "type": "string",
131
+ "format": "markdown",
132
+ "title": "Embedded feature - Footer",
133
+ "description": "A footer that displays below the embedded feature. Only used with either embedded_feature_url or embedded_feature_html.",
134
+ "links": [
135
+ {
136
+ "rel": "More information",
137
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#embedded-feature-metadata"
138
+ }
139
+ ]
140
+ },
141
+ "embedded_feature_html": {
142
+ "type": "string",
143
+ "format": "textarea",
144
+ "title": "Embedded feature - HTML",
145
+ "description": "Any HTML to display in another tab, after Chart/Table/etc.",
146
+ "links": [
147
+ {
148
+ "rel": "More information",
149
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#embedded-feature-metadata"
150
+ }
151
+ ]
152
+ },
153
+ "embedded_feature_tab_title": {
154
+ "type": "string",
155
+ "title": "Embedded feature - Tab Title",
156
+ "description": "A title for the embedded feature tab (ie, Chart/Table/[this]). Only used with either embedded_feature_url or embedded_feature_html.",
157
+ "links": [
158
+ {
159
+ "rel": "More information",
160
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#embedded-feature-metadata"
161
+ }
162
+ ]
163
+ },
164
+ "embedded_feature_title": {
165
+ "type": "string",
166
+ "title": "Embedded feature - Title",
167
+ "description": "A title that displays above the embedded feature. Only used with either embedded_feature_url or embedded_feature_html.",
168
+ "links": [
169
+ {
170
+ "rel": "More information",
171
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#embedded-feature-metadata"
172
+ }
173
+ ]
174
+ },
175
+ "embedded_feature_url": {
176
+ "type": "string",
177
+ "format": "url",
178
+ "title": "Embedded feature - URL",
179
+ "description": "Any URL to display as an iframe in another tab, after Chart/Table/etc.",
180
+ "links": [
181
+ {
182
+ "rel": "More information",
183
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#embedded-feature-metadata"
184
+ }
185
+ ]
186
+ },
187
+ "graph_annotations": {
188
+ "options": {"collapsed": true},
189
+ "type": "array",
190
+ "title": "Graph annotations",
191
+ "description": "This can be used to add line annotations to the graph, such as target lines to show the progress towards the 2030 goal for an indicator.",
192
+ "items": {
193
+ "type": "object",
194
+ "title": "Graph annotation",
195
+ "properties": {
196
+ "preset": {
197
+ "type": "string",
198
+ "format": "choices",
199
+ "title": "Preset",
200
+ "enum": ["target_line"],
201
+ "description": "A preset bundle of configurations."
202
+ },
203
+ "value": {
204
+ "type": "number",
205
+ "minimum": 0,
206
+ "title": "Value",
207
+ "description": "The value at which to draw the line. For horizontal lines, this number corresponds to your actual data. For vertical lines, this number should be between 0 (the left side of the chart) and the number of years minus 1 (the right side of the chart)."
208
+ },
209
+ "endValue": {
210
+ "type": "number",
211
+ "title": "End value",
212
+ "description": "Optionally add a different ending value for the line."
213
+ },
214
+ "description": {
215
+ "type": "string",
216
+ "title": "Description",
217
+ "description": "A description of the annotation to be read by screenreaders."
218
+ },
219
+ "unit": {
220
+ "type": "string",
221
+ "title": "Unit",
222
+ "description": "The unit of measurement the annotation displays on."
223
+ },
224
+ "series": {
225
+ "type": "string",
226
+ "title": "Series",
227
+ "description": "The series the annotation displays on."
228
+ },
229
+ "mode": {
230
+ "type": "string",
231
+ "title": "Mode",
232
+ "description": "Whether the line will be vertical or horizontal.",
233
+ "enum": ["horizontal", "vertical"]
234
+ },
235
+ "borderColor": {
236
+ "type": "string",
237
+ "format": "color",
238
+ "title": "Line color",
239
+ "description": "The color of the line.",
240
+ "links": [
241
+ {
242
+ "rel": "More information",
243
+ "href": "https://github.com/chartjs/chartjs-plugin-annotation/blob/master/README.md"
244
+ }
245
+ ]
246
+ },
247
+ "borderDash": {
248
+ "type": "string",
249
+ "title": "Line dash type",
250
+ "description": "The type of line dash.",
251
+ "links": [
252
+ {
253
+ "rel": "More information",
254
+ "href": "https://github.com/chartjs/chartjs-plugin-annotation/blob/master/README.md"
255
+ }
256
+ ]
257
+ },
258
+ "label": {
259
+ "type": "object",
260
+ "title": "Label",
261
+ "description": "A text label for the annotation.",
262
+ "properties": {
263
+ "position": {
264
+ "type": "string",
265
+ "title": "Position",
266
+ "description": "Placement of the label along the line.",
267
+ "enum": [
268
+ "top",
269
+ "bottom",
270
+ "left",
271
+ "right",
272
+ "center"
273
+ ]
274
+ },
275
+ "content": {
276
+ "type": "string",
277
+ "minLength": 1,
278
+ "title": "Content",
279
+ "description": "Text of the line label."
280
+ },
281
+ "fontColor": {
282
+ "type": "string",
283
+ "format": "color",
284
+ "title": "Label color",
285
+ "description": "Color for the label text."
286
+ },
287
+ "backgroundColor": {
288
+ "type": "string",
289
+ "format": "color",
290
+ "default": "#FFFFFFF",
291
+ "title": "Background color",
292
+ "description": "Background color for the label text."
293
+ }
294
+ }
295
+ },
296
+ "highContrast": {
297
+ "type": "object",
298
+ "title": "High contrast options",
299
+ "description": "High-contrast overrides of certain color.",
300
+ "properties": {
301
+ "borderColor": {
302
+ "type": "string",
303
+ "format": "color",
304
+ "default": "#FFFFFF",
305
+ "title": "High-contrast line color",
306
+ "description": "The color of the line in high-contrast mode."
307
+ },
308
+ "label": {
309
+ "type": "object",
310
+ "title": "High contrast label",
311
+ "description": "High-contrast version of the label.",
312
+ "properties": {
313
+ "fontColor": {
314
+ "type": "string",
315
+ "format": "color",
316
+ "default": "#FFFFFF",
317
+ "title": "High-contrast label color",
318
+ "description": "Color for the label text in high-contrast mode."
319
+ },
320
+ "backgroundColor": {
321
+ "type": "string",
322
+ "format": "color",
323
+ "default": "#000000",
324
+ "title": "High-contrast background color",
325
+ "description": "Background color for the label text in high-contrast mode."
326
+ }
327
+ }
328
+ }
329
+ }
330
+ }
331
+ }
332
+ },
333
+ "links": [
334
+ {
335
+ "rel": "More information",
336
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#graph-metadata"
337
+ }
338
+ ]
339
+ },
340
+ "graph_limits": {
341
+ "options": {"collapsed": true},
342
+ "format": "table",
343
+ "type": "array",
344
+ "title": "Graph limits",
345
+ "description": "A list of min/max limits controlling the lowest/highest values to be shown on the y-axis.",
346
+ "items": {
347
+ "type": "object",
348
+ "title": "Graph limit",
349
+ "properties": {
350
+ "minimum": {
351
+ "type": "number",
352
+ "minimum": 0,
353
+ "title": "Minimum",
354
+ "description": "Minimum value for the y axis."
355
+ },
356
+ "maximum": {
357
+ "type": "number",
358
+ "minimum": 0,
359
+ "title": "Maximum",
360
+ "description": "Maximum value for the y axis."
361
+ },
362
+ "unit": {
363
+ "type": "string",
364
+ "title": "Unit",
365
+ "description": "The unit of measurement the limits apply to."
366
+ },
367
+ "series": {
368
+ "type": "string",
369
+ "title": "Series",
370
+ "description": "The series the limits apply to."
371
+ }
372
+ }
373
+ },
374
+ "links": [
375
+ {
376
+ "rel": "More information",
377
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#graph-metadata"
378
+ }
379
+ ]
380
+ },
381
+ "graph_stacked_disaggregation": {
382
+ "type": "string",
383
+ "title": "Stacked disaggregation",
384
+ "description": "This can be used with the bar graph type to place a certain disaggregation into the same stacked bars.",
385
+ "links": [
386
+ {
387
+ "rel": "More information",
388
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#recommended-special-fields"
389
+ }
390
+ ]
391
+ },
392
+ "graph_title": {
393
+ "type": "string",
394
+ "title": "Graph title",
395
+ "description": "The title that displays above the graph/chart.",
396
+ "links": [
397
+ {
398
+ "rel": "More information",
399
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#mandatory-for-statistical-indicators"
400
+ }
401
+ ]
402
+ },
403
+ "graph_titles": {
404
+ "options": {"collapsed": true},
405
+ "format": "table",
406
+ "type": "array",
407
+ "title": "Graph titles",
408
+ "description": "As an alternative to `graph_title`, this can be used to set specific titles for particular units and/or series.",
409
+ "items": {
410
+ "type": "object",
411
+ "title": "Graph title",
412
+ "properties": {
413
+ "title": {
414
+ "type": "string",
415
+ "minLength": 1,
416
+ "title": "Title",
417
+ "description": "The graph title."
418
+ },
419
+ "unit": {
420
+ "type": "string",
421
+ "title": "Unit",
422
+ "description": "The unit of measurement the title applies to."
423
+ },
424
+ "series": {
425
+ "type": "string",
426
+ "title": "Series",
427
+ "description": "The series the title applies to."
428
+ }
429
+ }
430
+ }
431
+ },
432
+ "graph_type": {
433
+ "type": "string",
434
+ "format": "choices",
435
+ "title": "Graph type",
436
+ "description": "What type of graph to use for the indicator.",
437
+ "enum": ["line", "bar", "binary"],
438
+ "links": [
439
+ {
440
+ "rel": "More information",
441
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#mandatory-for-statistical-indicators"
442
+ }
443
+ ]
444
+ },
445
+ "indicator_name": {
446
+ "type": "string",
447
+ "title": "Indicator name",
448
+ "description": "The name for the indicator, which displays at the top of the indicator page.",
449
+ "links": [
450
+ {
451
+ "rel": "More information",
452
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#mandatory-fields"
453
+ }
454
+ ]
455
+ },
456
+ "indicator_number": {
457
+ "type": "string",
458
+ "title": "Indicator number",
459
+ "description": "The number (or 'id') for the indicator.",
460
+ "links": [
461
+ {
462
+ "rel": "More information",
463
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#mandatory-fields"
464
+ }
465
+ ]
466
+ },
467
+ "national_geographical_coverage": {
468
+ "type": "string",
469
+ "title": "National geographical coverage",
470
+ "description": "A label used in the absence of any disaggregation.",
471
+ "links": [
472
+ {
473
+ "rel": "More information",
474
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#mandatory-for-statistical-indicators"
475
+ }
476
+ ]
477
+ },
478
+ "page_content": {
479
+ "type": "string",
480
+ "format": "markdown",
481
+ "title": "Page content",
482
+ "description": "Content which displays in the main content area of the indicator page."
483
+ },
484
+ "reporting_status": {
485
+ "type": "string",
486
+ "format": "choices",
487
+ "title": "Reporting status",
488
+ "enum": ["complete", "inprogress", "notstarted", "notapplicable"],
489
+ "description": "The status of the indicator.",
490
+ "links": [
491
+ {
492
+ "rel": "More information",
493
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#mandatory-fields"
494
+ }
495
+ ]
496
+ },
497
+ "tags": {
498
+ "options": {"collapsed": true},
499
+ "format": "table",
500
+ "type": "array",
501
+ "title": "Tags",
502
+ "description": "An optional list of 'tags' to display under an indicator when it is listed on its goal page.",
503
+ "items": {
504
+ "type": "string",
505
+ "title": "Tag"
506
+ },
507
+ "links": [
508
+ {
509
+ "rel": "More information",
510
+ "href": "https://open-sdg.readthedocs.io/en/latest/metadata-format/#recommended-special-fields"
511
+ }
512
+ ]
513
+ }
514
+ },
515
+ "additionalProperties": true
516
+ }