/ *
* 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 .
* /
/ * *
* AUTO - GENERATED FILE . DO NOT MODIFY .
* /
import { __ extends } from "tslib" ;
/ *
* 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 * as zrender from 'zrender/lib/zrender.js' ;
import { assert , each , isFunction , isObject , indexOf , bind , clone , setAsPrimitive , extend , createHashMap , map , defaults , isDom , isArray , noop , isString , retrieve2 } from 'zrender/lib/core/util.js' ;
import env from 'zrender/lib/core/env.js' ;
import timsort from 'zrender/lib/core/timsort.js' ;
import Eventful from 'zrender/lib/core/Eventful.js' ;
import GlobalModel from '../model/Global.js' ;
import ExtensionAPI from './ExtensionAPI.js' ;
import CoordinateSystemManager from './CoordinateSystem.js' ;
import OptionManager from '../model/OptionManager.js' ;
import backwardCompat from '../preprocessor/backwardCompat.js' ;
import dataStack from '../processor/dataStack.js' ;
import SeriesModel from '../model/Series.js' ;
import ComponentView from '../view/Component.js' ;
import ChartView from '../view/Chart.js' ;
import * as graphic from '../util/graphic.js' ;
import { getECData } from '../util/innerStore.js' ;
import { isHighDownDispatcher , HOVER_STATE_EMPHASIS , HOVER_STATE_BLUR , blurSeriesFromHighlightPayload , toggleSelectionFromPayload , updateSeriesElementSelection , getAllSelectedIndices , isSelectChangePayload , isHighDownPayload , HIGHLIGHT_ACTION_TYPE , DOWNPLAY_ACTION_TYPE , SELECT_ACTION_TYPE , UNSELECT_ACTION_TYPE , TOGGLE_SELECT_ACTION_TYPE , savePathStates , enterEmphasis , leaveEmphasis , leaveBlur , enterSelect , leaveSelect , enterBlur , allLeaveBlur , findComponentHighDownDispatchers , blurComponent , handleGlobalMouseOverForHighDown , handleGlobalMouseOutForHighDown } from '../util/states.js' ;
import * as modelUtil from '../util/model.js' ;
import { throttle } from '../util/throttle.js' ;
import { seriesStyleTask , dataStyleTask , dataColorPaletteTask } from '../visual/style.js' ;
import loadingDefault from '../loading/default.js' ;
import Scheduler from './Scheduler.js' ;
import lightTheme from '../theme/light.js' ;
import darkTheme from '../theme/dark.js' ;
import { parseClassType } from '../util/clazz.js' ;
import { ECEventProcessor } from '../util/ECEventProcessor.js' ;
import { seriesSymbolTask , dataSymbolTask } from '../visual/symbol.js' ;
import { getVisualFromData , getItemVisualFromData } from '../visual/helper.js' ;
import { deprecateLog , deprecateReplaceLog , error , warn } from '../util/log.js' ;
import { handleLegacySelectEvents } from '../legacy/dataSelectAction.js' ;
import { registerExternalTransform } from '../data/helper/transform.js' ;
import { createLocaleObject , SYSTEM_LANG } from './locale.js' ;
import { findEventDispatcher } from '../util/event.js' ;
import decal from '../visual/decal.js' ;
import lifecycle from './lifecycle.js' ;
import { platformApi , setPlatformAPI } from 'zrender/lib/core/platform.js' ;
import { getImpl } from './impl.js' ;
export var version = '5.4.3' ;
export var dependencies = {
zrender : '5.4.4'
} ;
var TEST_FRAME_REMAIN_TIME = 1 ;
var PRIORITY_PROCESSOR_SERIES_FILTER = 800 ; // Some data processors depends on the stack result dimension (to calculate data extent).
// So data stack stage should be in front of data processing stage.
var PRIORITY_PROCESSOR_DATASTACK = 900 ; // "Data filter" will block the stream, so it should be
// put at the beginning of data processing.
var PRIORITY_PROCESSOR_FILTER = 1000 ;
var PRIORITY_PROCESSOR_DEFAULT = 2000 ;
var PRIORITY_PROCESSOR_STATISTIC = 5000 ;
var PRIORITY_VISUAL_LAYOUT = 1000 ;
var PRIORITY_VISUAL_PROGRESSIVE_LAYOUT = 1100 ;
var PRIORITY_VISUAL_GLOBAL = 2000 ;
var PRIORITY_VISUAL_CHART = 3000 ;
var PRIORITY_VISUAL_COMPONENT = 4000 ; // Visual property in data. Greater than `PRIORITY_VISUAL_COMPONENT` to enable to
// overwrite the viusal result of component (like `visualMap`)
// using data item specific setting (like itemStyle.xxx on data item)
var PRIORITY_VISUAL_CHART_DATA_CUSTOM = 4500 ; // Greater than `PRIORITY_VISUAL_CHART_DATA_CUSTOM` to enable to layout based on
// visual result like `symbolSize`.
var PRIORITY_VISUAL_POST_CHART_LAYOUT = 4600 ;
var PRIORITY_VISUAL_BRUSH = 5000 ;
var PRIORITY_VISUAL_ARIA = 6000 ;
var PRIORITY_VISUAL_DECAL = 7000 ;
export var PRIORITY = {
PROCESSOR : {
FILTER : PRIORITY_PROCESSOR_FILTER ,
SERIES_FILTER : PRIORITY_PROCESSOR_SERIES_FILTER ,
STATISTIC : PRIORITY_PROCESSOR_STATISTIC
} ,
VISUAL : {
LAYOUT : PRIORITY_VISUAL_LAYOUT ,
PROGRESSIVE_LAYOUT : PRIORITY_VISUAL_PROGRESSIVE_LAYOUT ,
GLOBAL : PRIORITY_VISUAL_GLOBAL ,
CHART : PRIORITY_VISUAL_CHART ,
POST_CHART_LAYOUT : PRIORITY_VISUAL_POST_CHART_LAYOUT ,
COMPONENT : PRIORITY_VISUAL_COMPONENT ,
BRUSH : PRIORITY_VISUAL_BRUSH ,
CHART_ITEM : PRIORITY_VISUAL_CHART_DATA_CUSTOM ,
ARIA : PRIORITY_VISUAL_ARIA ,
DECAL : PRIORITY_VISUAL_DECAL
}
} ; // Main process have three entries: `setOption`, `dispatchAction` and `resize`,
// where they must not be invoked nestedly, except the only case: invoke
// dispatchAction with updateMethod "none" in main process.
// This flag is used to carry out this rule.
// All events will be triggered out side main process (i.e. when !this[IN_MAIN_PROCESS]).
var IN_MAIN_PROCESS_KEY = '__flagInMainProcess' ;
var PENDING_UPDATE = '__pendingUpdate' ;
var STATUS_NEEDS_UPDATE_KEY = '__needsUpdateStatus' ;
var ACTION_REG = /^[a-zA-Z0-9_]+$/ ;
var CONNECT_STATUS_KEY = '__connectUpdateStatus' ;
var CONNECT_STATUS_PENDING = 0 ;
var CONNECT_STATUS_UPDATING = 1 ;
var CONNECT_STATUS_UPDATED = 2 ;
;
;
function createRegisterEventWithLowercaseECharts ( method ) {
return function ( ) {
var args = [ ] ;
for ( var _ i = 0 ; _ i < arguments . length ; _ i ++ ) {
args [ _ i ] = arguments [ _ i ] ;
}
if ( this . isDisposed ( ) ) {
disposedWarning ( this . id ) ;
return ;
}
return toLowercaseNameAndCallEventful ( this , method , args ) ;
} ;
}
function createRegisterEventWithLowercaseMessageCenter ( method ) {
return function ( ) {
var args = [ ] ;
for ( var _ i = 0 ; _ i < arguments . length ; _ i ++ ) {
args [ _ i ] = arguments [ _ i ] ;
}
return toLowercaseNameAndCallEventful ( this , method , args ) ;
} ;
}
function toLowercaseNameAndCallEventful ( host , method , args ) {
// `args[0]` is event name. Event name is all lowercase.
args [ 0 ] = args [ 0 ] && args [ 0 ] . toLowerCase ( ) ;
return Eventful . prototype [ method ] . apply ( host , args ) ;
}
var MessageCenter =
/** @class */
function ( _ super ) {
__ extends ( MessageCenter , _ super ) ;
function MessageCenter ( ) {
return _ super !== null && _ super . apply ( this , arguments ) || this ;
}
return MessageCenter ;
} ( Eventful ) ;
var messageCenterProto = MessageCenter . prototype ;
messageCenterProto . on = createRegisterEventWithLowercaseMessageCenter ( 'on' ) ;
messageCenterProto . off = createRegisterEventWithLowercaseMessageCenter ( 'off' ) ; // ---------------------------------------
// Internal method names for class ECharts
// ---------------------------------------
var prepare ;
var prepareView ;
var updateDirectly ;
var updateMethods ;
var doConvertPixel ;
var updateStreamModes ;
var doDispatchAction ;
var flushPendingActions ;
var triggerUpdatedEvent ;
var bindRenderedEvent ;
var bindMouseEvent ;
var render ;
var renderComponents ;
var renderSeries ;
var createExtensionAPI ;
var enableConnect ;
var markStatusToUpdate ;
var applyChangedStates ;
var ECharts =
/** @class */
function ( _ super ) {
__ extends ( ECharts , _ super ) ;
function ECharts ( dom , // Theme name or themeOption.
theme , opts ) {
var _ this = _ super . call ( this , new ECEventProcessor ( ) ) || this ;
_ this . _ chartsViews = [ ] ;
_ this . _ chartsMap = { } ;
_ this . _ componentsViews = [ ] ;
_ this . _ componentsMap = { } ; // Can't dispatch action during rendering procedure
_ this . _ pendingActions = [ ] ;
opts = opts || { } ; // Get theme by name
if ( isString ( theme ) ) {
theme = themeStorage [ theme ] ;
}
_ this . _ dom = dom ;
var defaultRenderer = 'canvas' ;
var defaultCoarsePointer = 'auto' ;
var defaultUseDirtyRect = false ;
if ( process . env . NODE_ENV !== 'production' ) {
var root =
/* eslint-disable-next-line */
env . hasGlobalWindow ? window : global ;
defaultRenderer = root . __ ECHARTS__DEFAULT__RENDERER__ || defaultRenderer ;
defaultCoarsePointer = retrieve2 ( root . __ ECHARTS__DEFAULT__COARSE_POINTER , defaultCoarsePointer ) ;
var devUseDirtyRect = root . __ ECHARTS__DEFAULT__USE_DIRTY_RECT__ ;
defaultUseDirtyRect = devUseDirtyRect == null ? defaultUseDirtyRect : devUseDirtyRect ;
}
var zr = _ this . _ zr = zrender . init ( dom , {
renderer : opts . renderer || defaultRenderer ,
devicePixelRatio : opts . devicePixelRatio ,
width : opts . width ,
height : opts . height ,
ssr : opts . ssr ,
useDirtyRect : retrieve2 ( opts . useDirtyRect , defaultUseDirtyRect ) ,
useCoarsePointer : retrieve2 ( opts . useCoarsePointer , defaultCoarsePointer ) ,
pointerSize : opts . pointerSize
} ) ;
_ this . _ ssr = opts . ssr ; // Expect 60 fps.
_ this . _ throttledZrFlush = throttle ( bind ( zr . flush , zr ) , 17 ) ;
theme = clone ( theme ) ;
theme && backwardCompat ( theme , true ) ;
_ this . _ theme = theme ;
_ this . _ locale = createLocaleObject ( opts . locale || SYSTEM_LANG ) ;
_ this . _ coordSysMgr = new CoordinateSystemManager ( ) ;
var api = _ this . _ api = createExtensionAPI ( _ this ) ; // Sort on demand
function prioritySortFunc ( a , b ) {
return a . __ prio - b . __ prio ;
}
timsort ( visualFuncs , prioritySortFunc ) ;
timsort ( dataProcessorFuncs , prioritySortFunc ) ;
_ this . _ scheduler = new Scheduler ( _ this , api , dataProcessorFuncs , visualFuncs ) ;
_ this . _ messageCenter = new MessageCenter ( ) ; // Init mouse events
_ this . _ initEvents ( ) ; // In case some people write `window.onresize = chart.resize`
_ this . resize = bind ( _ this . resize , _ this ) ;
zr . animation . on ( 'frame' , _ this . _ onframe , _ this ) ;
bindRenderedEvent ( zr , _ this ) ;
bindMouseEvent ( zr , _ this ) ; // ECharts instance can be used as value.
setAsPrimitive ( _ this ) ;
return _ this ;
}
ECharts . prototype . _ onframe = function ( ) {
if ( this . _ disposed ) {
return ;
}
applyChangedStates ( this ) ;
var scheduler = this . _ scheduler ; // Lazy update
if ( this [ PENDING_UPDATE ] ) {
var silent = this [ PENDING_UPDATE ] . silent ;
this [ IN_MAIN_PROCESS_KEY ] = true ;
try {
prepare ( this ) ;
updateMethods . update . call ( this , null , this [ PENDING_UPDATE ] . updateParams ) ;
} catch ( e ) {
this [ IN_MAIN_PROCESS_KEY ] = false ;
this [ PENDING_UPDATE ] = null ;
throw e ;
} // At present, in each frame, zrender performs:
// (1) animation step forward.
// (2) trigger('frame') (where this `_onframe` is called)
// (3) zrender flush (render).
// If we do nothing here, since we use `setToFinal: true`, the step (3) above
// will render the final state of the elements before the real animation started.
this . _ zr . flush ( ) ;
this [ IN_MAIN_PROCESS_KEY ] = false ;
this [ PENDING_UPDATE ] = null ;
flushPendingActions . call ( this , silent ) ;
triggerUpdatedEvent . call ( this , silent ) ;
} // Avoid do both lazy update and progress in one frame.
else if ( scheduler . unfinished ) {
// Stream progress.
var remainTime = TEST_FRAME_REMAIN_TIME ;
var ecModel = this . _ model ;
var api = this . _ api ;
scheduler . unfinished = false ;
do {
var startTime = + new Date ( ) ;
scheduler . performSeriesTasks ( ecModel ) ; // Currently dataProcessorFuncs do not check threshold.
scheduler . performDataProcessorTasks ( ecModel ) ;
updateStreamModes ( this , ecModel ) ; // Do not update coordinate system here. Because that coord system update in
// each frame is not a good user experience. So we follow the rule that
// the extent of the coordinate system is determined in the first frame (the
// frame is executed immediately after task reset.
// this._coordSysMgr.update(ecModel, api);
// console.log('--- ec frame visual ---', remainTime);
scheduler . performVisualTasks ( ecModel ) ;
renderSeries ( this , this . _ model , api , 'remain' , { } ) ;
remainTime -= + new Date ( ) - startTime ;
} while ( remainTime > 0 && scheduler . unfinished ) ; // Call flush explicitly for trigger finished event.
if ( ! scheduler . unfinished ) {
this . _ zr . flush ( ) ;
} // Else, zr flushing be ensue within the same frame,
// because zr flushing is after onframe event.
}
} ;
ECharts . prototype . getDom = function ( ) {
return this . _ dom ;
} ;
ECharts . prototype . getId = function ( ) {
return this . id ;
} ;
ECharts . prototype . getZr = function ( ) {
return this . _ zr ;
} ;
ECharts . prototype . isSSR = function ( ) {
return this . _ ssr ;
} ;
/* eslint-disable-next-line */
ECharts . prototype . setOption = function ( option , notMerge , lazyUpdate ) {
if ( this [ IN_MAIN_PROCESS_KEY ] ) {
if ( process . env . NODE_ENV !== 'production' ) {
error ( '`setOption` should not be called during main process.' ) ;
}
return ;
}
if ( this . _ disposed ) {
disposedWarning ( this . id ) ;
return ;
}
var silent ;
var replaceMerge ;
var transitionOpt ;
if ( isObject ( notMerge ) ) {
lazyUpdate = notMerge . lazyUpdate ;
silent = notMerge . silent ;
replaceMerge = notMerge . replaceMerge ;
transitionOpt = notMerge . transition ;
notMerge = notMerge . notMerge ;
}
this [ IN_MAIN_PROCESS_KEY ] = true ;
if ( ! this . _ model || notMerge ) {
var optionManager = new OptionManager ( this . _ api ) ;
var theme = this . _ theme ;
var ecModel = this . _ model = new GlobalModel ( ) ;
ecModel . scheduler = this . _ scheduler ;
ecModel . ssr = this . _ ssr ;
ecModel . init ( null , null , null , theme , this . _ locale , optionManager ) ;
}
this . _ model . setOption ( option , {
replaceMerge : replaceMerge
} , optionPreprocessorFuncs ) ;
var updateParams = {
seriesTransition : transitionOpt ,
optionChanged : true
} ;
if ( lazyUpdate ) {
this [ PENDING_UPDATE ] = {
silent : silent ,
updateParams : updateParams
} ;
this [ IN_MAIN_PROCESS_KEY ] = false ; // `setOption(option, {lazyMode: true})` may be called when zrender has been slept.
// It should wake it up to make sure zrender start to render at the next frame.
this . getZr ( ) . wakeUp ( ) ;
} else {
try {
prepare ( this ) ;
updateMethods . update . call ( this , null , updateParams ) ;
} catch ( e ) {
this [ PENDING_UPDATE ] = null ;
this [ IN_MAIN_PROCESS_KEY ] = false ;
throw e ;
} // Ensure zr refresh sychronously, and then pixel in canvas can be
// fetched after `setOption`.
if ( ! this . _ ssr ) {
// not use flush when using ssr mode.
this . _ zr . flush ( ) ;
}
this [ PENDING_UPDATE ] = null ;
this [ IN_MAIN_PROCESS_KEY ] = false ;
flushPendingActions . call ( this , silent ) ;
triggerUpdatedEvent . call ( this , silent ) ;
}
} ;
/ * *
* @ deprecated
* /
ECharts . prototype . setTheme = function ( ) {
deprecateLog ( 'ECharts#setTheme() is DEPRECATED in ECharts 3.0' ) ;
} ; // We don't want developers to use getModel directly.
ECharts . prototype . getModel = function ( ) {
return this . _ model ;
} ;
ECharts . prototype . getOption = function ( ) {
return this . _ model && this . _ model . getOption ( ) ;
} ;
ECharts . prototype . getWidth = function ( ) {
return this . _ zr . getWidth ( ) ;
} ;
ECharts . prototype . getHeight = function ( ) {
return this . _ zr . getHeight ( ) ;
} ;
ECharts . prototype . getDevicePixelRatio = function ( ) {
return this . _ zr . painter . dpr
/* eslint-disable-next-line */
|| env . hasGlobalWindow && window . devicePixelRatio || 1 ;
} ;
/ * *
* Get canvas which has all thing rendered
* @ deprecated Use renderToCanvas instead .
* /
ECharts . prototype . getRenderedCanvas = function ( opts ) {
if ( process . env . NODE_ENV !== 'production' ) {
deprecateReplaceLog ( 'getRenderedCanvas' , 'renderToCanvas' ) ;
}
return this . renderToCanvas ( opts ) ;
} ;
ECharts . prototype . renderToCanvas = function ( opts ) {
opts = opts || { } ;
var painter = this . _ zr . painter ;
if ( process . env . NODE_ENV !== 'production' ) {
if ( painter . type !== 'canvas' ) {
throw new Error ( 'renderToCanvas can only be used in the canvas renderer.' ) ;
}
}
return painter . getRenderedCanvas ( {
backgroundColor : opts . backgroundColor || this . _ model . get ( 'backgroundColor' ) ,
pixelRatio : opts . pixelRatio || this . getDevicePixelRatio ( )
} ) ;
} ;
ECharts . prototype . renderToSVGString = function ( opts ) {
opts = opts || { } ;
var painter = this . _ zr . painter ;
if ( process . env . NODE_ENV !== 'production' ) {
if ( painter . type !== 'svg' ) {
throw new Error ( 'renderToSVGString can only be used in the svg renderer.' ) ;
}
}
return painter . renderToString ( {
useViewBox : opts . useViewBox
} ) ;
} ;
/ * *
* Get svg data url
* /
ECharts . prototype . getSvgDataURL = function ( ) {
if ( ! env . svgSupported ) {
return ;
}
var zr = this . _ zr ;
var list = zr . storage . getDisplayList ( ) ; // Stop animations
each ( list , function ( el ) {
el . stopAnimation ( null , true ) ;
} ) ;
return zr . painter . toDataURL ( ) ;
} ;
ECharts . prototype . getDataURL = function ( opts ) {
if ( this . _ disposed ) {
disposedWarning ( this . id ) ;
return ;
}
opts = opts || { } ;
var excludeComponents = opts . excludeComponents ;
var ecModel = this . _ model ;
var excludesComponentViews = [ ] ;
var self = this ;
each ( excludeComponents , function ( componentType ) {
ecModel . eachComponent ( {
mainType : componentType
} , function ( component ) {
var view = self . _ componentsMap [ component . __ viewId ] ;
if ( ! view . group . ignore ) {
excludesComponentViews . push ( view ) ;
view . group . ignore = true ;
}
} ) ;
} ) ;
var url = this . _ zr . painter . getType ( ) === 'svg' ? this . getSvgDataURL ( ) : this . renderToCanvas ( opts ) . toDataURL ( 'image/' + ( opts && opts . type || 'png' ) ) ;
each ( excludesComponentViews , function ( view ) {
view . group . ignore = false ;
} ) ;
return url ;
} ;
ECharts . prototype . getConnectedDataURL = function ( opts ) {
if ( this . _ disposed ) {
disposedWarning ( this . id ) ;
return ;
}
var isSvg = opts . type === 'svg' ;
var groupId = this . group ;
var mathMin = Math . min ;
var mathMax = Math . max ;
var MAX_NUMBER = Infinity ;
if ( connectedGroups [ groupId ] ) {
var left_1 = MAX_NUMBER ;
var top_1 = MAX_NUMBER ;
var right_1 = - MAX_NUMBER ;
var bottom_1 = - MAX_NUMBER ;
var canvasList_1 = [ ] ;
var dpr_1 = opts && opts . pixelRatio || this . getDevicePixelRatio ( ) ;
each ( instances , function ( chart , id ) {
if ( chart . group === groupId ) {
var canvas = isSvg ? chart . getZr ( ) . painter . getSvgDom ( ) . innerHTML : chart . renderToCanvas ( clone ( opts ) ) ;
var boundingRect = chart . getDom ( ) . getBoundingClientRect ( ) ;
left_1 = mathMin ( boundingRect . left , left_1 ) ;
top_1 = mathMin ( boundingRect . top , top_1 ) ;
right_1 = mathMax ( boundingRect . right , right_1 ) ;
bottom_1 = mathMax ( boundingRect . bottom , bottom_1 ) ;
canvasList_1 . push ( {
dom : canvas ,
left : boundingRect . left ,
top : boundingRect . top
} ) ;
}
} ) ;
left_1 *= dpr_1 ;
top_1 *= dpr_1 ;
right_1 *= dpr_1 ;
bottom_1 *= dpr_1 ;
var width = right_1 - left_1 ;
var height = bottom_1 - top_1 ;
var targetCanvas = platformApi . createCanvas ( ) ;
var zr_1 = zrender . init ( targetCanvas , {
renderer : isSvg ? 'svg' : 'canvas'
} ) ;
zr_1 . resize ( {
width : width ,
height : height
} ) ;
if ( isSvg ) {
var content_1 = '' ;
each ( canvasList_1 , function ( item ) {
var x = item . left - left_1 ;
var y = item . top - top_1 ;
content_1 += '<g transform="translate(' + x + ',' + y + ')">' + item . dom + '</g>' ;
} ) ;
zr_1 . painter . getSvgRoot ( ) . innerHTML = content_1 ;
if ( opts . connectedBackgroundColor ) {
zr_1 . painter . setBackgroundColor ( opts . connectedBackgroundColor ) ;
}
zr_1 . refreshImmediately ( ) ;
return zr_1 . painter . toDataURL ( ) ;
} else {
// Background between the charts
if ( opts . connectedBackgroundColor ) {
zr_1 . add ( new graphic . Rect ( {
shape : {
x : 0 ,
y : 0 ,
width : width ,
height : height
} ,
style : {
fill : opts . connectedBackgroundColor
}
} ) ) ;
}
each ( canvasList_1 , function ( item ) {
var img = new graphic . Image ( {
style : {
x : item . left * dpr_1 - left_1 ,
y : item . top * dpr_1 - top_1 ,
image : item . dom
}
} ) ;
zr_1 . add ( img ) ;
} ) ;
zr_1 . refreshImmediately ( ) ;
return targetCanvas . toDataURL ( 'image/' + ( opts && opts . type || 'png' ) ) ;
}
} else {
return this . getDataURL ( opts ) ;
}
} ;
ECharts . prototype . convertToPixel = function ( finder , value ) {
return doConvertPixel ( this , 'convertToPixel' , finder , value ) ;
} ;
ECharts . prototype . convertFromPixel = function ( finder , value ) {
return doConvertPixel ( this , 'convertFromPixel' , finder , value ) ;
} ;
/ * *
* Is the specified coordinate systems or components contain the given pixel point .
* @ param { Array | number } value
* @ return { boolean } result
* /
ECharts . prototype . containPixel = function ( finder , value ) {
if ( this . _ disposed ) {
disposedWarning ( this . id ) ;
return ;
}
var ecModel = this . _ model ;
var result ;
var findResult = modelUtil . parseFinder ( ecModel , finder ) ;
each ( findResult , function ( models , key ) {
key . indexOf ( 'Models' ) >= 0 && each ( models , function ( model ) {
var coordSys = model . coordinateSystem ;
if ( coordSys && coordSys . containPoint ) {
result = result || ! ! coordSys . containPoint ( value ) ;
} else if ( key === 'seriesModels' ) {
var view = this . _ chartsMap [ model . __ viewId ] ;
if ( view && view . containPoint ) {
result = result || view . containPoint ( value , model ) ;
} else {
if ( process . env . NODE_ENV !== 'production' ) {
warn ( key + ': ' + ( view ? 'The found component do not support containPoint.' : 'No view mapping to the found component.' ) ) ;
}
}
} else {
if ( process . env . NODE_ENV !== 'production' ) {
warn ( key + ': containPoint is not supported' ) ;
}
}
} , this ) ;
} , this ) ;
return ! ! result ;
} ;
/ * *
* Get visual from series or data .
* @ param finder
* If string , e . g . , 'series' , means { seriesIndex : 0 } .
* If Object , could contain some of these properties below :
* {
* seriesIndex / seriesId / seriesName ,
* dataIndex / dataIndexInside
* }
* If dataIndex is not specified , series visual will be fetched ,
* but not data item visual .
* If all of seriesIndex , seriesId , seriesName are not specified ,
* visual will be fetched from first series .
* @ param visualType 'color' , 'symbol' , 'symbolSize'
* /
ECharts . prototype . getVisual = function ( finder , visualType ) {
var ecModel = this . _ model ;
var parsedFinder = modelUtil . parseFinder ( ecModel , finder , {
defaultMainType : 'series'
} ) ;
var seriesModel = parsedFinder . seriesModel ;
if ( process . env . NODE_ENV !== 'production' ) {
if ( ! seriesModel ) {
warn ( 'There is no specified series model' ) ;
}
}
var data = seriesModel . getData ( ) ;
var dataIndexInside = parsedFinder . hasOwnProperty ( 'dataIndexInside' ) ? parsedFinder . dataIndexInside : parsedFinder . hasOwnProperty ( 'dataIndex' ) ? data . indexOfRawIndex ( parsedFinder . dataIndex ) : null ;
return dataIndexInside != null ? getItemVisualFromData ( data , dataIndexInside , visualType ) : getVisualFromData ( data , visualType ) ;
} ;
/ * *
* Get view of corresponding component model
* /
ECharts . prototype . getViewOfComponentModel = function ( componentModel ) {
return this . _ componentsMap [ componentModel . __ viewId ] ;
} ;
/ * *
* Get view of corresponding series model
* /
ECharts . prototype . getViewOfSeriesModel = function ( seriesModel ) {
return this . _ chartsMap [ seriesModel . __ viewId ] ;
} ;
ECharts . prototype . _ initEvents = function ( ) {
var _ this = this ;
each ( MOUSE_EVENT_NAMES , function ( eveName ) {
var handler = function ( e ) {
var ecModel = _ this . getModel ( ) ;
var el = e . target ;
var params ;
var isGlobalOut = eveName === 'globalout' ; // no e.target when 'globalout'.
if ( isGlobalOut ) {
params = { } ;
} else {
el && findEventDispatcher ( el , function ( parent ) {
var ecData = getECData ( parent ) ;
if ( ecData && ecData . dataIndex != null ) {
var dataModel = ecData . dataModel || ecModel . getSeriesByIndex ( ecData . seriesIndex ) ;
params = dataModel && dataModel . getDataParams ( ecData . dataIndex , ecData . dataType , el ) || { } ;
return true ;
} // If element has custom eventData of components
else if ( ecData . eventData ) {
params = extend ( { } , ecData . eventData ) ;
return true ;
}
} , true ) ;
} // Contract: if params prepared in mouse event,
// these properties must be specified:
// {
// componentType: string (component main type)
// componentIndex: number
// }
// Otherwise event query can not work.
if ( params ) {
var componentType = params . componentType ;
var componentIndex = params . componentIndex ; // Special handling for historic reason: when trigger by
// markLine/markPoint/markArea, the componentType is
// 'markLine'/'markPoint'/'markArea', but we should better
// enable them to be queried by seriesIndex, since their
// option is set in each series.
if ( componentType === 'markLine' || componentType === 'markPoint' || componentType === 'markArea' ) {
componentType = 'series' ;
componentIndex = params . seriesIndex ;
}
var model = componentType && componentIndex != null && ecModel . getComponent ( componentType , componentIndex ) ;
var view = model && _ this [ model . mainType === 'series' ? '_chartsMap' : '_componentsMap' ] [ model . __ viewId ] ;
if ( process . env . NODE_ENV !== 'production' ) {
// `event.componentType` and `event[componentTpype + 'Index']` must not
// be missed, otherwise there is no way to distinguish source component.
// See `dataFormat.getDataParams`.
if ( ! isGlobalOut && ! ( model && view ) ) {
warn ( 'model or view can not be found by params' ) ;
}
}
params . event = e ;
params . type = eveName ;
_ this . _ $eventProcessor . eventInfo = {
targetEl : el ,
packedEvent : params ,
model : model ,
view : view
} ;
_ this . trigger ( eveName , params ) ;
}
} ; // Consider that some component (like tooltip, brush, ...)
// register zr event handler, but user event handler might
// do anything, such as call `setOption` or `dispatchAction`,
// which probably update any of the content and probably
// cause problem if it is called previous other inner handlers.
handler . zrEventfulCallAtLast = true ;
_ this . _ zr . on ( eveName , handler , _ this ) ;
} ) ;
each ( eventActionMap , function ( actionType , eventType ) {
_ this . _ messageCenter . on ( eventType , function ( event ) {
this . trigger ( eventType , event ) ;
} , _ this ) ;
} ) ; // Extra events
// TODO register?
each ( [ 'selectchanged' ] , function ( eventType ) {
_ this . _ messageCenter . on ( eventType , function ( event ) {
this . trigger ( eventType , event ) ;
} , _ this ) ;
} ) ;
handleLegacySelectEvents ( this . _ messageCenter , this , this . _ api ) ;
} ;
ECharts . prototype . isDisposed = function ( ) {
return this . _ disposed ;
} ;
ECharts . prototype . clear = function ( ) {
if ( this . _ disposed ) {
disposedWarning ( this . id ) ;
return ;
}
this . setOption ( {
series : [ ]
} , true ) ;
} ;
ECharts . prototype . dispose = function ( ) {
if ( this . _ disposed ) {
disposedWarning ( this . id ) ;
return ;
}
this . _ disposed = true ;
var dom = this . getDom ( ) ;
if ( dom ) {
modelUtil . setAttribute ( this . getDom ( ) , DOM_ATTRIBUTE_KEY , '' ) ;
}
var chart = this ;
var api = chart . _ api ;
var ecModel = chart . _ model ;
each ( chart . _ componentsViews , function ( component ) {
component . dispose ( ecModel , api ) ;
} ) ;
each ( chart . _ chartsViews , function ( chart ) {
chart . dispose ( ecModel , api ) ;
} ) ; // Dispose after all views disposed
chart . _ zr . dispose ( ) ; // Set properties to null.
// To reduce the memory cost in case the top code still holds this instance unexpectedly.
chart . _ dom = chart . _ model = chart . _ chartsMap = chart . _ componentsMap = chart . _ chartsViews = chart . _ componentsViews = chart . _ scheduler = chart . _ api = chart . _ zr = chart . _ throttledZrFlush = chart . _ theme = chart . _ coordSysMgr = chart . _ messageCenter = null ;
delete instances [ chart . id ] ;
} ;
/ * *
* Resize the chart
* /
ECharts . prototype . resize = function ( opts ) {
if ( this [ IN_MAIN_PROCESS_KEY ] ) {
if ( process . env . NODE_ENV !== 'production' ) {
error ( '`resize` should not be called during main process.' ) ;
}
return ;
}
if ( this . _ disposed ) {
disposedWarning ( this . id ) ;
return ;
}
this . _ zr . resize ( opts ) ;
var ecModel = this . _ model ; // Resize loading effect
this . _ loadingFX && this . _ loadingFX . resize ( ) ;
if ( ! ecModel ) {
return ;
}
var needPrepare = ecModel . resetOption ( 'media' ) ;
var silent = opts && opts . silent ; // There is some real cases that:
// chart.setOption(option, { lazyUpdate: true });
// chart.resize();
if ( this [ PENDING_UPDATE ] ) {
if ( silent == null ) {
silent = this [ PENDING_UPDATE ] . silent ;
}
needPrepare = true ;
this [ PENDING_UPDATE ] = null ;
}
this [ IN_MAIN_PROCESS_KEY ] = true ;
try {
needPrepare && prepare ( this ) ;
updateMethods . update . call ( this , {
type : 'resize' ,
animation : extend ( {
// Disable animation
duration : 0
} , opts && opts . animation )
} ) ;
} catch ( e ) {
this [ IN_MAIN_PROCESS_KEY ] = false ;
throw e ;
}
this [ IN_MAIN_PROCESS_KEY ] = false ;
flushPendingActions . call ( this , silent ) ;
triggerUpdatedEvent . call ( this , silent ) ;
} ;
ECharts . prototype . showLoading = function ( name , cfg ) {
if ( this . _ disposed ) {
disposedWarning ( this . id ) ;
return ;
}
if ( isObject ( name ) ) {
cfg = name ;
name = '' ;
}
name = name || 'default' ;
this . hideLoading ( ) ;
if ( ! loadingEffects [ name ] ) {
if ( process . env . NODE_ENV !== 'production' ) {
warn ( 'Loading effects ' + name + ' not exists.' ) ;
}
return ;
}
var el = loadingEffects [ name ] ( this . _ api , cfg ) ;
var zr = this . _ zr ;
this . _ loadingFX = el ;
zr . add ( el ) ;
} ;
/ * *
* Hide loading effect
* /
ECharts . prototype . hideLoading = function ( ) {
if ( this . _ disposed ) {
disposedWarning ( this . id ) ;
return ;
}
this . _ loadingFX && this . _ zr . remove ( this . _ loadingFX ) ;
this . _ loadingFX = null ;
} ;
ECharts . prototype . makeActionFromEvent = function ( eventObj ) {
var payload = extend ( { } , eventObj ) ;
payload . type = eventActionMap [ eventObj . type ] ;
return payload ;
} ;
/ * *
* @ param opt If pass boolean , means opt . silent
* @ param opt . silent Default ` false ` . Whether trigger events .
* @ param opt . flush Default ` undefined ` .
* true : Flush immediately , and then pixel in canvas can be fetched
* immediately . Caution : it might affect performance .
* false : Not flush .
* undefined : Auto decide whether perform flush .
* /
ECharts . prototype . dispatchAction = function ( payload , opt ) {
if ( this . _ disposed ) {
disposedWarning ( this . id ) ;
return ;
}
if ( ! isObject ( opt ) ) {
opt = {
silent : ! ! opt
} ;
}
if ( ! actions [ payload . type ] ) {
return ;
} // Avoid dispatch action before setOption. Especially in `connect`.
if ( ! this . _ model ) {
return ;
} // May dispatchAction in rendering procedure
if ( this [ IN_MAIN_PROCESS_KEY ] ) {
this . _ pendingActions . push ( payload ) ;
return ;
}
var silent = opt . silent ;
doDispatchAction . call ( this , payload , silent ) ;
var flush = opt . flush ;
if ( flush ) {
this . _ zr . flush ( ) ;
} else if ( flush !== false && env . browser . weChat ) {
// In WeChat embedded browser, `requestAnimationFrame` and `setInterval`
// hang when sliding page (on touch event), which cause that zr does not
// refresh until user interaction finished, which is not expected.
// But `dispatchAction` may be called too frequently when pan on touch
// screen, which impacts performance if do not throttle them.
this . _ throttledZrFlush ( ) ;
}
flushPendingActions . call ( this , silent ) ;
triggerUpdatedEvent . call ( this , silent ) ;
} ;
ECharts . prototype . updateLabelLayout = function ( ) {
lifecycle . trigger ( 'series:layoutlabels' , this . _ model , this . _ api , {
// Not adding series labels.
// TODO
updatedSeries : [ ]
} ) ;
} ;
ECharts . prototype . appendData = function ( params ) {
if ( this . _ disposed ) {
disposedWarning ( this . id ) ;
return ;
}
var seriesIndex = params . seriesIndex ;
var ecModel = this . getModel ( ) ;
var seriesModel = ecModel . getSeriesByIndex ( seriesIndex ) ;
if ( process . env . NODE_ENV !== 'production' ) {
assert ( params . data && seriesModel ) ;
}
seriesModel . appendData ( params ) ; // Note: `appendData` does not support that update extent of coordinate
// system, util some scenario require that. In the expected usage of
// `appendData`, the initial extent of coordinate system should better
// be fixed by axis `min`/`max` setting or initial data, otherwise if
// the extent changed while `appendData`, the location of the painted
// graphic elements have to be changed, which make the usage of
// `appendData` meaningless.
this . _ scheduler . unfinished = true ;
this . getZr ( ) . wakeUp ( ) ;
} ; // A work around for no `internal` modifier in ts yet but
// need to strictly hide private methods to JS users.
ECharts . internalField = function ( ) {
prepare = function ( ecIns ) {
var scheduler = ecIns . _ scheduler ;
scheduler . restorePipelines ( ecIns . _ model ) ;
scheduler . prepareStageTasks ( ) ;
prepareView ( ecIns , true ) ;
prepareView ( ecIns , false ) ;
scheduler . plan ( ) ;
} ;
/ * *
* Prepare view instances of charts and components
* /
prepareView = function ( ecIns , isComponent ) {
var ecModel = ecIns . _ model ;
var scheduler = ecIns . _ scheduler ;
var viewList = isComponent ? ecIns . _ componentsViews : ecIns . _ chartsViews ;
var viewMap = isComponent ? ecIns . _ componentsMap : ecIns . _ chartsMap ;
var zr = ecIns . _ zr ;
var api = ecIns . _ api ;
for ( var i = 0 ; i < viewList . length ; i ++ ) {
viewList [ i ] . __ alive = false ;
}
isComponent ? ecModel . eachComponent ( function ( componentType , model ) {
componentType !== 'series' && doPrepare ( model ) ;
} ) : ecModel . eachSeries ( doPrepare ) ;
function doPrepare ( model ) {
// By default view will be reused if possible for the case that `setOption` with "notMerge"
// mode and need to enable transition animation. (Usually, when they have the same id, or
// especially no id but have the same type & name & index. See the `model.id` generation
// rule in `makeIdAndName` and `viewId` generation rule here).
// But in `replaceMerge` mode, this feature should be able to disabled when it is clear that
// the new model has nothing to do with the old model.
var requireNewView = model . __ requireNewView ; // This command should not work twice.
model . __ requireNewView = false ; // Consider: id same and type changed.
var viewId = '_ec_' + model . id + '_' + model . type ;
var view = ! requireNewView && viewMap [ viewId ] ;
if ( ! view ) {
var classType = parseClassType ( model . type ) ;
var Clazz = isComponent ? ComponentView . getClass ( classType . main , classType . sub ) : // FIXME:TS
// (ChartView as ChartViewConstructor).getClass('series', classType.sub)
// For backward compat, still support a chart type declared as only subType
// like "liquidfill", but recommend "series.liquidfill"
// But need a base class to make a type series.
ChartView . getClass ( classType . sub ) ;
if ( process . env . NODE_ENV !== 'production' ) {
assert ( Clazz , classType . sub + ' does not exist.' ) ;
}
view = new Clazz ( ) ;
view . init ( ecModel , api ) ;
viewMap [ viewId ] = view ;
viewList . push ( view ) ;
zr . add ( view . group ) ;
}
model . __ viewId = view . __ id = viewId ;
view . __ alive = true ;
view . __ model = model ;
view . group . __ ecComponentInfo = {
mainType : model . mainType ,
index : model . componentIndex
} ;
! isComponent && scheduler . prepareView ( view , model , ecModel , api ) ;
}
for ( var i = 0 ; i < viewList . length ; ) {
var view = viewList [ i ] ;
if ( ! view . __ alive ) {
! isComponent && view . renderTask . dispose ( ) ;
zr . remove ( view . group ) ;
view . dispose ( ecModel , api ) ;
viewList . splice ( i , 1 ) ;
if ( viewMap [ view . __ id ] === view ) {
delete viewMap [ view . __ id ] ;
}
view . __ id = view . group . __ ecComponentInfo = null ;
} else {
i ++ ;
}
}
} ;
updateDirectly = function ( ecIns , method , payload , mainType , subType ) {
var ecModel = ecIns . _ model ;
ecModel . setUpdatePayload ( payload ) ; // broadcast
if ( ! mainType ) {
// FIXME
// Chart will not be update directly here, except set dirty.
// But there is no such scenario now.
each ( [ ] . concat ( ecIns . _ componentsViews ) . concat ( ecIns . _ chartsViews ) , callView ) ;
return ;
}
var query = { } ;
query [ mainType + 'Id' ] = payload [ mainType + 'Id' ] ;
query [ mainType + 'Index' ] = payload [ mainType + 'Index' ] ;
query [ mainType + 'Name' ] = payload [ mainType + 'Name' ] ;
var condition = {
mainType : mainType ,
query : query
} ;
subType && ( condition . subType = subType ) ; // subType may be '' by parseClassType;
var excludeSeriesId = payload . excludeSeriesId ;
var excludeSeriesIdMap ;
if ( excludeSeriesId != null ) {
excludeSeriesIdMap = createHashMap ( ) ;
each ( modelUtil . normalizeToArray ( excludeSeriesId ) , function ( id ) {
var modelId = modelUtil . convertOptionIdName ( id , null ) ;
if ( modelId != null ) {
excludeSeriesIdMap . set ( modelId , true ) ;
}
} ) ;
} // If dispatchAction before setOption, do nothing.
ecModel && ecModel . eachComponent ( condition , function ( model ) {
var isExcluded = excludeSeriesIdMap && excludeSeriesIdMap . get ( model . id ) != null ;
if ( isExcluded ) {
return ;
}
;
if ( isHighDownPayload ( payload ) ) {
if ( model instanceof SeriesModel ) {
if ( payload . type === HIGHLIGHT_ACTION_TYPE && ! payload . notBlur && ! model . get ( [ 'emphasis' , 'disabled' ] ) ) {
blurSeriesFromHighlightPayload ( model , payload , ecIns . _ api ) ;
}
} else {
var _ a = findComponentHighDownDispatchers ( model . mainType , model . componentIndex , payload . name , ecIns . _ api ) ,
focusSelf = _ a . focusSelf ,
dispatchers = _ a . dispatchers ;
if ( payload . type === HIGHLIGHT_ACTION_TYPE && focusSelf && ! payload . notBlur ) {
blurComponent ( model . mainType , model . componentIndex , ecIns . _ api ) ;
} // PENDING:
// Whether to put this "enter emphasis" code in `ComponentView`,
// which will be the same as `ChartView` but might be not necessary
// and will be far from this logic.
if ( dispatchers ) {
each ( dispatchers , function ( dispatcher ) {
payload . type === HIGHLIGHT_ACTION_TYPE ? enterEmphasis ( dispatcher ) : leaveEmphasis ( dispatcher ) ;
} ) ;
}
}
} else if ( isSelectChangePayload ( payload ) ) {
// TODO geo
if ( model instanceof SeriesModel ) {
toggleSelectionFromPayload ( model , payload , ecIns . _ api ) ;
updateSeriesElementSelection ( model ) ;
markStatusToUpdate ( ecIns ) ;
}
}
} , ecIns ) ;
ecModel && ecModel . eachComponent ( condition , function ( model ) {
var isExcluded = excludeSeriesIdMap && excludeSeriesIdMap . get ( model . id ) != null ;
if ( isExcluded ) {
return ;
}
;
callView ( ecIns [ mainType === 'series' ? '_chartsMap' : '_componentsMap' ] [ model . __ viewId ] ) ;
} , ecIns ) ;
function callView ( view ) {
view && view . __ alive && view [ method ] && view [ method ] ( view . __ model , ecModel , ecIns . _ api , payload ) ;
}
} ;
updateMethods = {
prepareAndUpdate : function ( payload ) {
prepare ( this ) ;
updateMethods . update . call ( this , payload , {
// Needs to mark option changed if newOption is given.
// It's from MagicType.
// TODO If use a separate flag optionChanged in payload?
optionChanged : payload . newOption != null
} ) ;
} ,
update : function ( payload , updateParams ) {
var ecModel = this . _ model ;
var api = this . _ api ;
var zr = this . _ zr ;
var coordSysMgr = this . _ coordSysMgr ;
var scheduler = this . _ scheduler ; // update before setOption
if ( ! ecModel ) {
return ;
}
ecModel . setUpdatePayload ( payload ) ;
scheduler . restoreData ( ecModel , payload ) ;
scheduler . performSeriesTasks ( ecModel ) ; // TODO
// Save total ecModel here for undo/redo (after restoring data and before processing data).
// Undo (restoration of total ecModel) can be carried out in 'action' or outside API call.
// Create new coordinate system each update
// In LineView may save the old coordinate system and use it to get the original point.
coordSysMgr . create ( ecModel , api ) ;
scheduler . performDataProcessorTasks ( ecModel , payload ) ; // Current stream render is not supported in data process. So we can update
// stream modes after data processing, where the filtered data is used to
// determine whether to use progressive rendering.
updateStreamModes ( this , ecModel ) ; // We update stream modes before coordinate system updated, then the modes info
// can be fetched when coord sys updating (consider the barGrid extent fix). But
// the drawback is the full coord info can not be fetched. Fortunately this full
// coord is not required in stream mode updater currently.
coordSysMgr . update ( ecModel , api ) ;
clearColorPalette ( ecModel ) ;
scheduler . performVisualTasks ( ecModel , payload ) ;
render ( this , ecModel , api , payload , updateParams ) ; // Set background
var backgroundColor = ecModel . get ( 'backgroundColor' ) || 'transparent' ;
var darkMode = ecModel . get ( 'darkMode' ) ;
zr . setBackgroundColor ( backgroundColor ) ; // Force set dark mode.
if ( darkMode != null && darkMode !== 'auto' ) {
zr . setDarkMode ( darkMode ) ;
}
lifecycle . trigger ( 'afterupdate' , ecModel , api ) ;
} ,
updateTransform : function ( payload ) {
var _ this = this ;
var ecModel = this . _ model ;
var api = this . _ api ; // update before setOption
if ( ! ecModel ) {
return ;
}
ecModel . setUpdatePayload ( payload ) ; // ChartView.markUpdateMethod(payload, 'updateTransform');
var componentDirtyList = [ ] ;
ecModel . eachComponent ( function ( componentType , componentModel ) {
if ( componentType === 'series' ) {
return ;
}
var componentView = _ this . getViewOfComponentModel ( componentModel ) ;
if ( componentView && componentView . __ alive ) {
if ( componentView . updateTransform ) {
var result = componentView . updateTransform ( componentModel , ecModel , api , payload ) ;
result && result . update && componentDirtyList . push ( componentView ) ;
} else {
componentDirtyList . push ( componentView ) ;
}
}
} ) ;
var seriesDirtyMap = createHashMap ( ) ;
ecModel . eachSeries ( function ( seriesModel ) {
var chartView = _ this . _ chartsMap [ seriesModel . __ viewId ] ;
if ( chartView . updateTransform ) {
var result = chartView . updateTransform ( seriesModel , ecModel , api , payload ) ;
result && result . update && seriesDirtyMap . set ( seriesModel . uid , 1 ) ;
} else {
seriesDirtyMap . set ( seriesModel . uid , 1 ) ;
}
} ) ;
clearColorPalette ( ecModel ) ; // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline.
// this._scheduler.performVisualTasks(ecModel, payload, 'layout', true);
this . _ scheduler . performVisualTasks ( ecModel , payload , {
setDirty : true ,
dirtyMap : seriesDirtyMap
} ) ; // Currently, not call render of components. Geo render cost a lot.
// renderComponents(ecIns, ecModel, api, payload, componentDirtyList);
renderSeries ( this , ecModel , api , payload , { } , seriesDirtyMap ) ;
lifecycle . trigger ( 'afterupdate' , ecModel , api ) ;
} ,
updateView : function ( payload ) {
var ecModel = this . _ model ; // update before setOption
if ( ! ecModel ) {
return ;
}
ecModel . setUpdatePayload ( payload ) ;
ChartView . markUpdateMethod ( payload , 'updateView' ) ;
clearColorPalette ( ecModel ) ; // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline.
this . _ scheduler . performVisualTasks ( ecModel , payload , {
setDirty : true
} ) ;
render ( this , ecModel , this . _ api , payload , { } ) ;
lifecycle . trigger ( 'afterupdate' , ecModel , this . _ api ) ;
} ,
updateVisual : function ( payload ) {
// updateMethods.update.call(this, payload);
var _ this = this ;
var ecModel = this . _ model ; // update before setOption
if ( ! ecModel ) {
return ;
}
ecModel . setUpdatePayload ( payload ) ; // clear all visual
ecModel . eachSeries ( function ( seriesModel ) {
seriesModel . getData ( ) . clearAllVisual ( ) ;
} ) ; // Perform visual
ChartView . markUpdateMethod ( payload , 'updateVisual' ) ;
clearColorPalette ( ecModel ) ; // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline.
this . _ scheduler . performVisualTasks ( ecModel , payload , {
visualType : 'visual' ,
setDirty : true
} ) ;
ecModel . eachComponent ( function ( componentType , componentModel ) {
if ( componentType !== 'series' ) {
var componentView = _ this . getViewOfComponentModel ( componentModel ) ;
componentView && componentView . __ alive && componentView . updateVisual ( componentModel , ecModel , _ this . _ api , payload ) ;
}
} ) ;
ecModel . eachSeries ( function ( seriesModel ) {
var chartView = _ this . _ chartsMap [ seriesModel . __ viewId ] ;
chartView . updateVisual ( seriesModel , ecModel , _ this . _ api , payload ) ;
} ) ;
lifecycle . trigger ( 'afterupdate' , ecModel , this . _ api ) ;
} ,
updateLayout : function ( payload ) {
updateMethods . update . call ( this , payload ) ;
}
} ;
doConvertPixel = function ( ecIns , methodName , finder , value ) {
if ( ecIns . _ disposed ) {
disposedWarning ( ecIns . id ) ;
return ;
}
var ecModel = ecIns . _ model ;
var coordSysList = ecIns . _ coordSysMgr . getCoordinateSystems ( ) ;
var result ;
var parsedFinder = modelUtil . parseFinder ( ecModel , finder ) ;
for ( var i = 0 ; i < coordSysList . length ; i ++ ) {
var coordSys = coordSysList [ i ] ;
if ( coordSys [ methodName ] && ( result = coordSys [ methodName ] ( ecModel , parsedFinder , value ) ) != null ) {
return result ;
}
}
if ( process . env . NODE_ENV !== 'production' ) {
warn ( 'No coordinate system that supports ' + methodName + ' found by the given finder.' ) ;
}
} ;
updateStreamModes = function ( ecIns , ecModel ) {
var chartsMap = ecIns . _ chartsMap ;
var scheduler = ecIns . _ scheduler ;
ecModel . eachSeries ( function ( seriesModel ) {
scheduler . updateStreamModes ( seriesModel , chartsMap [ seriesModel . __ viewId ] ) ;
} ) ;
} ;
doDispatchAction = function ( payload , silent ) {
var _ this = this ;
var ecModel = this . getModel ( ) ;
var payloadType = payload . type ;
var escapeConnect = payload . escapeConnect ;
var actionWrap = actions [ payloadType ] ;
var actionInfo = actionWrap . actionInfo ;
var cptTypeTmp = ( actionInfo . update || 'update' ) . split ( ':' ) ;
var updateMethod = cptTypeTmp . pop ( ) ;
var cptType = cptTypeTmp [ 0 ] != null && parseClassType ( cptTypeTmp [ 0 ] ) ;
this [ IN_MAIN_PROCESS_KEY ] = true ;
var payloads = [ payload ] ;
var batched = false ; // Batch action
if ( payload . batch ) {
batched = true ;
payloads = map ( payload . batch , function ( item ) {
item = defaults ( extend ( { } , item ) , payload ) ;
item . batch = null ;
return item ;
} ) ;
}
var eventObjBatch = [ ] ;
var eventObj ;
var isSelectChange = isSelectChangePayload ( payload ) ;
var isHighDown = isHighDownPayload ( payload ) ; // Only leave blur once if there are multiple batches.
if ( isHighDown ) {
allLeaveBlur ( this . _ api ) ;
}
each ( payloads , function ( batchItem ) {
// Action can specify the event by return it.
eventObj = actionWrap . action ( batchItem , _ this . _ model , _ this . _ api ) ; // Emit event outside
eventObj = eventObj || extend ( { } , batchItem ) ; // Convert type to eventType
eventObj . type = actionInfo . event || eventObj . type ;
eventObjBatch . push ( eventObj ) ; // light update does not perform data process, layout and visual.
if ( isHighDown ) {
var _ a = modelUtil . preParseFinder ( payload ) ,
queryOptionMap = _ a . queryOptionMap ,
mainTypeSpecified = _ a . mainTypeSpecified ;
var componentMainType = mainTypeSpecified ? queryOptionMap . keys ( ) [ 0 ] : 'series' ;
updateDirectly ( _ this , updateMethod , batchItem , componentMainType ) ;
markStatusToUpdate ( _ this ) ;
} else if ( isSelectChange ) {
// At present `dispatchAction({ type: 'select', ... })` is not supported on components.
// geo still use 'geoselect'.
updateDirectly ( _ this , updateMethod , batchItem , 'series' ) ;
markStatusToUpdate ( _ this ) ;
} else if ( cptType ) {
updateDirectly ( _ this , updateMethod , batchItem , cptType . main , cptType . sub ) ;
}
} ) ;
if ( updateMethod !== 'none' && ! isHighDown && ! isSelectChange && ! cptType ) {
try {
// Still dirty
if ( this [ PENDING_UPDATE ] ) {
prepare ( this ) ;
updateMethods . update . call ( this , payload ) ;
this [ PENDING_UPDATE ] = null ;
} else {
updateMethods [ updateMethod ] . call ( this , payload ) ;
}
} catch ( e ) {
this [ IN_MAIN_PROCESS_KEY ] = false ;
throw e ;
}
} // Follow the rule of action batch
if ( batched ) {
eventObj = {
type : actionInfo . event || payloadType ,
escapeConnect : escapeConnect ,
batch : eventObjBatch
} ;
} else {
eventObj = eventObjBatch [ 0 ] ;
}
this [ IN_MAIN_PROCESS_KEY ] = false ;
if ( ! silent ) {
var messageCenter = this . _ messageCenter ;
messageCenter . trigger ( eventObj . type , eventObj ) ; // Extra triggered 'selectchanged' event
if ( isSelectChange ) {
var newObj = {
type : 'selectchanged' ,
escapeConnect : escapeConnect ,
selected : getAllSelectedIndices ( ecModel ) ,
isFromClick : payload . isFromClick || false ,
fromAction : payload . type ,
fromActionPayload : payload
} ;
messageCenter . trigger ( newObj . type , newObj ) ;
}
}
} ;
flushPendingActions = function ( silent ) {
var pendingActions = this . _ pendingActions ;
while ( pendingActions . length ) {
var payload = pendingActions . shift ( ) ;
doDispatchAction . call ( this , payload , silent ) ;
}
} ;
triggerUpdatedEvent = function ( silent ) {
! silent && this . trigger ( 'updated' ) ;
} ;
/ * *
* Event ` rendered ` is triggered when zr
* rendered . It is useful for realtime
* snapshot ( reflect animation ) .
*
* Event ` finished ` is triggered when :
* ( 1 ) zrender rendering finished .
* ( 2 ) initial animation finished .
* ( 3 ) progressive rendering finished .
* ( 4 ) no pending action .
* ( 5 ) no delayed setOption needs to be processed .
* /
bindRenderedEvent = function ( zr , ecIns ) {
zr . on ( 'rendered' , function ( params ) {
ecIns . trigger ( 'rendered' , params ) ; // The `finished` event should not be triggered repeatedly,
// so it should only be triggered when rendering indeed happens
// in zrender. (Consider the case that dipatchAction is keep
// triggering when mouse move).
if ( // Although zr is dirty if initial animation is not finished
// and this checking is called on frame, we also check
// animation finished for robustness.
zr . animation . isFinished ( ) && ! ecIns [ PENDING_UPDATE ] && ! ecIns . _ scheduler . unfinished && ! ecIns . _ pendingActions . length ) {
ecIns . trigger ( 'finished' ) ;
}
} ) ;
} ;
bindMouseEvent = function ( zr , ecIns ) {
zr . on ( 'mouseover' , function ( e ) {
var el = e . target ;
var dispatcher = findEventDispatcher ( el , isHighDownDispatcher ) ;
if ( dispatcher ) {
handleGlobalMouseOverForHighDown ( dispatcher , e , ecIns . _ api ) ;
markStatusToUpdate ( ecIns ) ;
}
} ) . on ( 'mouseout' , function ( e ) {
var el = e . target ;
var dispatcher = findEventDispatcher ( el , isHighDownDispatcher ) ;
if ( dispatcher ) {
handleGlobalMouseOutForHighDown ( dispatcher , e , ecIns . _ api ) ;
markStatusToUpdate ( ecIns ) ;
}
} ) . on ( 'click' , function ( e ) {
var el = e . target ;
var dispatcher = findEventDispatcher ( el , function ( target ) {
return getECData ( target ) . dataIndex != null ;
} , true ) ;
if ( dispatcher ) {
var actionType = dispatcher . selected ? 'unselect' : 'select' ;
var ecData = getECData ( dispatcher ) ;
ecIns . _ api . dispatchAction ( {
type : actionType ,
dataType : ecData . dataType ,
dataIndexInside : ecData . dataIndex ,
seriesIndex : ecData . seriesIndex ,
isFromClick : true
} ) ;
}
} ) ;
} ;
function clearColorPalette ( ecModel ) {
ecModel . clearColorPalette ( ) ;
ecModel . eachSeries ( function ( seriesModel ) {
seriesModel . clearColorPalette ( ) ;
} ) ;
}
; // Allocate zlevels for series and components
function allocateZlevels ( ecModel ) {
;
var componentZLevels = [ ] ;
var seriesZLevels = [ ] ;
var hasSeperateZLevel = false ;
ecModel . eachComponent ( function ( componentType , componentModel ) {
var zlevel = componentModel . get ( 'zlevel' ) || 0 ;
var z = componentModel . get ( 'z' ) || 0 ;
var zlevelKey = componentModel . getZLevelKey ( ) ;
hasSeperateZLevel = hasSeperateZLevel || ! ! zlevelKey ;
( componentType === 'series' ? seriesZLevels : componentZLevels ) . push ( {
zlevel : zlevel ,
z : z ,
idx : componentModel . componentIndex ,
type : componentType ,
key : zlevelKey
} ) ;
} ) ;
if ( hasSeperateZLevel ) {
// Series after component
var zLevels = componentZLevels . concat ( seriesZLevels ) ;
var lastSeriesZLevel_1 ;
var lastSeriesKey_1 ;
timsort ( zLevels , function ( a , b ) {
if ( a . zlevel === b . zlevel ) {
return a . z - b . z ;
}
return a . zlevel - b . zlevel ;
} ) ;
each ( zLevels , function ( item ) {
var componentModel = ecModel . getComponent ( item . type , item . idx ) ;
var zlevel = item . zlevel ;
var key = item . key ;
if ( lastSeriesZLevel_1 != null ) {
zlevel = Math . max ( lastSeriesZLevel_1 , zlevel ) ;
}
if ( key ) {
if ( zlevel === lastSeriesZLevel_1 && key !== lastSeriesKey_1 ) {
zlevel ++ ;
}
lastSeriesKey_1 = key ;
} else if ( lastSeriesKey_1 ) {
if ( zlevel === lastSeriesZLevel_1 ) {
zlevel ++ ;
}
lastSeriesKey_1 = '' ;
}
lastSeriesZLevel_1 = zlevel ;
componentModel . setZLevel ( zlevel ) ;
} ) ;
}
}
render = function ( ecIns , ecModel , api , payload , updateParams ) {
allocateZlevels ( ecModel ) ;
renderComponents ( ecIns , ecModel , api , payload , updateParams ) ;
each ( ecIns . _ chartsViews , function ( chart ) {
chart . __ alive = false ;
} ) ;
renderSeries ( ecIns , ecModel , api , payload , updateParams ) ; // Remove groups of unrendered charts
each ( ecIns . _ chartsViews , function ( chart ) {
if ( ! chart . __ alive ) {
chart . remove ( ecModel , api ) ;
}
} ) ;
} ;
renderComponents = function ( ecIns , ecModel , api , payload , updateParams , dirtyList ) {
each ( dirtyList || ecIns . _ componentsViews , function ( componentView ) {
var componentModel = componentView . __ model ;
clearStates ( componentModel , componentView ) ;
componentView . render ( componentModel , ecModel , api , payload ) ;
updateZ ( componentModel , componentView ) ;
updateStates ( componentModel , componentView ) ;
} ) ;
} ;
/ * *
* Render each chart and component
* /
renderSeries = function ( ecIns , ecModel , api , payload , updateParams , dirtyMap ) {
// Render all charts
var scheduler = ecIns . _ scheduler ;
updateParams = extend ( updateParams || { } , {
updatedSeries : ecModel . getSeries ( )
} ) ; // TODO progressive?
lifecycle . trigger ( 'series:beforeupdate' , ecModel , api , updateParams ) ;
var unfinished = false ;
ecModel . eachSeries ( function ( seriesModel ) {
var chartView = ecIns . _ chartsMap [ seriesModel . __ viewId ] ;
chartView . __ alive = true ;
var renderTask = chartView . renderTask ;
scheduler . updatePayload ( renderTask , payload ) ; // TODO states on marker.
clearStates ( seriesModel , chartView ) ;
if ( dirtyMap && dirtyMap . get ( seriesModel . uid ) ) {
renderTask . dirty ( ) ;
}
if ( renderTask . perform ( scheduler . getPerformArgs ( renderTask ) ) ) {
unfinished = true ;
}
chartView . group . silent = ! ! seriesModel . get ( 'silent' ) ; // Should not call markRedraw on group, because it will disable zrender
// incremental render (always render from the __startIndex each frame)
// chartView.group.markRedraw();
updateBlend ( seriesModel , chartView ) ;
updateSeriesElementSelection ( seriesModel ) ;
} ) ;
scheduler . unfinished = unfinished || scheduler . unfinished ;
lifecycle . trigger ( 'series:layoutlabels' , ecModel , api , updateParams ) ; // transition after label is layouted.
lifecycle . trigger ( 'series:transition' , ecModel , api , updateParams ) ;
ecModel . eachSeries ( function ( seriesModel ) {
var chartView = ecIns . _ chartsMap [ seriesModel . __ viewId ] ; // Update Z after labels updated. Before applying states.
updateZ ( seriesModel , chartView ) ; // NOTE: Update states after label is updated.
// label should be in normal status when layouting.
updateStates ( seriesModel , chartView ) ;
} ) ; // If use hover layer
updateHoverLayerStatus ( ecIns , ecModel ) ;
lifecycle . trigger ( 'series:afterupdate' , ecModel , api , updateParams ) ;
} ;
markStatusToUpdate = function ( ecIns ) {
ecIns [ STATUS_NEEDS_UPDATE_KEY ] = true ; // Wake up zrender if it's sleep. Let it update states in the next frame.
ecIns . getZr ( ) . wakeUp ( ) ;
} ;
applyChangedStates = function ( ecIns ) {
if ( ! ecIns [ STATUS_NEEDS_UPDATE_KEY ] ) {
return ;
}
ecIns . getZr ( ) . storage . traverse ( function ( el ) {
// Not applied on removed elements, it may still in fading.
if ( graphic . isElementRemoved ( el ) ) {
return ;
}
applyElementStates ( el ) ;
} ) ;
ecIns [ STATUS_NEEDS_UPDATE_KEY ] = false ;
} ;
function applyElementStates ( el ) {
var newStates = [ ] ;
var oldStates = el . currentStates ; // Keep other states.
for ( var i = 0 ; i < oldStates . length ; i ++ ) {
var stateName = oldStates [ i ] ;
if ( ! ( stateName === 'emphasis' || stateName === 'blur' || stateName === 'select' ) ) {
newStates . push ( stateName ) ;
}
} // Only use states when it's exists.
if ( el . selected && el . states . select ) {
newStates . push ( 'select' ) ;
}
if ( el . hoverState === HOVER_STATE_EMPHASIS && el . states . emphasis ) {
newStates . push ( 'emphasis' ) ;
} else if ( el . hoverState === HOVER_STATE_BLUR && el . states . blur ) {
newStates . push ( 'blur' ) ;
}
el . useStates ( newStates ) ;
}
function updateHoverLayerStatus ( ecIns , ecModel ) {
var zr = ecIns . _ zr ;
var storage = zr . storage ;
var elCount = 0 ;
storage . traverse ( function ( el ) {
if ( ! el . isGroup ) {
elCount ++ ;
}
} ) ;
if ( elCount > ecModel . get ( 'hoverLayerThreshold' ) && ! env . node && ! env . worker ) {
ecModel . eachSeries ( function ( seriesModel ) {
if ( seriesModel . preventUsingHoverLayer ) {
return ;
}
var chartView = ecIns . _ chartsMap [ seriesModel . __ viewId ] ;
if ( chartView . __ alive ) {
chartView . eachRendered ( function ( el ) {
if ( el . states . emphasis ) {
el . states . emphasis . hoverLayer = true ;
}
} ) ;
}
} ) ;
}
}
;
/ * *
* Update chart and blend .
* /
function updateBlend ( seriesModel , chartView ) {
var blendMode = seriesModel . get ( 'blendMode' ) || null ;
chartView . eachRendered ( function ( el ) {
// FIXME marker and other components
if ( ! el . isGroup ) {
// DON'T mark the element dirty. In case element is incremental and don't want to rerender.
el . style . blend = blendMode ;
}
} ) ;
}
;
function updateZ ( model , view ) {
if ( model . preventAutoZ ) {
return ;
}
var z = model . get ( 'z' ) || 0 ;
var zlevel = model . get ( 'zlevel' ) || 0 ; // Set z and zlevel
view . eachRendered ( function ( el ) {
doUpdateZ ( el , z , zlevel , - Infinity ) ; // Don't traverse the children because it has been traversed in _updateZ.
return true ;
} ) ;
}
;
function doUpdateZ ( el , z , zlevel , maxZ2 ) {
// Group may also have textContent
var label = el . getTextContent ( ) ;
var labelLine = el . getTextGuideLine ( ) ;
var isGroup = el . isGroup ;
if ( isGroup ) {
// set z & zlevel of children elements of Group
var children = el . childrenRef ( ) ;
for ( var i = 0 ; i < children . length ; i ++ ) {
maxZ2 = Math . max ( doUpdateZ ( children [ i ] , z , zlevel , maxZ2 ) , maxZ2 ) ;
}
} else {
// not Group
el . z = z ;
el . zlevel = zlevel ;
maxZ2 = Math . max ( el . z2 , maxZ2 ) ;
} // always set z and zlevel if label/labelLine exists
if ( label ) {
label . z = z ;
label . zlevel = zlevel ; // lift z2 of text content
// TODO if el.emphasis.z2 is spcefied, what about textContent.
isFinite ( maxZ2 ) && ( label . z2 = maxZ2 + 2 ) ;
}
if ( labelLine ) {
var textGuideLineConfig = el . textGuideLineConfig ;
labelLine . z = z ;
labelLine . zlevel = zlevel ;
isFinite ( maxZ2 ) && ( labelLine . z2 = maxZ2 + ( textGuideLineConfig && textGuideLineConfig . showAbove ? 1 : - 1 ) ) ;
}
return maxZ2 ;
} // Clear states without animation.
// TODO States on component.
function clearStates ( model , view ) {
view . eachRendered ( function ( el ) {
// Not applied on removed elements, it may still in fading.
if ( graphic . isElementRemoved ( el ) ) {
return ;
}
var textContent = el . getTextContent ( ) ;
var textGuide = el . getTextGuideLine ( ) ;
if ( el . stateTransition ) {
el . stateTransition = null ;
}
if ( textContent && textContent . stateTransition ) {
textContent . stateTransition = null ;
}
if ( textGuide && textGuide . stateTransition ) {
textGuide . stateTransition = null ;
} // TODO If el is incremental.
if ( el . hasState ( ) ) {
el . prevStates = el . currentStates ;
el . clearStates ( ) ;
} else if ( el . prevStates ) {
el . prevStates = null ;
}
} ) ;
}
function updateStates ( model , view ) {
var stateAnimationModel = model . getModel ( 'stateAnimation' ) ;
var enableAnimation = model . isAnimationEnabled ( ) ;
var duration = stateAnimationModel . get ( 'duration' ) ;
var stateTransition = duration > 0 ? {
duration : duration ,
delay : stateAnimationModel . get ( 'delay' ) ,
easing : stateAnimationModel . get ( 'easing' ) // additive: stateAnimationModel.get('additive')
} : null ;
view . eachRendered ( function ( el ) {
if ( el . states && el . states . emphasis ) {
// Not applied on removed elements, it may still in fading.
if ( graphic . isElementRemoved ( el ) ) {
return ;
}
if ( el instanceof graphic . Path ) {
savePathStates ( el ) ;
} // Only updated on changed element. In case element is incremental and don't want to rerender.
// TODO, a more proper way?
if ( el . __ dirty ) {
var prevStates = el . prevStates ; // Restore states without animation
if ( prevStates ) {
el . useStates ( prevStates ) ;
}
} // Update state transition and enable animation again.
if ( enableAnimation ) {
el . stateTransition = stateTransition ;
var textContent = el . getTextContent ( ) ;
var textGuide = el . getTextGuideLine ( ) ; // TODO Is it necessary to animate label?
if ( textContent ) {
textContent . stateTransition = stateTransition ;
}
if ( textGuide ) {
textGuide . stateTransition = stateTransition ;
}
} // Use highlighted and selected flag to toggle states.
if ( el . __ dirty ) {
applyElementStates ( el ) ;
}
}
} ) ;
}
;
createExtensionAPI = function ( ecIns ) {
return new (
/** @class */
function ( _ super ) {
__ extends ( class_1 , _ super ) ;
function class_1 ( ) {
return _ super !== null && _ super . apply ( this , arguments ) || this ;
}
class_1 . prototype . getCoordinateSystems = function ( ) {
return ecIns . _ coordSysMgr . getCoordinateSystems ( ) ;
} ;
class_1 . prototype . getComponentByElement = function ( el ) {
while ( el ) {
var modelInfo = el . __ ecComponentInfo ;
if ( modelInfo != null ) {
return ecIns . _ model . getComponent ( modelInfo . mainType , modelInfo . index ) ;
}
el = el . parent ;
}
} ;
class_1 . prototype . enterEmphasis = function ( el , highlightDigit ) {
enterEmphasis ( el , highlightDigit ) ;
markStatusToUpdate ( ecIns ) ;
} ;
class_1 . prototype . leaveEmphasis = function ( el , highlightDigit ) {
leaveEmphasis ( el , highlightDigit ) ;
markStatusToUpdate ( ecIns ) ;
} ;
class_1 . prototype . enterBlur = function ( el ) {
enterBlur ( el ) ;
markStatusToUpdate ( ecIns ) ;
} ;
class_1 . prototype . leaveBlur = function ( el ) {
leaveBlur ( el ) ;
markStatusToUpdate ( ecIns ) ;
} ;
class_1 . prototype . enterSelect = function ( el ) {
enterSelect ( el ) ;
markStatusToUpdate ( ecIns ) ;
} ;
class_1 . prototype . leaveSelect = function ( el ) {
leaveSelect ( el ) ;
markStatusToUpdate ( ecIns ) ;
} ;
class_1 . prototype . getModel = function ( ) {
return ecIns . getModel ( ) ;
} ;
class_1 . prototype . getViewOfComponentModel = function ( componentModel ) {
return ecIns . getViewOfComponentModel ( componentModel ) ;
} ;
class_1 . prototype . getViewOfSeriesModel = function ( seriesModel ) {
return ecIns . getViewOfSeriesModel ( seriesModel ) ;
} ;
return class_1 ;
} ( ExtensionAPI ) ) ( ecIns ) ;
} ;
enableConnect = function ( chart ) {
function updateConnectedChartsStatus ( charts , status ) {
for ( var i = 0 ; i < charts . length ; i ++ ) {
var otherChart = charts [ i ] ;
otherChart [ CONNECT_STATUS_KEY ] = status ;
}
}
each ( eventActionMap , function ( actionType , eventType ) {
chart . _ messageCenter . on ( eventType , function ( event ) {
if ( connectedGroups [ chart . group ] && chart [ CONNECT_STATUS_KEY ] !== CONNECT_STATUS_PENDING ) {
if ( event && event . escapeConnect ) {
return ;
}
var action_1 = chart . makeActionFromEvent ( event ) ;
var otherCharts_1 = [ ] ;
each ( instances , function ( otherChart ) {
if ( otherChart !== chart && otherChart . group === chart . group ) {
otherCharts_1 . push ( otherChart ) ;
}
} ) ;
updateConnectedChartsStatus ( otherCharts_1 , CONNECT_STATUS_PENDING ) ;
each ( otherCharts_1 , function ( otherChart ) {
if ( otherChart [ CONNECT_STATUS_KEY ] !== CONNECT_STATUS_UPDATING ) {
otherChart . dispatchAction ( action_1 ) ;
}
} ) ;
updateConnectedChartsStatus ( otherCharts_1 , CONNECT_STATUS_UPDATED ) ;
}
} ) ;
} ) ;
} ;
} ( ) ;
return ECharts ;
} ( Eventful ) ;
var echartsProto = ECharts . prototype ;
echartsProto . on = createRegisterEventWithLowercaseECharts ( 'on' ) ;
echartsProto . off = createRegisterEventWithLowercaseECharts ( 'off' ) ;
/ * *
* @ deprecated
* /
// @ts-ignore
echartsProto . one = function ( eventName , cb , ctx ) {
var self = this ;
deprecateLog ( 'ECharts#one is deprecated.' ) ;
function wrapped ( ) {
var args2 = [ ] ;
for ( var _ i = 0 ; _ i < arguments . length ; _ i ++ ) {
args2 [ _ i ] = arguments [ _ i ] ;
}
cb && cb . apply && cb . apply ( this , args2 ) ; // @ts-ignore
self . off ( eventName , wrapped ) ;
}
; // @ts-ignore
this . on . call ( this , eventName , wrapped , ctx ) ;
} ;
var MOUSE_EVENT_NAMES = [ 'click' , 'dblclick' , 'mouseover' , 'mouseout' , 'mousemove' , 'mousedown' , 'mouseup' , 'globalout' , 'contextmenu' ] ;
function disposedWarning ( id ) {
if ( process . env . NODE_ENV !== 'production' ) {
warn ( 'Instance ' + id + ' has been disposed' ) ;
}
}
var actions = { } ;
/ * *
* Map eventType to actionType
* /
var eventActionMap = { } ;
var dataProcessorFuncs = [ ] ;
var optionPreprocessorFuncs = [ ] ;
var visualFuncs = [ ] ;
var themeStorage = { } ;
var loadingEffects = { } ;
var instances = { } ;
var connectedGroups = { } ;
var idBase = + new Date ( ) - 0 ;
var groupIdBase = + new Date ( ) - 0 ;
var DOM_ATTRIBUTE_KEY = '_echarts_instance_' ;
/ * *
* @ param opts . devicePixelRatio Use window . devicePixelRatio by default
* @ param opts . renderer Can choose 'canvas' or 'svg' to render the chart .
* @ param opts . width Use clientWidth of the input ` dom ` by default .
* Can be 'auto' ( the same as null / undefined )
* @ param opts . height Use clientHeight of the input ` dom ` by default .
* Can be 'auto' ( the same as null / undefined )
* @ param opts . locale Specify the locale .
* @ param opts . useDirtyRect Enable dirty rectangle rendering or not .
* /
export function init ( dom , theme , opts ) {
var isClient = ! ( opts && opts . ssr ) ;
if ( isClient ) {
if ( process . env . NODE_ENV !== 'production' ) {
if ( ! dom ) {
throw new Error ( 'Initialize failed: invalid dom.' ) ;
}
}
var existInstance = getInstanceByDom ( dom ) ;
if ( existInstance ) {
if ( process . env . NODE_ENV !== 'production' ) {
warn ( 'There is a chart instance already initialized on the dom.' ) ;
}
return existInstance ;
}
if ( process . env . NODE_ENV !== 'production' ) {
if ( isDom ( dom ) && dom . nodeName . toUpperCase ( ) !== 'CANVAS' && ( ! dom . clientWidth && ( ! opts || opts . width == null ) || ! dom . clientHeight && ( ! opts || opts . height == null ) ) ) {
warn ( 'Can\'t get DOM width or height. Please check ' + 'dom.clientWidth and dom.clientHeight. They should not be 0.' + 'For example, you may need to call this in the callback ' + 'of window.onload.' ) ;
}
}
}
var chart = new ECharts ( dom , theme , opts ) ;
chart . id = 'ec_' + idBase ++ ;
instances [ chart . id ] = chart ;
isClient && modelUtil . setAttribute ( dom , DOM_ATTRIBUTE_KEY , chart . id ) ;
enableConnect ( chart ) ;
lifecycle . trigger ( 'afterinit' , chart ) ;
return chart ;
}
/ * *
* @ usage
* ( A )
* ` ` ` js
* let chart1 = echarts . init ( dom1 ) ;
* let chart2 = echarts . init ( dom2 ) ;
* chart1 . group = 'xxx' ;
* chart2 . group = 'xxx' ;
* echarts . connect ( 'xxx' ) ;
* ` ` `
* ( B )
* ` ` ` js
* let chart1 = echarts . init ( dom1 ) ;
* let chart2 = echarts . init ( dom2 ) ;
* echarts . connect ( 'xxx' , [ chart1 , chart2 ] ) ;
* ` ` `
* /
export function connect ( groupId ) {
// Is array of charts
if ( isArray ( groupId ) ) {
var charts = groupId ;
groupId = null ; // If any chart has group
each ( charts , function ( chart ) {
if ( chart . group != null ) {
groupId = chart . group ;
}
} ) ;
groupId = groupId || 'g_' + groupIdBase ++ ;
each ( charts , function ( chart ) {
chart . group = groupId ;
} ) ;
}
connectedGroups [ groupId ] = true ;
return groupId ;
}
export function disconnect ( groupId ) {
connectedGroups [ groupId ] = false ;
}
/ * *
* Alias and backward compatibility
* @ deprecated
* /
export var disConnect = disconnect ;
/ * *
* Dispose a chart instance
* /
export function dispose ( chart ) {
if ( isString ( chart ) ) {
chart = instances [ chart ] ;
} else if ( ! ( chart instanceof ECharts ) ) {
// Try to treat as dom
chart = getInstanceByDom ( chart ) ;
}
if ( chart instanceof ECharts && ! chart . isDisposed ( ) ) {
chart . dispose ( ) ;
}
}
export function getInstanceByDom ( dom ) {
return instances [ modelUtil . getAttribute ( dom , DOM_ATTRIBUTE_KEY ) ] ;
}
export function getInstanceById ( key ) {
return instances [ key ] ;
}
/ * *
* Register theme
* /
export function registerTheme ( name , theme ) {
themeStorage [ name ] = theme ;
}
/ * *
* Register option preprocessor
* /
export function registerPreprocessor ( preprocessorFunc ) {
if ( indexOf ( optionPreprocessorFuncs , preprocessorFunc ) < 0 ) {
optionPreprocessorFuncs . push ( preprocessorFunc ) ;
}
}
export function registerProcessor ( priority , processor ) {
normalizeRegister ( dataProcessorFuncs , priority , processor , PRIORITY_PROCESSOR_DEFAULT ) ;
}
/ * *
* Register postIniter
* @ param { Function } postInitFunc
* /
export function registerPostInit ( postInitFunc ) {
registerUpdateLifecycle ( 'afterinit' , postInitFunc ) ;
}
/ * *
* Register postUpdater
* @ param { Function } postUpdateFunc
* /
export function registerPostUpdate ( postUpdateFunc ) {
registerUpdateLifecycle ( 'afterupdate' , postUpdateFunc ) ;
}
export function registerUpdateLifecycle ( name , cb ) {
lifecycle . on ( name , cb ) ;
}
export function registerAction ( actionInfo , eventName , action ) {
if ( isFunction ( eventName ) ) {
action = eventName ;
eventName = '' ;
}
var actionType = isObject ( actionInfo ) ? actionInfo . type : [ actionInfo , actionInfo = {
event : eventName
} ] [ 0 ] ; // Event name is all lowercase
actionInfo . event = ( actionInfo . event || actionType ) . toLowerCase ( ) ;
eventName = actionInfo . event ;
if ( eventActionMap [ eventName ] ) {
// Already registered.
return ;
} // Validate action type and event name.
assert ( ACTION_REG . test ( actionType ) && ACTION_REG . test ( eventName ) ) ;
if ( ! actions [ actionType ] ) {
actions [ actionType ] = {
action : action ,
actionInfo : actionInfo
} ;
}
eventActionMap [ eventName ] = actionType ;
}
export function registerCoordinateSystem ( type , coordSysCreator ) {
CoordinateSystemManager . register ( type , coordSysCreator ) ;
}
/ * *
* Get dimensions of specified coordinate system .
* @ param { string } type
* @ return { Array . < string | Object > }
* /
export function getCoordinateSystemDimensions ( type ) {
var coordSysCreator = CoordinateSystemManager . get ( type ) ;
if ( coordSysCreator ) {
return coordSysCreator . getDimensionsInfo ? coordSysCreator . getDimensionsInfo ( ) : coordSysCreator . dimensions . slice ( ) ;
}
}
export { registerLocale } from './locale.js' ;
function registerLayout ( priority , layoutTask ) {
normalizeRegister ( visualFuncs , priority , layoutTask , PRIORITY_VISUAL_LAYOUT , 'layout' ) ;
}
function registerVisual ( priority , visualTask ) {
normalizeRegister ( visualFuncs , priority , visualTask , PRIORITY_VISUAL_CHART , 'visual' ) ;
}
export { registerLayout , registerVisual } ;
var registeredTasks = [ ] ;
function normalizeRegister ( targetList , priority , fn , defaultPriority , visualType ) {
if ( isFunction ( priority ) || isObject ( priority ) ) {
fn = priority ;
priority = defaultPriority ;
}
if ( process . env . NODE_ENV !== 'production' ) {
if ( isNaN ( priority ) || priority == null ) {
throw new Error ( 'Illegal priority' ) ;
} // Check duplicate
each ( targetList , function ( wrap ) {
assert ( wrap . __ raw !== fn ) ;
} ) ;
} // Already registered
if ( indexOf ( registeredTasks , fn ) >= 0 ) {
return ;
}
registeredTasks . push ( fn ) ;
var stageHandler = Scheduler . wrapStageHandler ( fn , visualType ) ;
stageHandler . __ prio = priority ;
stageHandler . __ raw = fn ;
targetList . push ( stageHandler ) ;
}
export function registerLoading ( name , loadingFx ) {
loadingEffects [ name ] = loadingFx ;
}
/ * *
* ZRender need a canvas context to do measureText .
* But in node environment canvas may be created by node - canvas .
* So we need to specify how to create a canvas instead of using document . createElement ( 'canvas' )
*
*
* @ deprecated use setPlatformAPI ( { createCanvas } ) instead .
*
* @ example
* let Canvas = require ( 'canvas' ) ;
* let echarts = require ( 'echarts' ) ;
* echarts . setCanvasCreator ( function ( ) {
* // Small size is enough.
* return new Canvas ( 32 , 32 ) ;
* } ) ;
* /
export function setCanvasCreator ( creator ) {
if ( process . env . NODE_ENV !== 'production' ) {
deprecateLog ( 'setCanvasCreator is deprecated. Use setPlatformAPI({ createCanvas }) instead.' ) ;
}
setPlatformAPI ( {
createCanvas : creator
} ) ;
}
/ * *
* The parameters and usage : see ` geoSourceManager.registerMap ` .
* Compatible with previous ` echarts.registerMap ` .
* /
export function registerMap ( mapName , geoJson , specialAreas ) {
var registerMap = getImpl ( 'registerMap' ) ;
registerMap && registerMap ( mapName , geoJson , specialAreas ) ;
}
export function getMap ( mapName ) {
var getMap = getImpl ( 'getMap' ) ;
return getMap && getMap ( mapName ) ;
}
export var registerTransform = registerExternalTransform ;
/ * *
* Globa dispatchAction to a specified chart instance .
* /
// export function dispatchAction(payload: { chartId: string } & Payload, opt?: Parameters<ECharts['dispatchAction']>[1]) {
// if (!payload || !payload.chartId) {
// // Must have chartId to find chart
// return;
// }
// const chart = instances[payload.chartId];
// if (chart) {
// chart.dispatchAction(payload, opt);
// }
// }
// Builtin global visual
registerVisual ( PRIORITY_VISUAL_GLOBAL , seriesStyleTask ) ;
registerVisual ( PRIORITY_VISUAL_CHART_DATA_CUSTOM , dataStyleTask ) ;
registerVisual ( PRIORITY_VISUAL_CHART_DATA_CUSTOM , dataColorPaletteTask ) ;
registerVisual ( PRIORITY_VISUAL_GLOBAL , seriesSymbolTask ) ;
registerVisual ( PRIORITY_VISUAL_CHART_DATA_CUSTOM , dataSymbolTask ) ;
registerVisual ( PRIORITY_VISUAL_DECAL , decal ) ;
registerPreprocessor ( backwardCompat ) ;
registerProcessor ( PRIORITY_PROCESSOR_DATASTACK , dataStack ) ;
registerLoading ( 'default' , loadingDefault ) ; // Default actions
registerAction ( {
type : HIGHLIGHT_ACTION_TYPE ,
event : HIGHLIGHT_ACTION_TYPE ,
update : HIGHLIGHT_ACTION_TYPE
} , noop ) ;
registerAction ( {
type : DOWNPLAY_ACTION_TYPE ,
event : DOWNPLAY_ACTION_TYPE ,
update : DOWNPLAY_ACTION_TYPE
} , noop ) ;
registerAction ( {
type : SELECT_ACTION_TYPE ,
event : SELECT_ACTION_TYPE ,
update : SELECT_ACTION_TYPE
} , noop ) ;
registerAction ( {
type : UNSELECT_ACTION_TYPE ,
event : UNSELECT_ACTION_TYPE ,
update : UNSELECT_ACTION_TYPE
} , noop ) ;
registerAction ( {
type : TOGGLE_SELECT_ACTION_TYPE ,
event : TOGGLE_SELECT_ACTION_TYPE ,
update : TOGGLE_SELECT_ACTION_TYPE
} , noop ) ; // Default theme
registerTheme ( 'light' , lightTheme ) ;
registerTheme ( 'dark' , darkTheme ) ; // For backward compatibility, where the namespace `dataTool` will
// be mounted on `echarts` is the extension `dataTool` is imported.
export var dataTool = { } ;