• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

antvis / G2Plot / 4486686012

pending completion
4486686012

push

github

GitHub
fix: renderer error (#3500)

0 of 42 branches covered (0.0%)

Branch coverage included in aggregate %.

18 of 18 new or added lines in 13 files covered. (100.0%)

77 of 216 relevant lines covered (35.65%)

0.46 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

8.86
/src/core/plot.ts
1
// @ts-nocheck
2
import EE from '@antv/event-emitter';
1✔
3
import { Chart } from '@antv/g2';
1✔
4
import { bind } from 'size-sensor';
1✔
5
import { merge, omit, pick } from '../utils';
1✔
6
import type { Annotation, Options, Adaptor } from '../types';
7

8
const SOURCE_ATTRIBUTE_NAME = 'data-chart-source-type';
1✔
9

10
/** new Chart options */
11
export const CHART_OPTIONS = ['width', 'height', 'renderer', 'autoFit', 'canvas', 'theme'];
1✔
12

13
export abstract class Plot<O extends Options> extends EE {
1✔
14
  /** plot 类型名称 */
15
  public abstract readonly type: string;
16
  /** plot 绘制的 dom */
17
  public readonly container: HTMLElement;
18
  /** G2 Spec */
19
  public options: O;
20
  /** G2 chart 实例 */
21
  public chart: Chart;
22
  /** resizer unbind  */
23
  private unbind: () => void;
24

25
  constructor(container: string | HTMLElement, options: O) {
26
    super();
×
27
    this.container = typeof container === 'string' ? document.getElementById(container) : container;
×
28
    this.options = merge({}, this.getBaseOptions(), this.getDefaultOptions(), options);
×
29
    this.createG2();
×
30
    this.render();
×
31
    this.bindEvents();
×
32
  }
33

34
  /**
35
   * new Chart 所需配置
36
   */
37
  private getChartOptions() {
38
    const { clientWidth, clientHeight } = this.container;
×
39
    // 逻辑简化:如果存在 width 或 height,则直接使用,否则使用容器大小
40
    const { width = clientWidth || 640, height = clientHeight || 480, autoFit = true } = this.options;
×
41
    return {
×
42
      ...pick(this.options, CHART_OPTIONS),
43
      container: this.container,
44
      width,
45
      height,
46
      autoFit,
47
    };
48
  }
49

50
  /**
51
   * G2 options(Spec) 配置
52
   */
53
  private getSpecOptions() {
54
    return omit(this.options, CHART_OPTIONS);
×
55
  }
56

57
  /**
58
   * 创建 G2 实例
59
   */
60
  private createG2() {
61
    if (!this.container) {
×
62
      throw Error('The container is not initialized!');
×
63
    }
64
    this.chart = new Chart(this.getChartOptions());
×
65
    // 给容器增加标识,知道图表的来源区别于 G2
66
    this.container.setAttribute(SOURCE_ATTRIBUTE_NAME, 'G2Plot');
×
67
  }
68

69
  /**
70
   * 绑定代理所有 G2 的事件
71
   */
72
  private bindEvents() {
73
    if (this.chart) {
×
74
      this.chart.on('*', (e) => {
×
75
        if (e?.type) {
×
76
          this.emit(e.type, e);
×
77
        }
78
      });
79
    }
80
  }
81

82
  private getBaseOptions(): Partial<Options> {
83
    return { theme: 'classic' };
×
84
  }
85

86
  /**
87
   * 获取默认的 options 配置项,每个组件都可以复写
88
   */
89
  protected getDefaultOptions(): Partial<Options>;
90

91
  /**
92
   * 绘制
93
   */
94
  public render() {
95
    // 暴力处理,先清空再渲染,需要 G2 层自行做好更新渲染
96
    this.chart.clear();
×
97
    // 执行 adaptor
98
    this.execAdaptor();
×
99

100
    // options 转换
101
    this.chart.options(this.getSpecOptions());
×
102
    // 渲染
103
    this.chart.render();
×
104
    // 绑定
105
    this.bindSizeSensor();
×
106
  }
107

108
  /**
109
   * 更新: 更新配置且重新渲染
110
   * @param options
111
   */
112
  public update(options: Partial<O>) {
113
    this.updateOption(options);
×
114
    this.render();
×
115
  }
116

117
  /**
118
   * 更新配置
119
   * @param options
120
   */
121
  protected updateOption(options: Partial<O>) {
122
    this.options = merge({}, this.options, options);
×
123
  }
124

125
  /**
126
   * 更新数据
127
   * @override
128
   * @param options
129
   */
130
  public changeData(data: any) {
131
    this.chart.data(data);
×
132
    this.chart.render();
×
133
  }
134

135
  /**
136
   * 修改画布大小
137
   * @param width
138
   * @param height
139
   */
140
  public changeSize(width: number, height: number) {
141
    this.chart.changeSize(width, height);
×
142
  }
143

144
  /**
145
   * 增加图表标注。通过 id 标识,如果匹配到,就做更新
146
   */
147
  public addAnnotations(annotations: Annotation[]): void {}
148

149
  /**
150
   * 删除图表标注。通过 id 标识,如果匹配到,就做删除
151
   */
152
  public removeAnnotations(annotations: Array<{ id: string } & Partial<Annotation>>): void {}
153
  /**
154
   * 销毁
155
   */
156
  public destroy() {
157
    // 取消 size-sensor 的绑定
158
    this.unbindSizeSensor();
×
159
    // G2 的销毁
160
    this.chart.destroy();
×
161
    // 清空已经绑定的事件
162
    this.off();
×
163

164
    this.container.removeAttribute(SOURCE_ATTRIBUTE_NAME);
×
165
  }
166

167
  /**
168
   * 每个组件有自己的 schema adaptor
169
   */
170
  protected abstract getSchemaAdaptor(): (params: Adaptor<O>) => void;
171

172
  /**
173
   * 执行 adaptor 操作
174
   */
175
  protected execAdaptor() {
176
    const adaptor = this.getSchemaAdaptor();
×
177

178
    // 转化成 G2 Spec
179
    adaptor({
×
180
      chart: this.chart,
181
      options: this.options,
182
    });
183
  }
184

185
  /**
186
   * 当图表容器大小变化的时候,执行的函数
187
   */
188
  protected triggerResize() {
189
    this.chart.forceFit();
×
190
  }
191

192
  /**
193
   * 绑定 dom 容器大小变化的事件
194
   */
195
  private bindSizeSensor() {
196
    if (this.unbind) {
×
197
      return;
×
198
    }
199
    const { autoFit = true } = this.options;
×
200
    if (autoFit) {
×
201
      this.unbind = bind(this.container, () => {
×
202
        // 获取最新的宽高信息
203
        const { clientHeight, clientWidth } = this.container;
×
204
        const { width, height } = this.chart.options();
×
205
        // 主要是防止绑定的时候触发 resize 回调
206
        if (clientHeight !== width || clientWidth !== height) {
×
207
          this.triggerResize();
×
208
        }
209
      });
210
    }
211
  }
212

213
  /**
214
   * 取消绑定
215
   */
216
  private unbindSizeSensor() {
217
    if (this.unbind) {
×
218
      this.unbind();
×
219
      this.unbind = undefined;
×
220
    }
221
  }
222
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc