import Vue , { VNode , ComponentOptions } from 'vue' ; import typedProps from './typed' ; import * as viser from 'viser-cell' ; const regSeries = [ 'pie' , 'sector' , 'line' , 'smoothline' , 'dashline' , 'area' , 'point' , 'stackarea' , 'smootharea' , 'bar' , 'stackbar' , 'dodgebar' , 'interval' , 'stackinterval' , 'dodgeinterval' , 'schema' , 'box' , 'candle' , 'polygon' , 'path' , ] ; const rootCharts = [ 'v-chart' , 'v-lite-chart' ] ; const rootChartProps = [ 'data' , 'scale' ] ; const seriesProps = [ 'position' , 'quickType' , 'gemo' , 'adjust' , 'color' , 'shape' , 'size' , 'style' , 'animate' , ] ; const camelCase = ( ( ) => { const DEFAULT_REGEX = /[-_]+(.)?/g ; function toUpper ( match , group1 ) { return group1 ? group1 . toUpperCase ( ) : '' ; } return ( str , delimiters ? ) => { return str . replace ( delimiters ? new RegExp ( '[' + delimiters + ']+(.)?' , 'g' ) : DEFAULT_REGEX , toUpper ) ; } ; } ) ( ) ; declare module 'vue/types/vue' { interface Vue { chart : any ; _props ? : object ; _uid ? : string ; } } declare module 'vue/types/options' { interface ComponentOptions < V extends Vue > { _componentTag ? : any ; } } const baseChartComponent = { data ( ) { return { isViser : true , jsonForD2 : { } , } ; } , props : typedProps , methods : { checkIsContainer ( componentInstance ) { if ( ( componentInstance as any ) . isViser && rootCharts . indexOf ( ( ( componentInstance as any ) . $options as any ) . _componentTag ) > - 1 ) { return true ; } else { return false ; } } , /**
         * find nearest parent rechart component
         */ findNearestRootComponent ( componentInstance ) { if ( this . checkIsContainer ( componentInstance ) ) { if ( ( componentInstance . $options as any ) . _componentTag === 'v-lite-chart' ) { throw Error ( 'v-lite-chart should be no child elements.' ) ; } return componentInstance ; } if ( componentInstance . $parent ) { return this . findNearestRootComponent ( componentInstance . $parent ) ; } return null ; } , createRootD2Json ( ) { const d2Json = { ... cleanUndefined ( normalizeProps ( this . _props , rootChartProps ) ) , chart : { el : this . $el , ... cleanUndefined ( normalizeProps ( this . _props , null , rootChartProps ) ) , } , ... this . jsonForD2 , } ; if ( this . $options . _componentTag === 'v-lite-chart' ) { const existProps = cleanUndefined ( this . _props ) ; Object . keys ( existProps ) . forEach ( propsKey => { const lowerCasePropsKey = propsKey . toLowerCase ( ) ; if ( regSeries . indexOf ( lowerCasePropsKey ) > - 1 ) { safePush ( d2Json , 'series' , { quickType : propsKey , ... normalizeProps ( existProps , seriesProps ) , } ) ; } } ) ; setIfNotExist ( d2Json , 'axis' , true ) ; setIfNotExist ( d2Json , 'legend' , true ) ; setIfNotExist ( d2Json , 'tooltip' , true ) ; } return d2Json ; } , freshChart ( isUpdate ) { /**
             * refresh chart
             */ if ( rootCharts . indexOf ( this . $options . _componentTag ) > - 1 ) { const d2Json = this . createRootD2Json ( ) ; if ( ! isUpdate || ! this . chart ) { this . chart = viser . default ( d2Json ) ; } else { this . chart . repaint ( d2Json ) ; } } else { /**
                 * refresh others like axis, coord, guide, etc.
                 */ const nearestRootComponent = this . findNearestRootComponent ( this . $parent ) ; if ( ! nearestRootComponent ) { throw Error ( `${ this . $options . _componentTag } must be wrapped into v-chart` ) ; } const rechartName = this . $options . _componentTag . replace ( /-/g , '' ) . slice ( 1 ) ; const rechartNameCamelCase = camelCase ( this . $options . _componentTag . slice ( 2 ) ) ; if ( isAllUndefined ( this . _props ) ) { nearestRootComponent . jsonForD2 [ rechartName ] = true ; } else if ( regSeries . indexOf ( rechartName ) > - 1 ) { safePush ( nearestRootComponent . jsonForD2 , 'series' , { quickType : rechartNameCamelCase , ... cleanUndefined ( normalizeProps ( this . _props ) ) , } ) ; } else { oneObjectMoreArray ( nearestRootComponent . jsonForD2 , rechartName , { ... cleanUndefined ( normalizeProps ( this . _props ) ) , componentId : this . _uid , } ) ; } } } , } , created ( ) { } , mounted ( ) { ( this as any ) . freshChart ( false ) ; } , updated ( ) { ( this as any ) . freshChart ( true ) ; } , render ( createElement ) { const isContainer = ( this as any ) . checkIsContainer ( this ) ; if ( isContainer ) { return createElement ( 'canvas' , undefined , ( this as any ) . $slots . default ) ; } const props = cleanUndefined ( normalizeProps ( ( this as any ) . _props ) ) ; return createElement ( 'canvas' , { style : { display : 'none' } } , Object . keys ( props ) . map ( key => { return '' + key + ':' + JSON . stringify ( props [ key ] ) ; } ) ) ; } , } as ComponentOptions < any > ; export default { install : ( Vue , options ) => { Vue . component ( 'v-chart' , baseChartComponent ) ; Vue . component ( 'v-tooltip' , baseChartComponent ) ; Vue . component ( 'v-legend' , baseChartComponent ) ; Vue . component ( 'v-axis' , baseChartComponent ) ; Vue . component ( 'v-coord' , baseChartComponent ) ; Vue . component ( 'v-series' , baseChartComponent ) ; Vue . component ( 'v-lite-chart' , baseChartComponent ) ; Vue . component ( 'v-guide' , baseChartComponent ) ; Vue . component ( 'v-point' , baseChartComponent ) ; Vue . component ( 'v-pie' , baseChartComponent ) ; Vue . component ( 'v-bar' , baseChartComponent ) ; Vue . component ( 'v-stack-bar' , baseChartComponent ) ; Vue . component ( 'v-dodge-bar' , baseChartComponent ) ; Vue . component ( 'v-interval' , baseChartComponent ) ; Vue . component ( 'v-stack-interval' , baseChartComponent ) ; Vue . component ( 'v-dodge-interval' , baseChartComponent ) ; Vue . component ( 'v-schema' , baseChartComponent ) ; Vue . component ( 'v-line' , baseChartComponent ) ; Vue . component ( 'v-smooth-line' , baseChartComponent ) ; Vue . component ( 'v-dash-line' , baseChartComponent ) ; Vue . component ( 'v-sector' , baseChartComponent ) ; Vue . component ( 'v-area' , baseChartComponent ) ; Vue . component ( 'v-stack-area' , baseChartComponent ) ; Vue . component ( 'v-smooth-area' , baseChartComponent ) ; Vue . component ( 'v-polygon' , baseChartComponent ) ; Vue . component ( 'v-candle' , baseChartComponent ) ; Vue . component ( 'v-box' , baseChartComponent ) ; Vue . component ( 'v-path' , baseChartComponent ) ; } , } ; function safePush ( obj , key , value ) { if ( ! obj [ key ] ) { obj [ key ] = [ ] ; } cleanUndefined ( value ) ; obj [ key ] . push ( value ) ; } function oneObjectMoreArray ( obj , key , value ) { if ( ! obj [ key ] ) { obj [ key ] = value ; return ; } if ( obj [ key ] && obj [ key ] . constructor . name === 'Object' ) { obj [ key ] = [ obj [ key ] ] ; } let indexOfSameObject = - 1 ; if ( value && value . viewId ) { obj [ key ] . forEach ( ( o , i ) => { if ( o && o . viewId && o . viewId === value . viewId ) { indexOfSameObject = i ; } } ) ; } else if ( value && value . componentId ) { obj [ key ] . forEach ( ( o , i ) => { if ( o && o . componentId && o . componentId === value . componentId ) { indexOfSameObject = i ; } } ) ; } if ( indexOfSameObject === - 1 ) { obj [ key ] . push ( value ) ; } else { obj [ key ] [ indexOfSameObject ] = { ... obj [ key ] [ indexOfSameObject ] , ... value , } ; } } function cleanUndefined ( value ) { const newValue = { ... value } ; for ( const key in newValue ) { if ( newValue [ key ] === undefined ) { delete newValue [ key ] ; } } return newValue ; } function isAllUndefined ( value ) { return Object . keys ( value ) . every ( key => value [ key ] === undefined ) ; } /**
 * special props for vue
 */ function normalizeProps ( props , include = null , expect = null ) { const newProps = { ... props } ; if ( newProps . vStyle ) { newProps . style = newProps . vStyle ; delete newProps . vStyle ; } if ( expect !== null ) { expect . forEach ( propsKey => { delete newProps [ propsKey ] ; } ) ; } if ( include !== null ) { Object . keys ( newProps ) . forEach ( propsKey => { if ( include . indexOf ( propsKey ) === - 1 ) { delete newProps [ propsKey ] ; } } ) ; } return newProps ; } function setIfNotExist ( obj , key , value ) { if ( ! obj [ key ] ) { obj [ key ] = value ; } } export const registerAnimation = viser . registerAnimation ; export const registerShape = viser . registerShape ; export const Global = viser . Global ;