Spaces:
Running
Running
| /* | |
| * 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 SymbolDraw from '../../chart/helper/SymbolDraw'; | |
| import * as numberUtil from '../../util/number'; | |
| import SeriesData from '../../data/SeriesData'; | |
| import * as markerHelper from './markerHelper'; | |
| import MarkerView from './MarkerView'; | |
| import { CoordinateSystem } from '../../coord/CoordinateSystem'; | |
| import SeriesModel from '../../model/Series'; | |
| import MarkPointModel, {MarkPointDataItemOption} from './MarkPointModel'; | |
| import GlobalModel from '../../model/Global'; | |
| import MarkerModel from './MarkerModel'; | |
| import ExtensionAPI from '../../core/ExtensionAPI'; | |
| import { HashMap, isFunction, map, filter, curry, extend } from 'zrender/src/core/util'; | |
| import { getECData } from '../../util/innerStore'; | |
| import { getVisualFromData } from '../../visual/helper'; | |
| import { ZRColor } from '../../util/types'; | |
| import SeriesDimensionDefine from '../../data/SeriesDimensionDefine'; | |
| function updateMarkerLayout( | |
| mpData: SeriesData<MarkPointModel>, | |
| seriesModel: SeriesModel, | |
| api: ExtensionAPI | |
| ) { | |
| const coordSys = seriesModel.coordinateSystem; | |
| mpData.each(function (idx: number) { | |
| const itemModel = mpData.getItemModel<MarkPointDataItemOption>(idx); | |
| let point; | |
| const xPx = numberUtil.parsePercent(itemModel.get('x'), api.getWidth()); | |
| const yPx = numberUtil.parsePercent(itemModel.get('y'), api.getHeight()); | |
| if (!isNaN(xPx) && !isNaN(yPx)) { | |
| point = [xPx, yPx]; | |
| } | |
| // Chart like bar may have there own marker positioning logic | |
| else if (seriesModel.getMarkerPosition) { | |
| // Use the getMarkerPosition | |
| point = seriesModel.getMarkerPosition( | |
| mpData.getValues(mpData.dimensions, idx) | |
| ); | |
| } | |
| else if (coordSys) { | |
| const x = mpData.get(coordSys.dimensions[0], idx); | |
| const y = mpData.get(coordSys.dimensions[1], idx); | |
| point = coordSys.dataToPoint([x, y]); | |
| } | |
| // Use x, y if has any | |
| if (!isNaN(xPx)) { | |
| point[0] = xPx; | |
| } | |
| if (!isNaN(yPx)) { | |
| point[1] = yPx; | |
| } | |
| mpData.setItemLayout(idx, point); | |
| }); | |
| } | |
| class MarkPointView extends MarkerView { | |
| static type = 'markPoint'; | |
| type = MarkPointView.type; | |
| markerGroupMap: HashMap<SymbolDraw>; | |
| updateTransform(markPointModel: MarkPointModel, ecModel: GlobalModel, api: ExtensionAPI) { | |
| ecModel.eachSeries(function (seriesModel) { | |
| const mpModel = MarkerModel.getMarkerModelFromSeries(seriesModel, 'markPoint') as MarkPointModel; | |
| if (mpModel) { | |
| updateMarkerLayout( | |
| mpModel.getData(), | |
| seriesModel, api | |
| ); | |
| this.markerGroupMap.get(seriesModel.id).updateLayout(); | |
| } | |
| }, this); | |
| } | |
| renderSeries( | |
| seriesModel: SeriesModel, | |
| mpModel: MarkPointModel, | |
| ecModel: GlobalModel, | |
| api: ExtensionAPI | |
| ) { | |
| const coordSys = seriesModel.coordinateSystem; | |
| const seriesId = seriesModel.id; | |
| const seriesData = seriesModel.getData(); | |
| const symbolDrawMap = this.markerGroupMap; | |
| const symbolDraw = symbolDrawMap.get(seriesId) | |
| || symbolDrawMap.set(seriesId, new SymbolDraw()); | |
| const mpData = createData(coordSys, seriesModel, mpModel); | |
| // FIXME | |
| mpModel.setData(mpData); | |
| updateMarkerLayout(mpModel.getData(), seriesModel, api); | |
| mpData.each(function (idx) { | |
| const itemModel = mpData.getItemModel<MarkPointDataItemOption>(idx); | |
| let symbol = itemModel.getShallow('symbol'); | |
| let symbolSize = itemModel.getShallow('symbolSize'); | |
| let symbolRotate = itemModel.getShallow('symbolRotate'); | |
| let symbolOffset = itemModel.getShallow('symbolOffset'); | |
| const symbolKeepAspect = itemModel.getShallow('symbolKeepAspect'); | |
| // TODO: refactor needed: single data item should not support callback function | |
| if (isFunction(symbol) || isFunction(symbolSize) || isFunction(symbolRotate) || isFunction(symbolOffset)) { | |
| const rawIdx = mpModel.getRawValue(idx); | |
| const dataParams = mpModel.getDataParams(idx); | |
| if (isFunction(symbol)) { | |
| symbol = symbol(rawIdx, dataParams); | |
| } | |
| if (isFunction(symbolSize)) { | |
| // FIXME 这里不兼容 ECharts 2.x,2.x 貌似参数是整个数据? | |
| symbolSize = symbolSize(rawIdx, dataParams); | |
| } | |
| if (isFunction(symbolRotate)) { | |
| symbolRotate = symbolRotate(rawIdx, dataParams); | |
| } | |
| if (isFunction(symbolOffset)) { | |
| symbolOffset = symbolOffset(rawIdx, dataParams); | |
| } | |
| } | |
| const style = itemModel.getModel('itemStyle').getItemStyle(); | |
| const color = getVisualFromData(seriesData, 'color') as ZRColor; | |
| if (!style.fill) { | |
| style.fill = color; | |
| } | |
| mpData.setItemVisual(idx, { | |
| symbol: symbol, | |
| symbolSize: symbolSize, | |
| symbolRotate: symbolRotate, | |
| symbolOffset: symbolOffset, | |
| symbolKeepAspect: symbolKeepAspect, | |
| style | |
| }); | |
| }); | |
| // TODO Text are wrong | |
| symbolDraw.updateData(mpData); | |
| this.group.add(symbolDraw.group); | |
| // Set host model for tooltip | |
| // FIXME | |
| mpData.eachItemGraphicEl(function (el) { | |
| el.traverse(function (child) { | |
| getECData(child).dataModel = mpModel; | |
| }); | |
| }); | |
| this.markKeep(symbolDraw); | |
| symbolDraw.group.silent = mpModel.get('silent') || seriesModel.get('silent'); | |
| } | |
| } | |
| function createData( | |
| coordSys: CoordinateSystem, | |
| seriesModel: SeriesModel, | |
| mpModel: MarkPointModel | |
| ) { | |
| let coordDimsInfos: SeriesDimensionDefine[]; | |
| if (coordSys) { | |
| coordDimsInfos = map(coordSys && coordSys.dimensions, function (coordDim) { | |
| const info = seriesModel.getData().getDimensionInfo( | |
| seriesModel.getData().mapDimension(coordDim) | |
| ) || {}; | |
| // In map series data don't have lng and lat dimension. Fallback to same with coordSys | |
| return extend(extend({}, info), { | |
| name: coordDim, | |
| // DON'T use ordinalMeta to parse and collect ordinal. | |
| ordinalMeta: null | |
| }); | |
| }); | |
| } | |
| else { | |
| coordDimsInfos = [{ | |
| name: 'value', | |
| type: 'float' | |
| }]; | |
| } | |
| const mpData = new SeriesData(coordDimsInfos, mpModel); | |
| let dataOpt = map(mpModel.get('data'), curry( | |
| markerHelper.dataTransform, seriesModel | |
| )); | |
| if (coordSys) { | |
| dataOpt = filter( | |
| dataOpt, curry(markerHelper.dataFilter, coordSys) | |
| ); | |
| } | |
| const dimValueGetter = markerHelper.createMarkerDimValueGetter(!!coordSys, coordDimsInfos); | |
| mpData.initData(dataOpt, null, dimValueGetter); | |
| return mpData; | |
| } | |
| export default MarkPointView; | |