123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- <template>
- <div class="echarts" :class="className" />
- </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'
- 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,
- className: String
- },
- 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
- }
- const chart = echarts.init(this.$el, this.theme, this.initOptions)
- if (this.group) {
- chart.group = this.group
- }
- chart.setOption(options || this.manualOptions || this.options || {}, true)
- Object.keys(this.$listeners).forEach(event => {
- const handler = this.$listeners[event]
- if (event.indexOf('zr:') === 0) {
- chart.getZr().on(event.slice(3), handler)
- } else {
- chart.on(event, handler)
- }
- })
- 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 () {
- },
- mounted () {
- this.initOptionsWatcher()
- INIT_TRIGGERS.forEach(prop => {
- this.$watch(
- prop,
- () => {
- this.refresh()
- },
- { deep: true }
- )
- })
- REWATCH_TRIGGERS.forEach(prop => {
- this.$watch(prop, () => {
- this.initOptionsWatcher()
- this.refresh()
- })
- })
- // 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)
- },
- getMap (mapName) {
- return echarts.getMap(mapName)
- },
- registerMap (mapName, geoJSON, specialAreas) {
- echarts.registerMap(mapName, geoJSON, specialAreas)
- },
- registerTheme (name, theme) {
- echarts.registerTheme(name, theme)
- },
- graphic: echarts.graphic
- }
- </script>
|