ECharts.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import { Options } from '..'
  2. import { EChartsComponent } from './EChartsComponent.d'
  3. import ResizeObserverSham from './ResizeObserverSham'
  4. import { EChartOption } from 'echarts'
  5. import commonOptions from './common-options'
  6. export function createComponent({
  7. echarts,
  8. h,
  9. ResizeObserver = ResizeObserverSham,
  10. name = 'ECharts',
  11. deepWatchOption = true,
  12. }: Options) {
  13. const options: Record<string, unknown> = {}
  14. if (typeof h === 'function') {
  15. options.render = getVue3Render(h)
  16. options.beforeUnmount = beforeUnmount
  17. options.emits = ['resize']
  18. } else {
  19. options.render = vue2Render
  20. options.beforeDestroy = beforeUnmount
  21. }
  22. return {
  23. ...commonOptions,
  24. ...options,
  25. name,
  26. data(this: EChartsComponent) {
  27. return {
  28. _private: Object.preventExtensions({
  29. observer: new ResizeObserver(() => {
  30. this.resize()
  31. this.$emit('resize')
  32. }),
  33. inst: null,
  34. }),
  35. }
  36. },
  37. watch: {
  38. ...commonOptions.watch,
  39. option: {
  40. handler(this: EChartsComponent, val: EChartOption) {
  41. this.setOption(val)
  42. },
  43. deep: deepWatchOption,
  44. },
  45. },
  46. methods: {
  47. ...commonOptions.methods,
  48. init(this: EChartsComponent) {
  49. const ctx = this
  50. const oldInst = ctx.inst
  51. if (oldInst) {
  52. oldInst.dispose()
  53. }
  54. const inst = echarts.init(ctx.$el, ctx.initTheme, ctx.initOpts)
  55. ctx.$data._private.inst = inst
  56. if (ctx.loading) {
  57. inst.showLoading(ctx.loadingType, ctx.loadingOpts)
  58. }
  59. if (ctx.events) {
  60. for (const args of ctx.events) {
  61. inst.on(...<[any, any]>args)
  62. }
  63. }
  64. if (ctx.option) {
  65. if (oldInst) {
  66. ctx.setOption(ctx.option)
  67. } else {
  68. // Wait for rendering
  69. setTimeout(() => ctx.setOption(ctx.option))
  70. }
  71. }
  72. if (ctx.autoResize) {
  73. ctx.addResizeListener()
  74. }
  75. },
  76. },
  77. }
  78. }
  79. const style = {
  80. height: '100%',
  81. overflow: 'hidden',
  82. }
  83. function vue2Render(this: EChartsComponent, h: Function) {
  84. return h('div', {
  85. attrs: this.$attrs,
  86. style,
  87. })
  88. }
  89. function getVue3Render(h: Function) {
  90. return function (this: EChartsComponent) {
  91. return h('div', {
  92. ...this.$attrs,
  93. style,
  94. })
  95. }
  96. }
  97. function beforeUnmount(this: EChartsComponent) {
  98. this.removeResizeListener()
  99. this.inst.dispose()
  100. }
  101. export function plugin(app: { component: Function }, options: Options) {
  102. const definition = createComponent(options)
  103. app.component(definition.name, definition)
  104. }