Skip to content

Instantly share code, notes, and snippets.

@larsyencken
Created July 22, 2021 09:54
Show Gist options
  • Save larsyencken/9f157a3db5a4d5dcd26262d5e72a51c5 to your computer and use it in GitHub Desktop.
Save larsyencken/9f157a3db5a4d5dcd26262d5e72a51c5 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "66268232-f626-49ae-9bac-f3ddd2037d27",
"metadata": {},
"source": [
"# JSON schema for Grapher"
]
},
{
"cell_type": "markdown",
"id": "77537130-2a80-46a3-b4bb-61fb5126c7c7",
"metadata": {},
"source": [
"How can we improve the JSON schema for Grapher?"
]
},
{
"cell_type": "markdown",
"id": "6090587b-36d9-47ad-a0a9-41f3db03d484",
"metadata": {},
"source": [
"## Load all configs"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "95e3be95-659d-45fb-bbb4-2d416faccc6d",
"metadata": {},
"outputs": [],
"source": [
"import json"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "427415b3-b3f3-404c-a615-38d8783a07f3",
"metadata": {},
"outputs": [],
"source": [
"%%mysql\n",
"\n",
"select config from charts"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "c93f17a6-9df5-4907-b331-6281bf8baddc",
"metadata": {},
"outputs": [],
"source": [
"configs = list(df.config.apply(json.loads))"
]
},
{
"cell_type": "markdown",
"id": "68614f6f-61c6-4bba-b98e-9eabf1204e95",
"metadata": {},
"source": [
"## Find the code"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "38f98bf0-65bc-4815-bbb9-9708b03f9fb1",
"metadata": {},
"outputs": [],
"source": [
"from sh import grep"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "b94dbebd-7a07-45c7-a942-1fe188d24277",
"metadata": {},
"outputs": [],
"source": [
"CODE_DIR = '../owid-grapher'"
]
},
{
"cell_type": "code",
"execution_count": 61,
"id": "5b9b4b7f-8a45-4c4c-8253-4fb80bd92578",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"../owid-grapher/grapher/core/Grapher.tsx: @observable hideConnectedScatterLines?: boolean = undefined // Hides lines between points when timeline spans multiple years. Requested by core-econ for certain charts\n",
"../owid-grapher/grapher/core/GrapherInterface.ts: hideConnectedScatterLines?: boolean // Hides lines between points when timeline spans multiple years. Requested by core-econ for certain charts\n",
"../owid-grapher/grapher/core/GrapherInterface.ts: \"hideConnectedScatterLines\",\n",
"../owid-grapher/grapher/scatterCharts/ScatterUtils.ts: hideConnectedScatterLines: boolean\n",
"../owid-grapher/grapher/scatterCharts/ScatterUtils.ts: const fontSize = hideConnectedScatterLines\n",
"../owid-grapher/grapher/scatterCharts/ScatterUtils.ts: hideConnectedScatterLines: boolean\n",
"../owid-grapher/grapher/scatterCharts/ScatterUtils.ts: const fontSize = hideConnectedScatterLines\n",
"../owid-grapher/grapher/scatterCharts/ScatterUtils.ts: hideConnectedScatterLines: boolean\n",
"../owid-grapher/grapher/scatterCharts/ScatterUtils.ts: const fontSize = hideConnectedScatterLines\n",
"../owid-grapher/grapher/scatterCharts/ScatterUtils.ts: series.isForeground && !hideConnectedScatterLines ? 700 : 400\n",
"../owid-grapher/grapher/scatterCharts/ScatterUtils.ts: hideConnectedScatterLines && series.isForeground\n",
"../owid-grapher/grapher/scatterCharts/ScatterPlotChartConstants.ts: hideConnectedScatterLines?: boolean\n",
"../owid-grapher/grapher/scatterCharts/ScatterPlotChartConstants.ts: hideConnectedScatterLines: boolean\n",
"../owid-grapher/grapher/scatterCharts/ScatterPlotChart.tsx: @computed private get hideConnectedScatterLines(): boolean {\n",
"../owid-grapher/grapher/scatterCharts/ScatterPlotChart.tsx: return !!this.manager.hideConnectedScatterLines\n",
"../owid-grapher/grapher/scatterCharts/ScatterPlotChart.tsx: hideConnectedScatterLines,\n",
"../owid-grapher/grapher/scatterCharts/ScatterPlotChart.tsx: hideConnectedScatterLines={hideConnectedScatterLines}\n",
"../owid-grapher/grapher/scatterCharts/ScatterPointsWithLabels.tsx: @computed private get hideConnectedScatterLines(): boolean {\n",
"../owid-grapher/grapher/scatterCharts/ScatterPointsWithLabels.tsx: return this.props.hideConnectedScatterLines\n",
"../owid-grapher/grapher/scatterCharts/ScatterPointsWithLabels.tsx: this.hideConnectedScatterLines\n",
"../owid-grapher/grapher/scatterCharts/ScatterPointsWithLabels.tsx: this.hideConnectedScatterLines\n",
"../owid-grapher/grapher/scatterCharts/ScatterPointsWithLabels.tsx: this.hideConnectedScatterLines\n",
"../owid-grapher/grapher/scatterCharts/ScatterPointsWithLabels.tsx: hideConnectedScatterLines,\n",
"../owid-grapher/grapher/scatterCharts/ScatterPointsWithLabels.tsx: return hideConnectedScatterLines\n",
"../owid-grapher/grapher/scatterCharts/ScatterPointsWithLabels.tsx: const { isSubtleForeground, hideConnectedScatterLines } = this\n",
"../owid-grapher/grapher/scatterCharts/ScatterPointsWithLabels.tsx: (hideConnectedScatterLines\n",
"../owid-grapher/grapher/scatterCharts/ScatterPointsWithLabels.tsx: const radius = hideConnectedScatterLines\n",
"../owid-grapher/grapher/scatterCharts/ScatterPointsWithLabels.tsx: {!hideConnectedScatterLines && (\n",
"../owid-grapher/grapher/scatterCharts/ScatterPointsWithLabels.tsx: {(series.isFocus || hideConnectedScatterLines) &&\n",
"../owid-grapher/grapher/scatterCharts/ScatterPointsWithLabels.tsx: {(series.isHover || hideConnectedScatterLines) &&\n",
"../owid-grapher/grapher/scatterCharts/ScatterPointsWithLabels.tsx: hideConnectedScatterLines ? undefined : -1\n",
"../owid-grapher/grapher/scatterCharts/ScatterPointsWithLabels.tsx: {!hideConnectedScatterLines && ("
]
},
"execution_count": 61,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# test grep\n",
"sh.grep('-r', '--exclude=schema.json', 'hideConnectedScatterLines', f'{CODE_DIR}/grapher', _ok_code=[0, 1])"
]
},
{
"cell_type": "code",
"execution_count": 63,
"id": "d8ac3e57-adf7-4dbc-8654-0ba6821701bd",
"metadata": {},
"outputs": [],
"source": [
"def found_in_code(field_name):\n",
" return sh.grep('-r', '--exclude=schema.json', field_name, f'{CODE_DIR}/grapher', _ok_code=[0, 1]).exit_code == 0"
]
},
{
"cell_type": "markdown",
"id": "95aab9ac-d6fc-4b8e-8358-b76ef96f79b9",
"metadata": {},
"source": [
"## Find the schema"
]
},
{
"cell_type": "code",
"execution_count": 64,
"id": "254a00aa-1ab6-452b-bd57-4736e9a5b85c",
"metadata": {},
"outputs": [],
"source": [
"import jsonschema"
]
},
{
"cell_type": "code",
"execution_count": 127,
"id": "ae81d971-efa2-4f80-b7b7-59f1a8a9a738",
"metadata": {},
"outputs": [],
"source": [
"SCHEMA_FILE = f'{CODE_DIR}/grapher/core/schema.json'"
]
},
{
"cell_type": "code",
"execution_count": 128,
"id": "d384461e-0923-41e4-9f25-d8b684475ced",
"metadata": {},
"outputs": [],
"source": [
"schema = json.load(open(SCHEMA_FILE))"
]
},
{
"cell_type": "code",
"execution_count": 129,
"id": "14541976-1cc5-4c10-a346-1422bb9f4bf9",
"metadata": {},
"outputs": [],
"source": [
"jsonschema.Draft6Validator.check_schema(schema)"
]
},
{
"cell_type": "markdown",
"id": "60a59319-f9a6-444d-8595-960ef699dcf6",
"metadata": {},
"source": [
"## Improve it"
]
},
{
"cell_type": "markdown",
"id": "f58bec00-2b56-4ba6-a970-aa3c4eff8154",
"metadata": {},
"source": [
"### ① Find fields that are never used"
]
},
{
"cell_type": "code",
"execution_count": 130,
"id": "81bbd590-69ec-4655-8827-d04df4580b14",
"metadata": {},
"outputs": [],
"source": [
"def iter_fields(s, path=''):\n",
" if isinstance(s, dict) and any(k in s for k in ['oneOf', 'anyOf', 'allOf']):\n",
" for v in s.values():\n",
" yield from iter_fields(v, path)\n",
" \n",
" if 'type' in s and s['type'] == 'object' and 'properties' in s:\n",
" to_visit = list(s['properties'].items())\n",
" while to_visit:\n",
" field_name, field_schema = to_visit.pop()\n",
"\n",
" if field_name in ['oneOf', 'anyOf', 'allOf']:\n",
" to_visit.extend(field_schema)\n",
" continue\n",
"\n",
" field_path = f'{path}/{field_name}'\n",
" yield field_name, field_schema, field_path\n",
" \n",
" yield from iter_fields(field_schema, field_path)\n",
" \n",
"def mark_unused(s):\n",
" for field_name, field_schema, path in sorted(iter_fields(s), key=lambda d: d[2]):\n",
" if not found_in_code(field_name):\n",
" print(f'Never used: {path}')\n",
" field_schema['description'] = 'DELETE: never used in code'"
]
},
{
"cell_type": "code",
"execution_count": 131,
"id": "f899595f-d6b9-4c35-9a33-e16c7c8aceb2",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Never used: /isAutoTitle\n",
"Never used: /isExplorable\n",
"Never used: /lastEditedAt\n",
"Never used: /map/colorSchemeName\n",
"Never used: /map/defaultProjection\n",
"Never used: /map/defaultYear\n",
"Never used: /map/isColorblind\n",
"Never used: /map/legendOrientation\n",
"Never used: /map/legendStepSize\n",
"Never used: /map/maxYear\n",
"Never used: /map/minYear\n",
"Never used: /map/targetYearMode\n",
"Never used: /map/timeInterval\n",
"Never used: /map/timeRanges\n",
"Never used: /map/timelineMode\n",
"Never used: /margins\n",
"Never used: /xAxis/labelDistance\n",
"Never used: /yAxis/labelDistance\n"
]
}
],
"source": [
"mark_unused(schema)"
]
},
{
"cell_type": "markdown",
"id": "5c8580b3-4d75-403f-8254-539e4db34b33",
"metadata": {},
"source": [
"18 fields never used 😅"
]
},
{
"cell_type": "markdown",
"id": "4097003c-3e8c-457b-aaa1-ecc02c5c2485",
"metadata": {},
"source": [
"## ② Deprecate what hasn't been used in 1y"
]
},
{
"cell_type": "code",
"execution_count": 132,
"id": "946e630c-2101-4dd0-b362-12d425fe6714",
"metadata": {},
"outputs": [],
"source": [
"%%mysql\n",
"\n",
"select config\n",
"from charts\n",
"where lastEditedAt > NOW() - INTERVAL 1 YEAR"
]
},
{
"cell_type": "code",
"execution_count": 133,
"id": "4b78993f-40b9-4cb0-9764-b2cb5ea27c20",
"metadata": {},
"outputs": [],
"source": [
"recent_configs = [json.loads(c) for c in df.config]"
]
},
{
"cell_type": "code",
"execution_count": 134,
"id": "c95e1c39-521c-4158-ae80-bf58993df331",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1433"
]
},
"execution_count": 134,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"len(recent_configs)"
]
},
{
"cell_type": "code",
"execution_count": 135,
"id": "d495a619-93df-424d-9447-fa0622d852c6",
"metadata": {},
"outputs": [],
"source": [
"def is_used_recently(path):\n",
" for config in recent_configs:\n",
" cursor = config\n",
" for part in path:\n",
" if not cursor or not isinstance(cursor, dict) or part not in cursor:\n",
" break\n",
" \n",
" cursor = cursor[part]\n",
" else:\n",
" return True\n",
" \n",
" return False"
]
},
{
"cell_type": "code",
"execution_count": 136,
"id": "36b9d376-db54-42e9-a61a-287ed33f6d37",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 136,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"is_used_recently(['id'])"
]
},
{
"cell_type": "code",
"execution_count": 137,
"id": "8d4dfaa3-fc75-4dc7-a22c-14d56ac00308",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 137,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"is_used_recently(['yAxis', 'scaleType'])"
]
},
{
"cell_type": "code",
"execution_count": 138,
"id": "62387465-1af0-4be4-b5f1-fa5df8d9d8dc",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 138,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"is_used_recently(['yAxis', 'dog'])"
]
},
{
"cell_type": "code",
"execution_count": 139,
"id": "6cfffd19-f414-4856-afc0-3d6ab3b9992a",
"metadata": {},
"outputs": [],
"source": [
"def mark_not_used_recently(schema):\n",
" for field_name, field_schema, path in sorted(iter_fields(schema), key=lambda v: v[2]):\n",
" if not is_used_recently(path.lstrip('/').split(\"/\")):\n",
" if 'DELETE' not in field_schema.get('description', ''):\n",
" field_schema['description'] = 'DEPRECATE: this field has not been used in 1y or more'\n",
" print('Not used recently:', path)"
]
},
{
"cell_type": "code",
"execution_count": 140,
"id": "ac2bb046-57ff-4660-a8fc-14f3d449dd70",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Not used recently: /map/mode\n",
"Not used recently: /margins/bottom\n",
"Not used recently: /margins/left\n",
"Not used recently: /margins/right\n",
"Not used recently: /margins/top\n",
"Not used recently: /xAxis/numDecimalPlaces\n",
"Not used recently: /yAxis/facetAxisRange\n",
"Not used recently: /yAxis/numDecimalPlaces\n"
]
}
],
"source": [
"mark_not_used_recently(schema)"
]
},
{
"cell_type": "code",
"execution_count": 141,
"id": "cac4fbf6-43fd-4632-bdf0-70ea53ceb416",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'$schema': 'http://json-schema.org/draft-07/schema#',\n",
" 'required': ['title', 'version', 'dimensions'],\n",
" 'type': 'object',\n",
" 'properties': {'id': {'type': 'integer', 'minimum': 0},\n",
" 'map': {'type': 'object',\n",
" 'properties': {'legendOrientation': {'type': ['string', 'null'],\n",
" 'enum': ['portrait', 'landscape', None],\n",
" 'description': 'DELETE: never used in code'},\n",
" 'projection': {'type': ['string', 'null'],\n",
" 'enum': ['World',\n",
" 'Europe',\n",
" 'Africa',\n",
" 'Asia',\n",
" 'NortAmerica',\n",
" 'SouthAmerica',\n",
" 'Oceania',\n",
" None]},\n",
" 'isColorblind': {'type': 'boolean',\n",
" 'description': 'DELETE: never used in code'},\n",
" 'defaultProjection': {'type': 'string',\n",
" 'enum': ['World',\n",
" 'Europe',\n",
" 'Africa',\n",
" 'Asia',\n",
" 'NortAmerica',\n",
" 'SouthAmerica',\n",
" 'Oceania'],\n",
" 'description': 'DELETE: never used in code'},\n",
" 'timelineMode': {'type': ['string', 'null'],\n",
" 'enum': ['slider', 'timeline', 'buttons', None],\n",
" 'description': 'DELETE: never used in code'},\n",
" 'minYear': {'type': ['integer'],\n",
" 'description': 'DELETE: never used in code'},\n",
" 'timeRanges': {'type': 'array',\n",
" 'items': {'type': 'object',\n",
" 'properties': {'endYear': {'oneOf': [{'type': 'string',\n",
" 'enum': ['last']},\n",
" {'type': 'number', 'minimum': 0}]},\n",
" 'interval': {'type': 'integer', 'maximum': 32767, 'minimum': 0},\n",
" 'startYear': {'oneOf': [{'type': 'string', 'enum': ['first']},\n",
" {'type': 'number'}]},\n",
" 'year': {'oneOf': [{'type': 'string', 'enum': ['last']},\n",
" {'type': 'number', 'minimum': 0}]}},\n",
" 'additionalProperties': False},\n",
" 'description': 'DELETE: never used in code'},\n",
" 'legendStepSize': {'type': 'integer',\n",
" 'maximum': 32767,\n",
" 'minimum': 0,\n",
" 'description': 'DELETE: never used in code'},\n",
" 'hideTimeline': {'type': 'boolean'},\n",
" 'colorScale': {'type': 'object',\n",
" 'properties': {'customNumericLabels': {'type': 'array',\n",
" 'items': {'type': ['string', 'null']}},\n",
" 'customCategoryColors': {'type': ['object', 'array'],\n",
" 'patternProperties': {'.*': {'type': 'string'}},\n",
" 'items': {}},\n",
" 'baseColorScheme': {'type': 'string'},\n",
" 'equalSizeBins': {'type': 'boolean'},\n",
" 'customHiddenCategories': {'type': ['object', 'array'],\n",
" 'patternProperties': {'.*': {'type': 'boolean'}},\n",
" 'items': {}},\n",
" 'binningStrategy': {'type': 'string',\n",
" 'enum': ['equalInterval', 'quantiles', 'ckmeans', 'manual']},\n",
" 'legendDescription': {'type': 'string'},\n",
" 'customNumericColors': {'type': 'array',\n",
" 'items': {'type': ['string', 'null']}},\n",
" 'binningStrategyBinCount': {'type': 'integer', 'minimum': 0},\n",
" 'customNumericValues': {'type': 'array', 'items': {'type': 'number'}},\n",
" 'customNumericColorsActive': {'type': 'boolean'},\n",
" 'colorSchemeInvert': {'type': 'boolean'},\n",
" 'customNumericMinValue': {'type': 'number'},\n",
" 'customCategoryLabels': {'type': ['object', 'array'],\n",
" 'patternProperties': {'.*': {'type': 'string'}},\n",
" 'items': {}}},\n",
" 'additionalProperties': False},\n",
" 'timeTolerance': {'type': 'integer', 'minimum': 0},\n",
" 'targetYear': {'oneOf': [{'type': 'string', 'enum': ['latest']},\n",
" {'type': 'number', 'minimum': 0}]},\n",
" 'maxYear': {'oneOf': [{'type': 'string', 'enum': ['latest']},\n",
" {'type': 'number', 'minimum': 0}],\n",
" 'description': 'DELETE: never used in code'},\n",
" 'colorSchemeName': {'type': 'string',\n",
" 'description': 'DELETE: never used in code'},\n",
" 'tooltipUseCustomLabels': {'type': 'boolean'},\n",
" 'targetYearMode': {'type': 'string',\n",
" 'description': 'DELETE: never used in code'},\n",
" 'mode': {'type': 'string',\n",
" 'enum': ['specific'],\n",
" 'description': 'DEPRECATE: this field has not been used in 1y or more'},\n",
" 'time': {'type': ['string', 'integer'],\n",
" 'description': 'Select a specific time to be displayed.',\n",
" 'maximum': 32767,\n",
" 'minimum': 0},\n",
" 'defaultYear': {'oneOf': [{'type': 'string', 'enum': ['latest']},\n",
" {'type': 'number', 'minimum': 0}],\n",
" 'description': 'DELETE: never used in code'},\n",
" 'variableId': {'type': 'integer', 'maximum': 2147483647, 'minimum': 0},\n",
" 'timeInterval': {'type': 'integer',\n",
" '$comment': 'TODO: This property is used only if 13 very old charts',\n",
" 'description': 'DELETE: never used in code'}},\n",
" 'additionalProperties': False},\n",
" 'maxTime': {'oneOf': [{'type': 'string', 'enum': ['latest']},\n",
" {'type': 'number', 'minimum': 0}]},\n",
" 'subtitle': {'type': 'string'},\n",
" 'selectedEntityNames': {'type': 'array',\n",
" 'items': {'type': ['string', 'null']}},\n",
" 'baseColorScheme': {'type': 'string'},\n",
" 'yAxis': {'type': 'object',\n",
" 'properties': {'removePointsOutsideDomain': {'type': 'boolean'},\n",
" 'prefix': {'type': 'string'},\n",
" 'label': {'type': 'string'},\n",
" 'suffix': {'type': 'string'},\n",
" 'min': {'type': 'number'},\n",
" 'scaleType': {'type': 'string', 'enum': ['linear', 'log']},\n",
" 'max': {'type': 'number', 'minimum': 0},\n",
" 'canChangeScaleType': {'type': 'boolean'},\n",
" 'labelDistance': {'type': 'number',\n",
" 'description': 'DELETE: never used in code'},\n",
" 'facetAxisRange': {'type': 'string',\n",
" 'description': 'DEPRECATE: this field has not been used in 1y or more'},\n",
" 'numDecimalPlaces': {'type': 'integer',\n",
" 'minimum': 0,\n",
" 'description': 'DEPRECATE: this field has not been used in 1y or more'}},\n",
" 'additionalProperties': False},\n",
" 'tab': {'type': 'string',\n",
" 'enum': ['chart', 'map', 'sources', 'download', 'table']},\n",
" 'selectedData': {'type': 'array',\n",
" 'items': {'type': 'object',\n",
" 'properties': {'color': {'type': 'string'},\n",
" 'index': {'type': 'integer', 'minimum': 0},\n",
" 'entityId': {'type': 'integer', 'minimum': 0}},\n",
" 'additionalProperties': False}},\n",
" 'matchingEntitiesOnly': {'type': 'boolean'},\n",
" 'lastEditedAt': {'type': 'string',\n",
" 'format': 'date-time',\n",
" 'description': 'DELETE: never used in code'},\n",
" 'margins': {'type': 'object',\n",
" 'properties': {'top': {'type': ['string', 'integer'],\n",
" 'minimum': 0,\n",
" 'description': 'DEPRECATE: this field has not been used in 1y or more'},\n",
" 'left': {'type': ['string', 'integer'],\n",
" 'minimum': 0,\n",
" 'description': 'DEPRECATE: this field has not been used in 1y or more'},\n",
" 'right': {'type': ['string', 'integer'],\n",
" 'minimum': 0,\n",
" 'description': 'DEPRECATE: this field has not been used in 1y or more'},\n",
" 'bottom': {'type': ['string', 'integer'],\n",
" 'minimum': 0,\n",
" 'description': 'DEPRECATE: this field has not been used in 1y or more'}},\n",
" 'additionalProperties': False,\n",
" 'description': 'DELETE: never used in code'},\n",
" 'hasChartTab': {'type': 'boolean'},\n",
" 'data': {'type': 'object',\n",
" 'properties': {'availableEntities': {'type': 'array',\n",
" 'items': {'type': 'string'}}},\n",
" 'additionalProperties': False},\n",
" 'hideLegend': {'type': 'boolean'},\n",
" 'hideLogo': {'type': 'boolean'},\n",
" 'timelineMinTime': {'type': 'integer'},\n",
" 'variantName': {'type': 'string'},\n",
" 'hideTimeline': {'type': 'boolean'},\n",
" 'originUrl': {'type': ['string', 'null']},\n",
" 'colorScale': {'type': 'object',\n",
" 'properties': {'customNumericLabels': {'type': 'array',\n",
" 'items': {'type': ['string', 'null']}},\n",
" 'customCategoryColors': {'type': 'object',\n",
" 'patternProperties': {'.*': {'type': 'string'}}},\n",
" 'baseColorScheme': {'type': 'string'},\n",
" 'customHiddenCategories': {'type': 'object',\n",
" 'patternProperties': {'.*': {'type': 'boolean'}}},\n",
" 'binningStrategy': {'type': 'string',\n",
" 'enum': ['equalInterval', 'quantiles', 'ckmeans', 'manual']},\n",
" 'legendDescription': {'type': 'string'},\n",
" 'customNumericColors': {'type': 'array', 'items': {'type': 'string'}},\n",
" 'customNumericValues': {'type': 'array',\n",
" 'items': {'type': 'number', 'minimum': 0}},\n",
" 'customNumericColorsActive': {'type': 'boolean'},\n",
" 'colorSchemeInvert': {'type': 'boolean'},\n",
" 'customCategoryLabels': {'type': 'object',\n",
" 'properties': {'No data': {'type': 'string'}},\n",
" 'additionalProperties': False}},\n",
" 'additionalProperties': False},\n",
" 'scatterPointLabelStrategy': {'type': 'string', 'enum': ['x', 'y', 'year']},\n",
" 'sourceDesc': {'type': 'string'},\n",
" 'isPublished': {'type': ['boolean', 'null']},\n",
" 'invertColorScheme': {'type': 'boolean'},\n",
" 'hideRelativeToggle': {'type': 'boolean'},\n",
" 'comparisonLines': {'type': 'array',\n",
" 'items': {'type': 'object',\n",
" 'properties': {'label': {'type': 'string'}, 'yEquals': {'type': 'string'}},\n",
" 'additionalProperties': False}},\n",
" 'slug': {'type': 'string'},\n",
" 'internalNotes': {'type': 'string'},\n",
" 'version': {'type': 'integer', 'minimum': 0},\n",
" 'logo': {'type': 'string', 'enum': ['owid', 'core+owid', 'gv+owid']},\n",
" 'entityType': {'type': 'string'},\n",
" 'note': {'type': 'string'},\n",
" 'dimensions': {'type': 'array',\n",
" 'items': {'type': 'object',\n",
" 'properties': {'targetYear': {'type': ['integer', 'null'], 'minimum': 0},\n",
" 'id': {'type': 'integer', 'minimum': 0},\n",
" 'order': {'type': 'integer', 'minimum': 0},\n",
" 'chartId': {'type': 'integer', 'minimum': 0},\n",
" 'property': {'type': 'string'},\n",
" 'numDecimalPlaces': {'type': 'integer', 'minimum': 0},\n",
" 'display': {'type': 'object',\n",
" 'properties': {'isProjection': {'type': 'boolean'},\n",
" 'name': {'type': 'string'},\n",
" 'tableDisplay': {'type': 'object',\n",
" 'properties': {'hideAbsoluteChange': {'type': 'boolean'},\n",
" 'hideRelativeChange': {'type': 'boolean'}},\n",
" 'additionalProperties': False},\n",
" 'tolerance': {'type': 'integer', 'minimum': 0},\n",
" 'entityAnnotationsMap': {'type': 'string'},\n",
" 'yearIsDay': {'type': 'boolean'},\n",
" 'color': {'type': 'string'},\n",
" 'includeInTable': {'type': 'boolean'},\n",
" 'shortUnit': {'type': 'string'},\n",
" 'conversionFactor': {'type': 'number'},\n",
" 'unit': {'type': 'string'},\n",
" 'numDecimalPlaces': {'type': 'integer', 'minimum': 0},\n",
" 'zeroDay': {'type': 'string'}},\n",
" 'additionalProperties': False},\n",
" 'variableId': {'type': 'integer', 'minimum': 0}},\n",
" 'additionalProperties': False}},\n",
" 'selectedEntityIds': {'type': 'array',\n",
" 'items': {'type': 'integer', 'minimum': 0}},\n",
" 'addCountryMode': {'type': 'string',\n",
" 'enum': ['add-country', 'change-country', 'disabled']},\n",
" 'compareEndPointsOnly': {'type': 'boolean'},\n",
" 'selectedEntityColors': {'type': 'object',\n",
" 'patternProperties': {'.*': {'type': 'string'}}},\n",
" 'relatedQuestions': {'type': 'array',\n",
" 'items': {'type': 'object',\n",
" 'properties': {'url': {'type': 'string'}, 'text': {'type': 'string'}},\n",
" 'additionalProperties': False}},\n",
" 'title': {'type': 'string'},\n",
" 'isAutoTitle': {'type': 'boolean',\n",
" 'description': 'DELETE: never used in code'},\n",
" 'type': {'type': 'string',\n",
" 'enum': ['LineChart',\n",
" 'ScatterPlot',\n",
" 'TimeScatter',\n",
" 'StackedArea',\n",
" 'DiscreteBar',\n",
" 'StackedDiscreteBar',\n",
" 'SlopeChart',\n",
" 'StackedBar',\n",
" 'WorldMap',\n",
" 'Marimekko']},\n",
" 'hasMapTab': {'type': 'boolean'},\n",
" 'stackMode': {'type': ['string', 'null'],\n",
" 'enum': ['absolute', 'relative', 'grouped', 'stacked', None]},\n",
" 'minTime': {'oneOf': [{'type': 'string', 'enum': ['latest', 'earliest']},\n",
" {'type': 'number'}]},\n",
" 'hideTitleAnnotation': {'type': 'boolean'},\n",
" 'excludedEntities': {'type': 'array',\n",
" 'items': {'type': 'integer', 'minimum': 0}},\n",
" 'xAxis': {'type': 'object',\n",
" 'properties': {'removePointsOutsideDomain': {'type': 'boolean'},\n",
" 'prefix': {'type': 'string'},\n",
" 'label': {'type': 'string'},\n",
" 'suffix': {'type': 'string'},\n",
" 'min': {'type': 'number'},\n",
" 'scaleType': {'type': 'string', 'enum': ['linear', 'log']},\n",
" 'max': {'type': 'number', 'minimum': 0},\n",
" 'canChangeScaleType': {'type': 'boolean'},\n",
" 'labelDistance': {'type': 'integer',\n",
" 'maximum': 32767,\n",
" 'minimum': -327681,\n",
" 'description': 'DELETE: never used in code'},\n",
" 'numDecimalPlaces': {'type': 'integer',\n",
" 'minimum': 0,\n",
" 'description': 'DEPRECATE: this field has not been used in 1y or more'}},\n",
" 'additionalProperties': False},\n",
" 'timelineMaxTime': {'type': 'integer', 'minimum': 0},\n",
" 'isExplorable': {'type': 'boolean',\n",
" 'description': 'DELETE: never used in code'},\n",
" 'hideConnectedScatterLines': {'type': 'boolean'}},\n",
" 'additionalProperties': True}"
]
},
"execution_count": 141,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"schema"
]
},
{
"cell_type": "code",
"execution_count": 142,
"id": "cca22e59-c399-4f73-8288-616b75dc4a3f",
"metadata": {},
"outputs": [],
"source": [
"with open(SCHEMA_FILE, 'w') as istream:\n",
" json.dump(schema, istream, indent=4)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.4"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment