| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| import { each } from 'zrender/src/core/util'; |
| import Group from 'zrender/src/container/Group'; |
| import * as componentUtil from '../util/component'; |
| import * as clazzUtil from '../util/clazz'; |
| import * as modelUtil from '../util/model'; |
| import * as graphicUtil from '../util/graphic'; |
| import { createTask } from '../stream/task'; |
| import createRenderPlanner from '../chart/helper/createRenderPlanner'; |
| var inner = modelUtil.makeInner(); |
| var renderPlanner = createRenderPlanner(); |
| |
| function Chart() { |
| /** |
| * @type {module:zrender/container/Group} |
| * @readOnly |
| */ |
| this.group = new Group(); |
| /** |
| * @type {string} |
| * @readOnly |
| */ |
| |
| this.uid = componentUtil.getUID('viewChart'); |
| this.renderTask = createTask({ |
| plan: renderTaskPlan, |
| reset: renderTaskReset |
| }); |
| this.renderTask.context = { |
| view: this |
| }; |
| } |
| |
| Chart.prototype = { |
| type: 'chart', |
| |
| /** |
| * Init the chart. |
| * @param {module:echarts/model/Global} ecModel |
| * @param {module:echarts/ExtensionAPI} api |
| */ |
| init: function (ecModel, api) {}, |
| |
| /** |
| * Render the chart. |
| * @param {module:echarts/model/Series} seriesModel |
| * @param {module:echarts/model/Global} ecModel |
| * @param {module:echarts/ExtensionAPI} api |
| * @param {Object} payload |
| */ |
| render: function (seriesModel, ecModel, api, payload) {}, |
| |
| /** |
| * Highlight series or specified data item. |
| * @param {module:echarts/model/Series} seriesModel |
| * @param {module:echarts/model/Global} ecModel |
| * @param {module:echarts/ExtensionAPI} api |
| * @param {Object} payload |
| */ |
| highlight: function (seriesModel, ecModel, api, payload) { |
| toggleHighlight(seriesModel.getData(), payload, 'emphasis'); |
| }, |
| |
| /** |
| * Downplay series or specified data item. |
| * @param {module:echarts/model/Series} seriesModel |
| * @param {module:echarts/model/Global} ecModel |
| * @param {module:echarts/ExtensionAPI} api |
| * @param {Object} payload |
| */ |
| downplay: function (seriesModel, ecModel, api, payload) { |
| toggleHighlight(seriesModel.getData(), payload, 'normal'); |
| }, |
| |
| /** |
| * Remove self. |
| * @param {module:echarts/model/Global} ecModel |
| * @param {module:echarts/ExtensionAPI} api |
| */ |
| remove: function (ecModel, api) { |
| this.group.removeAll(); |
| }, |
| |
| /** |
| * Dispose self. |
| * @param {module:echarts/model/Global} ecModel |
| * @param {module:echarts/ExtensionAPI} api |
| */ |
| dispose: function () {}, |
| |
| /** |
| * Rendering preparation in progressive mode. |
| * @param {module:echarts/model/Series} seriesModel |
| * @param {module:echarts/model/Global} ecModel |
| * @param {module:echarts/ExtensionAPI} api |
| * @param {Object} payload |
| */ |
| incrementalPrepareRender: null, |
| |
| /** |
| * Render in progressive mode. |
| * @param {Object} params See taskParams in `stream/task.js` |
| * @param {module:echarts/model/Series} seriesModel |
| * @param {module:echarts/model/Global} ecModel |
| * @param {module:echarts/ExtensionAPI} api |
| * @param {Object} payload |
| */ |
| incrementalRender: null, |
| |
| /** |
| * Update transform directly. |
| * @param {module:echarts/model/Series} seriesModel |
| * @param {module:echarts/model/Global} ecModel |
| * @param {module:echarts/ExtensionAPI} api |
| * @param {Object} payload |
| * @return {Object} {update: true} |
| */ |
| updateTransform: null, |
| |
| /** |
| * The view contains the given point. |
| * @interface |
| * @param {Array.<number>} point |
| * @return {boolean} |
| */ |
| // containPoint: function () {} |
| |
| /** |
| * @param {string} eventType |
| * @param {Object} query |
| * @param {module:zrender/Element} targetEl |
| * @param {Object} packedEvent |
| * @return {boolen} Pass only when return `true`. |
| */ |
| filterForExposedEvent: null |
| }; |
| var chartProto = Chart.prototype; |
| |
| chartProto.updateView = chartProto.updateLayout = chartProto.updateVisual = function (seriesModel, ecModel, api, payload) { |
| this.render(seriesModel, ecModel, api, payload); |
| }; |
| /** |
| * Set state of single element |
| * @param {module:zrender/Element} el |
| * @param {string} state 'normal'|'emphasis' |
| * @param {number} highlightDigit |
| */ |
| |
| |
| function elSetState(el, state, highlightDigit) { |
| if (el) { |
| el.trigger(state, highlightDigit); |
| |
| if (el.isGroup // Simple optimize. |
| && !graphicUtil.isHighDownDispatcher(el)) { |
| for (var i = 0, len = el.childCount(); i < len; i++) { |
| elSetState(el.childAt(i), state, highlightDigit); |
| } |
| } |
| } |
| } |
| /** |
| * @param {module:echarts/data/List} data |
| * @param {Object} payload |
| * @param {string} state 'normal'|'emphasis' |
| */ |
| |
| |
| function toggleHighlight(data, payload, state) { |
| var dataIndex = modelUtil.queryDataIndex(data, payload); |
| var highlightDigit = payload && payload.highlightKey != null ? graphicUtil.getHighlightDigit(payload.highlightKey) : null; |
| |
| if (dataIndex != null) { |
| each(modelUtil.normalizeToArray(dataIndex), function (dataIdx) { |
| elSetState(data.getItemGraphicEl(dataIdx), state, highlightDigit); |
| }); |
| } else { |
| data.eachItemGraphicEl(function (el) { |
| elSetState(el, state, highlightDigit); |
| }); |
| } |
| } // Enable Chart.extend. |
| |
| |
| clazzUtil.enableClassExtend(Chart, ['dispose']); // Add capability of registerClass, getClass, hasClass, registerSubTypeDefaulter and so on. |
| |
| clazzUtil.enableClassManagement(Chart, { |
| registerWhenExtend: true |
| }); |
| |
| Chart.markUpdateMethod = function (payload, methodName) { |
| inner(payload).updateMethod = methodName; |
| }; |
| |
| function renderTaskPlan(context) { |
| return renderPlanner(context.model); |
| } |
| |
| function renderTaskReset(context) { |
| var seriesModel = context.model; |
| var ecModel = context.ecModel; |
| var api = context.api; |
| var payload = context.payload; // ???! remove updateView updateVisual |
| |
| var progressiveRender = seriesModel.pipelineContext.progressiveRender; |
| var view = context.view; |
| var updateMethod = payload && inner(payload).updateMethod; |
| var methodName = progressiveRender ? 'incrementalPrepareRender' : updateMethod && view[updateMethod] ? updateMethod // `appendData` is also supported when data amount |
| // is less than progressive threshold. |
| : 'render'; |
| |
| if (methodName !== 'render') { |
| view[methodName](seriesModel, ecModel, api, payload); |
| } |
| |
| return progressMethodMap[methodName]; |
| } |
| |
| var progressMethodMap = { |
| incrementalPrepareRender: { |
| progress: function (params, context) { |
| context.view.incrementalRender(params, context.model, context.ecModel, context.api, context.payload); |
| } |
| }, |
| render: { |
| // Put view.render in `progress` to support appendData. But in this case |
| // view.render should not be called in reset, otherwise it will be called |
| // twise. Use `forceFirstProgress` to make sure that view.render is called |
| // in any cases. |
| forceFirstProgress: true, |
| progress: function (params, context) { |
| context.view.render(context.model, context.ecModel, context.api, context.payload); |
| } |
| } |
| }; |
| export default Chart; |