{"record":{"id":"87ae11bca31cb61d","repo":"apache/echarts","slug":"render-method-must-been-implemented","errorCode":null,"errorMessage":"render method must been implemented","messagePattern":"render method must been implemented","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/view/Chart.ts","lineNumber":153,"sourceCode":"    })();\n\n\n    constructor() {\n        this.group = new Group();\n        this.uid = componentUtil.getUID('viewChart');\n\n        this.renderTask = createTask<SeriesTaskContext>({\n            plan: renderTaskPlan,\n            reset: renderTaskReset\n        });\n        this.renderTask.context = {view: this} as SeriesTaskContext;\n    }\n\n    init(ecModel: GlobalModel, api: ExtensionAPI): void {}\n\n    render(seriesModel: SeriesModel, ecModel: GlobalModel, api: ExtensionAPI, payload: Payload): void {\n        if (__DEV__) {\n            throw new Error('render method must been implemented');\n        }\n    }\n\n    /**\n     * Highlight series or specified data item.\n     */\n    highlight(seriesModel: SeriesModel, ecModel: GlobalModel, api: ExtensionAPI, payload: Payload): void {\n        const data = seriesModel.getData(payload && payload.dataType);\n        if (!data) {\n            if (__DEV__) {\n                error(`Unknown dataType ${payload.dataType}`);\n            }\n            return;\n        }\n        toggleHighlight(data, payload, 'emphasis');\n    }\n\n    /**","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/apache/echarts/blob/30076aedcd7b7f65d8dd8e8d9ece46ce778133a3/src/view/Chart.ts#L135-L171","documentation":"`ChartView` (src/view/Chart.ts) is the abstract base class for every chart renderer. Its `render(seriesModel, ecModel, api, payload)` is a stub guarded by `__DEV__` that throws to enforce that each concrete chart view overrides `render()`. When ECharts dispatches the render task for a series and the resolved ChartView subclass has not implemented its own `render`, this error fires (in dev builds). In a production build the guard is removed, so the stub becomes a silent no-op and the series simply renders nothing.","triggerScenarios":"A class extending `ChartView` is registered as a chart view (via `registers.registerChartView`/`registerClass`) without overriding `render(seriesModel, ecModel, api, payload)`. ECharts then instantiates it for a series and calls the inherited stub.","commonSituations":"Developing a custom series/chart extension and forgetting to implement `render`; a partially-ported or incompletely-updated third-party chart view; registering an abstract/incomplete view class by mistake; a version upgrade where the `render` signature changed and a subclass override stopped matching.","solutions":["Implement `render(seriesModel, ecModel, api, payload)` on your ChartView subclass.","Author the view in TypeScript extending `ChartView` so the type checker surfaces the missing override.","If the view comes from a third-party package, confirm it is compatible with your ECharts version and register the correct, complete view class.","Verify you registered the concrete view class (not the abstract base or a sibling) for the chart type."],"exampleFix":"// before\nclass MyChartView extends echarts.ChartView {\n  static type = 'myChart';\n  // render() missing -> 'render method must been implemented'\n}\n\n// after\nclass MyChartView extends echarts.ChartView {\n  static type = 'myChart';\n  render(seriesModel, ecModel, api, payload) {\n    // ...build zrender elements into this.group...\n  }\n}","handlingStrategy":"type-guard","validationCode":"// Before registering a custom chart view, assert it actually overrides render\n// (ChartView.prototype.render is the throwing stub).\nfunction assertViewImplementsRender(ViewClass) {\n  if (ViewClass.prototype.render === Object.getPrototypeOf(ViewClass.prototype).render\n      || ViewClass.prototype === echarts.ChartView.prototype) {\n    throw new Error(ViewClass.name + ' must override ChartView.render()');\n  }\n}\n// assertViewImplementsRender(MyChartView);","typeGuard":"function hasRenderOverride(ViewClass) {\n  // True only when render is declared on this class (or a non-ChartView ancestor).\n  let proto = ViewClass.prototype;\n  while (proto && proto !== echarts.ChartView.prototype) {\n    if (Object.prototype.hasOwnProperty.call(proto, 'render')) return true;\n    proto = Object.getPrototypeOf(proto);\n  }\n  return false;\n}","tryCatchPattern":null,"preventionTips":["Author chart views in TypeScript extending `ChartView` and mark `render` as required so the compiler rejects incomplete subclasses.","Add a unit test that instantiates each custom view and asserts `render` is callable on a minimal series model.","Develop against a dev build (`__DEV__` on) so the stub throws immediately rather than silently rendering nothing in production."],"tags":["chart-view","abstract-method","custom-chart","render"],"backgroundTag":null,"analyzedSha":"30076aedcd7b7f65d8dd8e8d9ece46ce778133a3","analyzedAt":"2026-08-12T12:42:28.134Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}