Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Request for JSON Schema #16427

Open
maneetgoyal opened this issue Jan 25, 2022 · 10 comments
Open

[Feature] Request for JSON Schema #16427

maneetgoyal opened this issue Jan 25, 2022 · 10 comments
Labels

Comments

@maneetgoyal
Copy link

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.

@echarts-bot echarts-bot bot added en This issue is in English pending We are not sure about whether this is a bug/new feature. waiting-for: community labels Jan 25, 2022
@pissang pissang removed pending We are not sure about whether this is a bug/new feature. waiting-for: community labels Jan 27, 2022
@pissang
Copy link
Contributor

pissang commented Jan 27, 2022

@maneetgoyal Hi, using TypeScript may provide a more accurate validation on the option.

@maneetgoyal
Copy link
Author

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.

@pissang
Copy link
Contributor

pissang commented Jan 27, 2022

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

@maneetgoyal

This comment has been minimized.

@maneetgoyal
Copy link
Author

@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.

@georgechr
Copy link

Hello, we are also looking for a valid schema. It's an important feature request

@guhuajun
Copy link

guhuajun commented Sep 21, 2022

@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:": []
}

@cjw85
Copy link

cjw85 commented Nov 24, 2022

@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.

@AaronNHart
Copy link

+1, a schema would be quite nice to have considering the json format was identified as a key feature in the echarts paper.

@lublak
Copy link

lublak commented Sep 6, 2024

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
grafik

which should have an anyOf only hast a "object" configured.
This means that validation is not possible even with a valid schema.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants