Open maneetgoyal opened 2 years ago
@maneetgoyal Hi, using TypeScript may provide a more accurate validation on the option.
Thanks for the reply @pissang. We are using TypeScript but we need run-time validation also as opposed to just compile-time validation. Say, while storing the option
JSON coming from the client/front-end into a database at our backend, we need to make sure that the client sent properly formatted option
.
We have a JSON schema for our doc page. https://github.com/apache/echarts-website/blob/asf-site/en/documents/option.json But I'm not sure if it's accurate enough for you. Perhaps you can have a try
Thanks again. If we run into any accuracy related issues, will bring it to the maintainers' notice. Feel free to close the issue AFAIC. 👍
@pissang Was taking a deeper look. The format of the JSON schema seems inconsistent with the specifications.
For example, the value of the first property $schema
seems incorrect.
If providing the JSON schema is too much of a hassle, is there any other way (utility function), which can validate the option
JSON during run time? Would be of great help.
Hello, we are also looking for a valid schema. It's an important feature request
@pissang Was taking a deeper look. The format of the JSON schema seems inconsistent with the specifications.
For example, the value of the first property
$schema
seems incorrect.If providing the JSON schema is too much of a hassle, is there any other way (utility function), which can validate the
option
JSON during run time? Would be of great help.
Greetings,
Just planning to build my own Python classes for generating echarts options, validations are also needed by me. And following content (WIP) is my first try to use Selenium to crawl all the properties. It's a little bit weird.
{
"title": {
"id": "",
"show": "true",
"text": "",
"link": "",
"target": "blank",
"textStyle:": {},
"subtext": "",
"sublink": "",
"subtarget": "blank",
"subtextStyle:": {},
"textAlign": "auto",
"textVerticalAlign": "auto",
"triggerEvent": "false",
"padding": "5",
"itemGap": "10",
"zlevel": "0",
"z": "2",
"left": "auto",
"top": "auto",
"right": "auto",
"bottom": "auto",
"backgroundColor": "transparent",
"borderColor": "#ccc",
"borderWidth": "0",
"borderRadius": "0",
"shadowBlur": "",
"shadowColor": "",
"shadowOffsetX": "0",
"shadowOffsetY": "0"
},
"legend": {
"type": "",
"id": "",
"show": "true",
"zlevel": "0",
"z": "2",
"left": "auto",
"top": "auto",
"right": "auto",
"bottom": "auto",
"width": "auto",
"height": "auto",
"orient": "horizontal",
"align": "auto",
"padding": "5",
"itemGap": "10",
"itemWidth": "25",
"itemHeight": "14",
"itemStyle:": {},
"lineStyle:": {},
"symbolRotate": "inherit",
"formatter": "",
"selectedMode": "true",
"inactiveColor": "#ccc",
"inactiveBorderColor": "#ccc",
"inactiveBorderWidth": "auto",
"selected": "",
"textStyle:": {},
"tooltip": "",
"icon": "",
"data:": [],
"backgroundColor": "transparent",
"borderColor": "#ccc",
"borderWidth": "1",
"borderRadius": "0",
"shadowBlur": "",
"shadowColor": "",
"shadowOffsetX": "0",
"shadowOffsetY": "0",
"scrollDataIndex": "0",
"pageButtonItemGap": "5",
"pageButtonGap": "",
"pageButtonPosition": "end",
"pageFormatter": "{current}/{total}",
"pageIcons:": {},
"pageIconColor": "#2f4554",
"pageIconInactiveColor": "#aaa",
"pageIconSize": "15",
"pageTextStyle:": {},
"animation": "",
"animationDurationUpdate": "800",
"emphasis:": {},
"selector": "false",
"selectorLabel:": {},
"selectorPosition": "auto",
"selectorItemGap": "7",
"selectorButtonGap": "10"
},
"grid": {
"id": "",
"show": "false",
"zlevel": "0",
"z": "2",
"left": "10%",
"top": "60",
"right": "10%",
"bottom": "60",
"width": "auto",
"height": "auto",
"containLabel": "false",
"backgroundColor": "transparent",
"borderColor": "#ccc",
"borderWidth": "1",
"shadowBlur": "",
"shadowColor": "",
"shadowOffsetX": "0",
"shadowOffsetY": "0",
"tooltip:": {}
},
"xAxis": {
"id": "",
"show": "true",
"gridIndex": "0",
"alignTicks": "false",
"position": "",
"offset": "0",
"type": "category",
"name": "",
"nameLocation": "end",
"nameTextStyle:": {},
"nameGap": "15",
"nameRotate": "",
"inverse": "false",
"boundaryGap": "",
"min": "",
"max": "",
"scale": "false",
"splitNumber": "5",
"minInterval": "0",
"maxInterval": "",
"interval": "",
"logBase": "10",
"silent": "false",
"triggerEvent": "false",
"axisLine:": {},
"axisTick:": {},
"minorTick:": {},
"axisLabel:": {},
"splitLine:": {},
"minorSplitLine:": {},
"splitArea:": {},
"data:": [],
"axisPointer:": {},
"zlevel": "0",
"z": "0"
},
"yAxis": {
"id": "",
"show": "true",
"gridIndex": "0",
"alignTicks": "false",
"position": "",
"offset": "0",
"type": "value",
"name": "",
"nameLocation": "end",
"nameTextStyle:": {},
"nameGap": "15",
"nameRotate": "",
"inverse": "false",
"boundaryGap": "",
"min": "",
"max": "",
"scale": "false",
"splitNumber": "5",
"minInterval": "0",
"maxInterval": "",
"interval": "",
"logBase": "10",
"silent": "false",
"triggerEvent": "false",
"axisLine:": {},
"axisTick:": {},
"minorTick:": {},
"axisLabel:": {},
"splitLine:": {},
"minorSplitLine:": {},
"splitArea:": {},
"data:": [],
"axisPointer:": {},
"zlevel": "0",
"z": "0"
},
"polar": {
"id": "",
"zlevel": "0",
"z": "2",
"center": "[50%, 50%]",
"radius": "",
"tooltip:": {}
},
"radiusAxis": {
"id": "",
"polarIndex": "0",
"type": "value",
"name": "",
"nameLocation": "end",
"nameTextStyle:": {},
"nameGap": "15",
"nameRotate": "",
"inverse": "false",
"boundaryGap": "",
"min": "",
"max": "",
"scale": "false",
"splitNumber": "5",
"minInterval": "0",
"maxInterval": "",
"interval": "",
"logBase": "10",
"silent": "false",
"triggerEvent": "false",
"axisLine:": {},
"axisTick:": {},
"minorTick:": {},
"axisLabel:": {},
"splitLine:": {},
"minorSplitLine:": {},
"splitArea:": {},
"data:": [],
"axisPointer:": {},
"zlevel": "0",
"z": "0"
},
"angleAxis": {
"id": "",
"polarIndex": "0",
"startAngle": "90",
"clockwise": "true",
"type": "category",
"boundaryGap": "",
"min": "",
"max": "",
"scale": "false",
"splitNumber": "5",
"minInterval": "0",
"maxInterval": "",
"interval": "",
"logBase": "10",
"silent": "false",
"triggerEvent": "false",
"axisLine:": {},
"axisTick:": {},
"minorTick:": {},
"axisLabel:": {},
"splitLine:": {},
"minorSplitLine:": {},
"splitArea:": {},
"data:": [],
"axisPointer:": {},
"zlevel": "0",
"z": "0"
},
"radar": {
"id": "",
"zlevel": "0",
"z": "2",
"center": "[50%, 50%]",
"radius": "75%",
"startAngle": "90",
"axisName:": {},
"nameGap": "15",
"splitNumber": "5",
"shape": "polygon",
"scale": "false",
"silent": "false",
"triggerEvent": "false",
"axisLine:": {},
"axisTick:": {},
"axisLabel:": {},
"splitLine:": {},
"splitArea:": {},
"indicator:": []
},
"dataZoom:": [],
"visualMap:": [],
"tooltip": {
"show": "true",
"trigger": "item",
"axisPointer:": {},
"showContent": "true",
"alwaysShowContent": "false",
"triggerOn": "mousemove|click",
"showDelay": "0",
"hideDelay": "100",
"enterable": "false",
"renderMode": "html",
"confine": "false",
"appendToBody": "false",
"className": "",
"transitionDuration": "0.4",
"position": "",
"formatter": "",
"valueFormatter": "",
"backgroundColor": "rgba(50,50,50,0.7)",
"borderColor": "#333",
"borderWidth": "0",
"padding": "5",
"textStyle:": {},
"extraCssText": "",
"order": "seriesAsc"
},
"axisPointer": {
"id": "",
"show": "false",
"type": "line",
"snap": "",
"z": "",
"label:": {},
"lineStyle:": {},
"shadowStyle:": {},
"triggerTooltip": "true",
"value": "",
"status": "",
"handle:": {},
"link": "",
"triggerOn": "mousemove|click"
},
"toolbox": {
"id": "",
"show": "true",
"orient": "horizontal",
"itemSize": "15",
"itemGap": "8",
"showTitle": "true",
"feature:": {},
"iconStyle:": {},
"emphasis:": {},
"zlevel": "0",
"z": "2",
"left": "auto",
"top": "auto",
"right": "auto",
"bottom": "auto",
"width": "auto",
"height": "auto",
"tooltip": ""
},
"brush": {
"id": "",
"toolbox": "[rect, polygon, keep, clear]",
"brushLink": "",
"seriesIndex": "all",
"geoIndex": "",
"xAxisIndex": "",
"yAxisIndex": "",
"brushType": "rect",
"brushMode": "single",
"transformable": "true",
"brushStyle": "",
"throttleType": "fixRate",
"throttleDelay": "0",
"removeOnClick": "true",
"inBrush": "",
"outOfBrush": "",
"z": "10000"
},
"geo": {
"id": "",
"show": "true",
"map": "",
"roam": "false",
"projection:": {},
"center": "",
"aspectScale": "0.75",
"boundingCoords": "",
"zoom": "1",
"scaleLimit:": {},
"nameMap": "",
"nameProperty": "name",
"selectedMode": "false",
"label:": {},
"itemStyle:": {},
"emphasis:": {},
"select:": {},
"blur:": {},
"zlevel": "0",
"z": "2",
"left": "auto",
"top": "auto",
"right": "auto",
"bottom": "auto",
"layoutCenter": "",
"layoutSize": "",
"regions:": [],
"silent": "false",
"tooltip:": {}
},
"parallel": {
"id": "",
"zlevel": "0",
"z": "2",
"left": "80",
"top": "60",
"right": "80",
"bottom": "60",
"width": "auto",
"height": "auto",
"layout": "horizontal",
"axisExpandable": "false",
"axisExpandCenter": "",
"axisExpandCount": "0",
"axisExpandWidth": "50",
"axisExpandTriggerOn": "click",
"parallelAxisDefault:": {}
},
"parallelAxis": {
"id": "",
"dim": "",
"parallelIndex": "0",
"realtime": "true",
"areaSelectStyle:": {},
"type": "value",
"name": "",
"nameLocation": "end",
"nameTextStyle:": {},
"nameGap": "15",
"nameRotate": "",
"inverse": "false",
"boundaryGap": "",
"min": "",
"max": "",
"scale": "false",
"splitNumber": "5",
"minInterval": "0",
"maxInterval": "",
"interval": "",
"logBase": "10",
"silent": "false",
"triggerEvent": "false",
"axisLine:": {},
"axisTick:": {},
"minorTick:": {},
"axisLabel:": {},
"data:": []
},
"singleAxis": {
"id": "",
"zlevel": "0",
"z": "2",
"left": "5%",
"top": "5%",
"right": "5%",
"bottom": "5%",
"width": "auto",
"height": "auto",
"orient": "horizontal",
"type": "value",
"name": "",
"nameLocation": "end",
"nameTextStyle:": {},
"nameGap": "15",
"nameRotate": "",
"inverse": "false",
"boundaryGap": "",
"min": "",
"max": "",
"scale": "false",
"splitNumber": "5",
"minInterval": "0",
"maxInterval": "",
"interval": "",
"logBase": "10",
"silent": "false",
"triggerEvent": "false",
"axisLine:": {},
"axisTick:": {},
"minorTick:": {},
"axisLabel:": {},
"splitLine:": {},
"minorSplitLine:": {},
"splitArea:": {},
"data:": [],
"axisPointer:": {},
"tooltip:": {}
},
"timeline": {
"show": "true",
"type": "slider",
"axisType": "time",
"currentIndex": "0",
"autoPlay": "false",
"rewind": "false",
"loop": "true",
"playInterval": "2000",
"realtime": "true",
"replaceMerge": "undefined",
"controlPosition": "left",
"zlevel": "0",
"z": "2",
"left": "auto",
"top": "auto",
"right": "auto",
"bottom": "auto",
"padding": "5",
"orient": "horizontal",
"inverse": "false",
"symbol": "emptyCircle",
"symbolSize": "10",
"symbolRotate": "",
"symbolKeepAspect": "false",
"symbolOffset": "[0, 0]",
"lineStyle:": {},
"label:": {},
"itemStyle:": {},
"checkpointStyle:": {},
"controlStyle:": {},
"progress:": {},
"emphasis:": {},
"data": ""
},
"graphic": { "id": "", "elements:": [] },
"calendar": {
"id": "",
"zlevel": "0",
"z": "2",
"left": "80",
"top": "60",
"right": "auto",
"bottom": "auto",
"width": "auto",
"height": "auto",
"range": "",
"cellSize": "20",
"orient": "horizontal",
"splitLine:": {},
"itemStyle:": {},
"dayLabel:": {},
"monthLabel:": {},
"yearLabel:": {},
"silent": "false"
},
"dataset": {
"id": "",
"source": "",
"dimensions": "",
"sourceHeader": "",
"transform:": [],
"fromDatasetIndex": "",
"fromDatasetId": "",
"fromTransformResult": ""
},
"aria": { "enabled": "false", "label:": {}, "decal:": {} },
"series:": [],
"darkMode": "false",
"color": [],
"backgroundColor": "transparent",
"textStyle": {
"color": "#fff",
"fontStyle": "normal",
"fontWeight": "normal",
"fontFamily": "sans-serif",
"fontSize": "12",
"lineHeight": "",
"width": "",
"height": "",
"textBorderColor": "",
"textBorderWidth": "",
"textBorderType": "solid",
"textBorderDashOffset": "0",
"textShadowColor": "transparent",
"textShadowBlur": "0",
"textShadowOffsetX": "0",
"textShadowOffsetY": "0",
"overflow": "none",
"ellipsis": "..."
},
"animation": "true",
"animationThreshold": "2000",
"animationDuration": "1000",
"animationEasing": "cubicOut",
"animationDelay": "0",
"animationDurationUpdate": "300",
"animationEasingUpdate": "cubicInOut",
"animationDelayUpdate": "0",
"stateAnimation": { "duration": "300", "easing": "cubicOut" },
"blendMode": "source-over",
"hoverLayerThreshold": "3000",
"useUTC": "false",
"options": [],
"media:": []
}
@guhuajun We've actually built a pydantic model for eCharts after extracting the schema in the eCharts documentation build: https://github.com/epi2me-labs/ezcharts
Its not perfect: its highly redundant and there are various things where the schema is not correct and we've have to manually edit things to allow contructs we know render correctly to pass the pydantic models.
+1, a schema would be quite nice to have considering the json format was identified as a key feature in the echarts paper.
Just some more infos, i tried to build a valid schema from https://github.com/apache/echarts-website/blob/asf-site/en/documents/option.json But there are some issues (i checked only one value after i give up):
path /xAxis/data
which should have an anyOf only hast a "object" configured. This means that validation is not possible even with a valid schema.
What problem does this feature solve?
It will allow the users to validate whether the Echarts
option
they have authored is correct or not. Vega and Vega-Lite also provides it: https://github.com/vega/schema.What does the proposed API look like?
.json
files can be released. Or an ESM module can be released from where the JSON schema can be simply imported and later used by users as needed.