123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- <template>
- <div class="echarts"/>
- </template>
- <style>
- .echarts {
- width: 600px;
- height: 400px;
- }
- </style>
- <script>
- import echarts from 'echarts/lib/echarts'
- import debounce from 'lodash/debounce'
- import { addListener, removeListener } from 'resize-detector'
- // enumerating ECharts events for now
- const EVENTS = [
- 'legendselectchanged',
- 'legendselected',
- 'legendunselected',
- 'legendscroll',
- 'datazoom',
- 'datarangeselected',
- 'timelinechanged',
- 'timelineplaychanged',
- 'restore',
- 'dataviewchanged',
- 'magictypechanged',
- 'geoselectchanged',
- 'geoselected',
- 'geounselected',
- 'pieselectchanged',
- 'pieselected',
- 'pieunselected',
- 'mapselectchanged',
- 'mapselected',
- 'mapunselected',
- 'axisareaselected',
- 'focusnodeadjacency',
- 'unfocusnodeadjacency',
- 'brush',
- 'brushselected',
- 'rendered',
- 'finished',
- 'click',
- 'dblclick',
- 'mouseover',
- 'mouseout',
- 'mousemove',
- 'mousedown',
- 'mouseup',
- 'globalout',
- 'contextmenu'
- ]
- const ZR_EVENTS = [
- 'click',
- 'mousedown',
- 'mouseup',
- 'mousewheel',
- 'dblclick',
- 'contextmenu'
- ]
- const INIT_TRIGGERS = ['theme', 'initOptions', 'autoresize']
- const REWATCH_TRIGGERS = ['manualUpdate', 'watchShallow']
- export default {
- props: {
- options: Object,
- theme: [String, Object],
- initOptions: Object,
- group: String,
- autoresize: Boolean,
- watchShallow: Boolean,
- manualUpdate: Boolean
- },
- data () {
- return {
- lastArea: 0
- }
- },
- watch: {
- group (group) {
- this.chart.group = group
- }
- },
- methods: {
- // provide an explicit merge option method
- mergeOptions (options, notMerge, lazyUpdate) {
- if (this.manualUpdate) {
- this.manualOptions = options
- }
- if (!this.chart) {
- this.init(options)
- } else {
- this.delegateMethod('setOption', options, notMerge, lazyUpdate)
- }
- },
- // just delegates ECharts methods to Vue component
- // use explicit params to reduce transpiled size for now
- appendData (params) {
- this.delegateMethod('appendData', params)
- },
- resize (options) {
- this.delegateMethod('resize', options)
- },
- dispatchAction (payload) {
- this.delegateMethod('dispatchAction', payload)
- },
- convertToPixel (finder, value) {
- return this.delegateMethod('convertToPixel', finder, value)
- },
- convertFromPixel (finder, value) {
- return this.delegateMethod('convertFromPixel', finder, value)
- },
- containPixel (finder, value) {
- return this.delegateMethod('containPixel', finder, value)
- },
- showLoading (type, options) {
- this.delegateMethod('showLoading', type, options)
- },
- hideLoading () {
- this.delegateMethod('hideLoading')
- },
- getDataURL (options) {
- return this.delegateMethod('getDataURL', options)
- },
- getConnectedDataURL (options) {
- return this.delegateMethod('getConnectedDataURL', options)
- },
- clear () {
- this.delegateMethod('clear')
- },
- dispose () {
- this.delegateMethod('dispose')
- },
- delegateMethod (name, ...args) {
- if (!this.chart) {
- this.init()
- }
- return this.chart[name](...args)
- },
- delegateGet (methodName) {
- if (!this.chart) {
- this.init()
- }
- return this.chart[methodName]()
- },
- getArea () {
- return this.$el.offsetWidth * this.$el.offsetHeight
- },
- init (options) {
- if (this.chart) {
- return
- }
- let chart = echarts.init(this.$el, this.theme, this.initOptions)
- if (this.group) {
- chart.group = this.group
- }
- chart.setOption(options || this.manualOptions || this.options || {}, true)
- // expose ECharts events as custom events
- EVENTS.forEach(event => {
- chart.on(event, params => {
- this.$emit(event, params)
- })
- })
- ZR_EVENTS.forEach(event => {
- chart.getZr().on(event, params => {
- this.$emit(`zr:${event}`, params)
- })
- })
- if (this.autoresize) {
- this.lastArea = this.getArea()
- this.__resizeHandler = debounce(() => {
- if (this.lastArea === 0) {
- // emulate initial render for initially hidden charts
- this.mergeOptions({}, true)
- this.resize()
- this.mergeOptions(this.options || this.manualOptions || {}, true)
- } else {
- this.resize()
- }
- this.lastArea = this.getArea()
- }, 100, { leading: true })
- addListener(this.$el, this.__resizeHandler)
- }
- Object.defineProperties(this, {
- // Only recalculated when accessed from JavaScript.
- // Won't update DOM on value change because getters
- // don't depend on reactive values
- width: {
- configurable: true,
- get: () => {
- return this.delegateGet('getWidth')
- }
- },
- height: {
- configurable: true,
- get: () => {
- return this.delegateGet('getHeight')
- }
- },
- isDisposed: {
- configurable: true,
- get: () => {
- return !!this.delegateGet('isDisposed')
- }
- },
- computedOptions: {
- configurable: true,
- get: () => {
- return this.delegateGet('getOption')
- }
- }
- })
- this.chart = chart
- },
- initOptionsWatcher () {
- if (this.__unwatchOptions) {
- this.__unwatchOptions()
- this.__unwatchOptions = null
- }
- if (!this.manualUpdate) {
- this.__unwatchOptions = this.$watch('options', (val, oldVal) => {
- if (!this.chart && val) {
- this.init()
- } else {
- // mutating `options` will lead to merging
- // replacing it with new reference will lead to not merging
- // eg.
- // `this.options = Object.assign({}, this.options, { ... })`
- // will trigger `this.chart.setOption(val, true)
- // `this.options.title.text = 'Trends'`
- // will trigger `this.chart.setOption(val, false)`
- this.chart.setOption(val, val !== oldVal)
- }
- }, { deep: !this.watchShallow })
- }
- },
- destroy () {
- if (this.autoresize) {
- removeListener(this.$el, this.__resizeHandler)
- }
- this.dispose()
- this.chart = null
- },
- refresh () {
- if (this.chart) {
- this.destroy()
- this.init()
- }
- }
- },
- created () {
- this.initOptionsWatcher()
- INIT_TRIGGERS.forEach(prop => {
- this.$watch(prop, () => {
- this.refresh()
- }, { deep: true })
- })
- REWATCH_TRIGGERS.forEach(prop => {
- this.$watch(prop, () => {
- this.initOptionsWatcher()
- this.refresh()
- })
- })
- },
- mounted () {
- // auto init if `options` is already provided
- if (this.options) {
- this.init()
- }
- },
- activated () {
- if (this.autoresize) {
- this.chart && this.chart.resize()
- }
- },
- destroyed () {
- if (this.chart) {
- this.destroy()
- }
- },
- connect (group) {
- if (typeof group !== 'string') {
- group = group.map(chart => chart.chart)
- }
- echarts.connect(group)
- },
- disconnect (group) {
- echarts.disConnect(group)
- },
- registerMap (mapName, geoJSON, specialAreas) {
- echarts.registerMap(mapName, geoJSON, specialAreas)
- },
- registerTheme (name, theme) {
- echarts.registerTheme(name, theme)
- },
- graphic: echarts.graphic
- }
- </script>
|