jmgraph 3.2.20 → 3.2.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,6 +9,40 @@ class WebglPath extends WebglBase {
9
9
  this.needCut = option.needCut || false;
10
10
  this.control = option.control;
11
11
  this.points = [];
12
+ // 缓存 buffer 和纹理,避免每帧创建/销毁
13
+ this.__cachedBuffers = [];
14
+ this.__cachedTexture = null;
15
+ this.__cachedTextureKey = null;
16
+ }
17
+
18
+ // 释放缓存的 WebGL 资源
19
+ dispose() {
20
+ for(const buf of this.__cachedBuffers) {
21
+ this.deleteBuffer(buf);
22
+ }
23
+ this.__cachedBuffers = [];
24
+ if(this.__cachedTexture) {
25
+ this.deleteTexture(this.__cachedTexture);
26
+ this.__cachedTexture = null;
27
+ this.__cachedTextureKey = null;
28
+ }
29
+ }
30
+
31
+ // 获取或创建 buffer,优先复用缓存
32
+ getOrCreateBuffer(data, attr) {
33
+ let buffer = this.__cachedBuffers.find(b => b.attr === attr);
34
+ if(buffer) {
35
+ const gl = this.context;
36
+ const float32 = new Float32Array(data);
37
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer.buffer);
38
+ gl.bufferData(gl.ARRAY_BUFFER, float32, gl.DYNAMIC_DRAW);
39
+ buffer.data = data;
40
+ return buffer;
41
+ }
42
+ buffer = this.createFloat32Buffer(data);
43
+ buffer.attr = attr;
44
+ this.__cachedBuffers.push(buffer);
45
+ return buffer;
12
46
  }
13
47
 
14
48
  // 应用变换到点
@@ -21,8 +55,14 @@ class WebglPath extends WebglBase {
21
55
  //this.useProgram();
22
56
 
23
57
  if(parentBounds) this.parentAbsoluteBounds = parentBounds;
24
- // 写入当前canvas大小
25
- this.context.uniform2f(this.program.uniforms.a_center_point.location, this.graph.width / 2, this.graph.height / 2);
58
+ // 缓存中心点值,只在变化时才更新 uniform
59
+ const cx = this.graph.width / 2;
60
+ const cy = this.graph.height / 2;
61
+ if(this.__lastCenterX !== cx || this.__lastCenterY !== cy) {
62
+ this.context.uniform2f(this.program.uniforms.a_center_point.location, cx, cy);
63
+ this.__lastCenterX = cx;
64
+ this.__lastCenterY = cy;
65
+ }
26
66
  }
27
67
 
28
68
  setFragColor(color) {
@@ -63,6 +103,7 @@ class WebglPath extends WebglBase {
63
103
  endDraw() {
64
104
  if(this.points) delete this.points;
65
105
  if(this.pathPoints) delete this.pathPoints;
106
+ // 缓存的纹理保留到下次绘制(渐变可能不变)
66
107
  }
67
108
 
68
109
  // 图形封闭
@@ -74,21 +115,47 @@ class WebglPath extends WebglBase {
74
115
  }
75
116
  }
76
117
 
77
- // 绘制点数组
118
+ // 绘制点数组(使用 DYNAMIC_DRAW 复用 buffer,避免每帧 create/delete)
78
119
  writePoints(points, attr = this.program.attrs.a_position) {
79
-
80
120
  const fixedPoints = [];
81
- for(const p of points) {
82
- // 应用变换矩阵
83
- const transformedPoint = this.applyTransform(p);
84
- fixedPoints.push(
85
- transformedPoint.x + this.parentAbsoluteBounds.left,
86
- transformedPoint.y + this.parentAbsoluteBounds.top
87
- );
88
- }
89
- const vertexBuffer = this.createFloat32Buffer(fixedPoints);
121
+ const [a, b, c, d, tx, ty] = this.transformMatrix;
122
+ const isIdentity = (a === 1 && b === 0 && c === 0 && d === 1 && tx === 0 && ty === 0);
123
+ const offsetLeft = this.parentAbsoluteBounds.left;
124
+ const offsetTop = this.parentAbsoluteBounds.top;
125
+
126
+ if(isIdentity) {
127
+ // 单位矩阵时直接加偏移,避免逐点调用 applyTransform
128
+ for(let i = 0; i < points.length; i++) {
129
+ fixedPoints.push(points[i].x + offsetLeft, points[i].y + offsetTop);
130
+ }
131
+ } else {
132
+ for(const p of points) {
133
+ const transformedPoint = this.applyTransform(p);
134
+ fixedPoints.push(
135
+ transformedPoint.x + offsetLeft,
136
+ transformedPoint.y + offsetTop
137
+ );
138
+ }
139
+ }
140
+ const float32 = new Float32Array(fixedPoints);
141
+ const gl = this.context;
142
+
143
+ // 复用已有 buffer 或创建新的
144
+ if(this.__cachedBuffers.length > 0) {
145
+ // 找一个同 attr 的 buffer 复用
146
+ let buffer = this.__cachedBuffers.find(b => b.attr === attr);
147
+ if(buffer) {
148
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer.buffer);
149
+ gl.bufferData(gl.ARRAY_BUFFER, float32, gl.DYNAMIC_DRAW);
150
+ buffer.data = fixedPoints;
151
+ this.writeVertexAttrib(buffer, attr, 2, 0, 0);
152
+ return buffer;
153
+ }
154
+ }
155
+ const vertexBuffer = this.createFloat32Buffer(float32, gl.ARRAY_BUFFER, gl.DYNAMIC_DRAW);
90
156
  this.writeVertexAttrib(vertexBuffer, attr, 2, 0, 0);
91
157
  vertexBuffer.attr = attr;
158
+ this.__cachedBuffers.push(vertexBuffer);
92
159
  return vertexBuffer;
93
160
  }
94
161
 
@@ -370,9 +437,10 @@ class WebglPath extends WebglBase {
370
437
 
371
438
  // 分割成一个个规则的三角形,不规则的多边形不全割的话纹理就会没法正确覆盖
372
439
  getTriangles(points) {
373
-
374
440
  this.trianglesCache = this.trianglesCache||(this.trianglesCache={});
375
- const key = JSON.stringify(points);
441
+ // 快速缓存 key:用长度和首尾点坐标(比 JSON.stringify 快几个数量级)
442
+ const len = points.length;
443
+ const key = len + '_' + points[0].x + '_' + points[0].y + '_' + points[len-1].x + '_' + points[len-1].y;
376
444
  if(this.trianglesCache[key]) return this.trianglesCache[key];
377
445
 
378
446
  const res = [];
@@ -411,10 +479,9 @@ class WebglPath extends WebglBase {
411
479
  points = regular? points : this.pathToPoints(points);
412
480
  const buffer = this.writePoints(points);
413
481
  this.context.drawArrays(regular? this.context.LINE_LOOP: this.context.POINTS, 0, points.length);
414
- this.deleteBuffer(buffer);
482
+ // buffer 由 endDraw 统一清理
415
483
  }
416
- colorBuffer && this.deleteBuffer(colorBuffer);
417
- colorBuffer && this.disableVertexAttribArray(colorBuffer.attr);
484
+ colorBuffer && this.disableVertexAttribArray(colorBuffer && colorBuffer.attr);
418
485
  }
419
486
 
420
487
  // 填充图形
@@ -445,8 +512,7 @@ class WebglPath extends WebglBase {
445
512
 
446
513
  this.fillPolygons(points);
447
514
 
448
- colorBuffer && this.deleteBuffer(colorBuffer);
449
- colorBuffer && this.disableVertexAttribArray(colorBuffer.attr);
515
+ colorBuffer && this.disableVertexAttribArray(colorBuffer && colorBuffer.attr);
450
516
 
451
517
  }
452
518
 
@@ -456,8 +522,24 @@ class WebglPath extends WebglBase {
456
522
  fillImage(img, points, bounds) {
457
523
  if(!img) return;
458
524
 
459
- // 设置纹理
460
- const texture = img instanceof ImageData? this.createDataTexture(img) : this.createImgTexture(img);
525
+ // 对于 ImageData,生成缓存 key(基于渐变参数或 bounds),复用纹理
526
+ let texture = null;
527
+ if(img instanceof ImageData) {
528
+ const key = `${img.width}_${img.height}_${bounds.width}_${bounds.height}_${bounds.left}_${bounds.top}`;
529
+ if(this.__cachedTexture && this.__cachedTextureKey === key) {
530
+ texture = this.__cachedTexture;
531
+ } else {
532
+ texture = this.createDataTexture(img);
533
+ // 释放旧纹理
534
+ if(this.__cachedTexture) {
535
+ this.deleteTexture(this.__cachedTexture);
536
+ }
537
+ this.__cachedTexture = texture;
538
+ this.__cachedTextureKey = key;
539
+ }
540
+ } else {
541
+ texture = this.createImgTexture(img);
542
+ }
461
543
  this.context.uniform1i(this.program.uniforms.u_sample.location, 0); // 纹理单元传递给着色器
462
544
 
463
545
  // 指定纹理区域尺寸
@@ -470,7 +552,10 @@ class WebglPath extends WebglBase {
470
552
 
471
553
  this.fillTexture(points);
472
554
 
473
- this.deleteTexture(texture);
555
+ // 仅对非缓存纹理(非 ImageData)立即删除
556
+ if(!(img instanceof ImageData)) {
557
+ this.deleteTexture(texture);
558
+ }
474
559
  }
475
560
 
476
561
  fillTexture(points) {
@@ -486,23 +571,67 @@ class WebglPath extends WebglBase {
486
571
 
487
572
  // 进行多边形填充
488
573
  fillPolygons(points, isTexture = false) {
489
- if(points.length > 3) {
490
- const triangles = this.needCut? this.earCutPointsToTriangles(points): this.getTriangles(points);
491
- if(triangles.length) {
492
- for(const triangle of triangles) {
493
- this.fillPolygons(triangle, isTexture);// 这里就变成了规则的图形了
494
- }
495
- }
496
- }
497
- else {
574
+ if(points.length <= 3) {
575
+ // 3个点以下的三角形直接画
498
576
  const buffer = this.writePoints(points);
499
- // 纹理坐标
500
577
  const coordBuffer = isTexture? this.writePoints(points, this.program.attrs.a_text_coord): null;
578
+ this.context.drawArrays(this.context.TRIANGLE_FAN, 0, points.length);
579
+ return;
580
+ }
501
581
 
582
+ // 规则图形(凸多边形,如圆):直接用 TRIANGLE_FAN 一次性绘制,无需 earcut
583
+ if(this.isRegular) {
584
+ const buffer = this.writePoints(points);
585
+ const coordBuffer = isTexture? this.writePoints(points, this.program.attrs.a_text_coord): null;
502
586
  this.context.drawArrays(this.context.TRIANGLE_FAN, 0, points.length);
503
- this.deleteBuffer(buffer);
504
- coordBuffer && this.deleteBuffer(coordBuffer);
587
+ return;
505
588
  }
589
+
590
+ // 不规则图形:需要 earcut 三角化后,合并为一个大的顶点缓冲区,单次 drawArrays
591
+ const triangles = this.needCut? this.earCutPointsToTriangles(points): this.getTriangles(points);
592
+ if(!triangles.length) return;
593
+
594
+ // 合并所有三角形的顶点到一个数组
595
+ const allVertices = [];
596
+ const allTexCoords = [];
597
+ for(const triangle of triangles) {
598
+ for(const p of triangle) {
599
+ allVertices.push(p.x, p.y);
600
+ if(isTexture) allTexCoords.push(p.x, p.y);
601
+ }
602
+ }
603
+
604
+ // 一次性上传所有数据并绘制
605
+ const vertexData = new Float32Array(allVertices);
606
+ const gl = this.context;
607
+
608
+ // 复用或创建 position buffer
609
+ let posBuffer = this.__cachedBuffers.find(b => b.attr === this.program.attrs.a_position);
610
+ if(!posBuffer) {
611
+ posBuffer = this.createFloat32Buffer(vertexData, gl.ARRAY_BUFFER, gl.DYNAMIC_DRAW);
612
+ posBuffer.attr = this.program.attrs.a_position;
613
+ this.__cachedBuffers.push(posBuffer);
614
+ } else {
615
+ gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer.buffer);
616
+ gl.bufferData(gl.ARRAY_BUFFER, vertexData, gl.DYNAMIC_DRAW);
617
+ }
618
+ this.writeVertexAttrib(posBuffer, this.program.attrs.a_position, 2, 0, 0);
619
+
620
+ if(isTexture && allTexCoords.length) {
621
+ const texData = new Float32Array(allTexCoords);
622
+ let texBuffer = this.__cachedBuffers.find(b => b.attr === this.program.attrs.a_text_coord);
623
+ if(!texBuffer) {
624
+ texBuffer = this.createFloat32Buffer(texData, gl.ARRAY_BUFFER, gl.DYNAMIC_DRAW);
625
+ texBuffer.attr = this.program.attrs.a_text_coord;
626
+ this.__cachedBuffers.push(texBuffer);
627
+ } else {
628
+ gl.bindBuffer(gl.ARRAY_BUFFER, texBuffer.buffer);
629
+ gl.bufferData(gl.ARRAY_BUFFER, texData, gl.DYNAMIC_DRAW);
630
+ }
631
+ this.writeVertexAttrib(texBuffer, this.program.attrs.a_text_coord, 2, 0, 0);
632
+ }
633
+
634
+ gl.drawArrays(gl.TRIANGLES, 0, allVertices.length / 2);
506
635
  }
507
636
 
508
637
  // 填充图形
@@ -123,7 +123,6 @@ export default class jmArc extends jmPath {
123
123
  if((mw == 0 && mh == 0) || start == end) return;
124
124
 
125
125
  let anticlockwise = this.anticlockwise;
126
- this.points = [];
127
126
  let step = 1 / Math.max(mw, mh);
128
127
 
129
128
  //如果是逆时针绘制,则角度为负数,并且结束角为2Math.PI-end
@@ -134,18 +133,33 @@ export default class jmArc extends jmPath {
134
133
  }
135
134
  if(start > end) step = -step;
136
135
 
137
- if(this.isFan) this.points.push(location.center);// 如果是扇形,则从中心开始画
136
+ // 预计算需要的点数量
137
+ let pointCount = Math.ceil(Math.abs(end - start) / Math.abs(step)) + 1;
138
+ if(this.isFan) pointCount++;
139
+
140
+ // 复用已有数组,避免每帧分配;大小变化时才重建
141
+ if(!this.points || this.points.length !== pointCount) {
142
+ this.points = new Array(pointCount);
143
+ for(let i = 0; i < pointCount; i++) {
144
+ this.points[i] = { x: 0, y: 0 };
145
+ }
146
+ }
147
+
148
+ let idx = 0;
149
+ if(this.isFan) {
150
+ this.points[idx].x = location.center.x;
151
+ this.points[idx].y = location.center.y;
152
+ idx++;
153
+ }
138
154
 
139
155
  //椭圆方程x=a*cos(r) ,y=b*sin(r)
140
156
  for(let r=start;;r += step) {
141
157
  if(step > 0 && r > end) r = end;
142
158
  else if(step < 0 && r < end) r = end;
143
159
 
144
- const p = {
145
- x : Math.cos(r) * mw + cx,
146
- y : Math.sin(r) * mh + cy
147
- };
148
- this.points.push(p);
160
+ this.points[idx].x = Math.cos(r) * mw + cx;
161
+ this.points[idx].y = Math.sin(r) * mh + cy;
162
+ idx++;
149
163
 
150
164
  if(r == end) break;
151
165
  }
@@ -22,7 +22,7 @@ export default class jmLabel extends jmControl {
22
22
  this.style.textAlign = this.style.textAlign || 'left';
23
23
  //文字垂直对齐
24
24
  this.style.textBaseline = this.style.textBaseline || 'middle';
25
- this.text = params.text || '';
25
+ this.text = params.text || params.value || '';
26
26
 
27
27
  this.center = params.center || null;
28
28
  }
@@ -311,67 +311,6 @@ export default class jmLabel extends jmControl {
311
311
  }
312
312
  }
313
313
  }
314
- //如果有指定边框,则画出边框
315
- if(this.style.border) {
316
- //如果指定了边框样式
317
- if(this.style.border.style) {
318
- this.context.save && this.context.save();
319
- this.setStyle(this.style.border.style);
320
- }
321
- if(this.mode === '2d') {
322
- this.context.moveTo(this.points[0].x + bounds.left,this.points[0].y + bounds.top);
323
- if(this.style.border.top) {
324
- this.context.lineTo(this.points[1].x + bounds.left,this.points[1].y + bounds.top);
325
- }
326
-
327
- if(this.style.border.right) {
328
- this.context.moveTo(this.points[1].x + bounds.left,this.points[1].y + bounds.top);
329
- this.context.lineTo(this.points[2].x + bounds.left,this.points[2].y + bounds.top);
330
- }
331
-
332
- if(this.style.border.bottom) {
333
- this.context.moveTo(this.points[2].x + bounds.left,this.points[2].y + bounds.top);
334
- this.context.lineTo(this.points[3].x + bounds.left,this.points[3].y + bounds.top);
335
- }
336
-
337
- if(this.style.border.left) {
338
- this.context.moveTo(this.points[3].x + bounds.left,this.points[3].y + bounds.top);
339
- this.context.lineTo(this.points[0].x + bounds.left,this.points[0].y + bounds.top);
340
- }
341
- }
342
- else {
343
- const points = [];
344
- if(this.style.border.top) {
345
- points.push(this.points[0]);
346
- points.push(this.points[1]);
347
- }
348
-
349
- if(this.style.border.right) {
350
- points.push({
351
- ...this.points[1],
352
- m: true
353
- });
354
- points.push(this.points[2]);
355
- }
356
-
357
- if(this.style.border.bottom) {
358
- points.push({
359
- ...this.points[2],
360
- m: true
361
- });
362
- points.push(this.points[3]);
363
- }
364
-
365
- if(this.style.border.left) {
366
- points.push({
367
- ...this.points[3],
368
- m: true
369
- });
370
- points.push(this.points[0]);
371
- }
372
- points.length && this.webglControl && this.webglControl.stroke(points);
373
- }
374
- }
375
314
  }
376
315
 
377
316
  endDraw() {
@@ -8,6 +8,7 @@ import {jmLine} from './jmLine.js';
8
8
  * @class jmRect
9
9
  * @extends jmPath
10
10
  * @param {object} params 参数 position=矩形左上角顶点坐标,width=宽,height=高,radius=边角弧度
11
+ * radius支持数字(四角相同)或对象 { topLeft, topRight, bottomRight, bottomLeft }
11
12
  */
12
13
  export default class jmRect extends jmPath {
13
14
 
@@ -17,12 +18,24 @@ export default class jmRect extends jmPath {
17
18
  super(params, t);
18
19
 
19
20
  this.style.close = true;
20
- this.radius = params.radius || this.style.radius || 0;
21
+ const r = params.radius || this.style.radius || this.style.borderRadius || 0;
22
+ if(typeof r === 'object' && r !== null) {
23
+ // 四角独立圆角
24
+ this.radius = {
25
+ topLeft: Number(r.topLeft) || 0,
26
+ topRight: Number(r.topRight) || 0,
27
+ bottomRight: Number(r.bottomRight) || 0,
28
+ bottomLeft: Number(r.bottomLeft) || 0
29
+ };
30
+ }
31
+ else {
32
+ this.radius = r;
33
+ }
21
34
  }
22
35
  /**
23
- * 圆角半径
36
+ * 圆角半径,支持数字或四角独立对象
24
37
  * @property radius
25
- * @type {number}
38
+ * @type {number|object}
26
39
  */
27
40
  get radius() {
28
41
  return this.property('radius');
@@ -30,6 +43,36 @@ export default class jmRect extends jmPath {
30
43
  set radius(v) {
31
44
  this.needUpdate = true;
32
45
  return this.property('radius', v);
46
+ }
47
+
48
+ /**
49
+ * 获取规范化的圆角值(四角独立)
50
+ * @returns {object} { topLeft, topRight, bottomRight, bottomLeft }
51
+ */
52
+ getNormalizedRadius() {
53
+ const r = this.radius;
54
+ if(typeof r === 'number') {
55
+ const v = Math.max(0, r);
56
+ return { topLeft: v, topRight: v, bottomRight: v, bottomLeft: v };
57
+ }
58
+ if(typeof r === 'object' && r !== null) {
59
+ return {
60
+ topLeft: Math.max(0, Number(r.topLeft) || 0),
61
+ topRight: Math.max(0, Number(r.topRight) || 0),
62
+ bottomRight: Math.max(0, Number(r.bottomRight) || 0),
63
+ bottomLeft: Math.max(0, Number(r.bottomLeft) || 0)
64
+ };
65
+ }
66
+ return { topLeft: 0, topRight: 0, bottomRight: 0, bottomLeft: 0 };
67
+ }
68
+
69
+ /**
70
+ * 检查是否有圆角
71
+ * @returns {boolean}
72
+ */
73
+ hasRadius() {
74
+ const nr = this.getNormalizedRadius();
75
+ return nr.topLeft > 0 || nr.topRight > 0 || nr.bottomRight > 0 || nr.bottomLeft > 0;
33
76
  }
34
77
 
35
78
  /**
@@ -92,7 +135,7 @@ export default class jmRect extends jmPath {
92
135
 
93
136
  /**
94
137
  * 初始化图形点
95
- * 如果有边角弧度则类型圆绝计算其描点
138
+ * 支持四角独立圆角,借助圆弧对象计算描点
96
139
  *
97
140
  * @method initPoints
98
141
  * @private
@@ -109,32 +152,67 @@ export default class jmRect extends jmPath {
109
152
  this.dottedLine = this.graph.createShape(jmLine, {style: this.style});
110
153
  }
111
154
 
112
- //如果有边界弧度则借助圆弧对象计算描点
113
- if(location.radius && location.radius < location.width/2 && location.radius < location.height/2) {
155
+ const nr = this.getNormalizedRadius();
156
+ const hasRadius = this.hasRadius();
157
+
158
+ // 如果有圆角(支持四角独立),借助圆弧对象计算描点
159
+ if(hasRadius) {
114
160
  let q = Math.PI / 2;
115
- let arc = this.graph.createShape(jmArc,{radius:location.radius,anticlockwise:false});
116
- arc.center = {x:location.left + location.radius,y:location.top+location.radius};
117
- arc.startAngle = Math.PI;
118
- arc.endAngle = Math.PI + q;
119
- let ps1 = arc.initPoints();
120
-
121
- arc = this.graph.createShape(jmArc,{radius:location.radius,anticlockwise:false});
122
- arc.center = {x:p2.x - location.radius,y:p2.y + location.radius};
123
- arc.startAngle = Math.PI + q;
124
- arc.endAngle = Math.PI * 2;
125
- let ps2 = arc.initPoints();
126
-
127
- arc = this.graph.createShape(jmArc,{radius:location.radius,anticlockwise:false});
128
- arc.center = {x:p3.x - location.radius,y:p3.y - location.radius};
129
- arc.startAngle = 0;
130
- arc.endAngle = q;
131
- let ps3 = arc.initPoints();
132
-
133
- arc = this.graph.createShape(jmArc,{radius:location.radius,anticlockwise:false});
134
- arc.center = {x:p4.x + location.radius,y:p4.y - location.radius};
135
- arc.startAngle = q;
136
- arc.endAngle = Math.PI;
137
- let ps4 = arc.initPoints();
161
+
162
+ // 限制圆角不超过短边的一半
163
+ const maxR = Math.min(location.width / 2, location.height / 2);
164
+ const rtl = Math.min(nr.topLeft, maxR);
165
+ const rtr = Math.min(nr.topRight, maxR);
166
+ const rbr = Math.min(nr.bottomRight, maxR);
167
+ const rbl = Math.min(nr.bottomLeft, maxR);
168
+
169
+ // 左上角圆弧
170
+ if(rtl > 0) {
171
+ let arc = this.graph.createShape(jmArc,{radius:rtl,anticlockwise:false});
172
+ arc.center = {x:location.left + rtl, y:location.top + rtl};
173
+ arc.startAngle = Math.PI;
174
+ arc.endAngle = Math.PI + q;
175
+ var ps1 = arc.initPoints();
176
+ }
177
+ else {
178
+ var ps1 = [p1];
179
+ }
180
+
181
+ // 右上角圆弧
182
+ if(rtr > 0) {
183
+ let arc = this.graph.createShape(jmArc,{radius:rtr,anticlockwise:false});
184
+ arc.center = {x:p2.x - rtr, y:p2.y + rtr};
185
+ arc.startAngle = Math.PI + q;
186
+ arc.endAngle = Math.PI * 2;
187
+ var ps2 = arc.initPoints();
188
+ }
189
+ else {
190
+ var ps2 = [p2];
191
+ }
192
+
193
+ // 右下角圆弧
194
+ if(rbr > 0) {
195
+ let arc = this.graph.createShape(jmArc,{radius:rbr,anticlockwise:false});
196
+ arc.center = {x:p3.x - rbr, y:p3.y - rbr};
197
+ arc.startAngle = 0;
198
+ arc.endAngle = q;
199
+ var ps3 = arc.initPoints();
200
+ }
201
+ else {
202
+ var ps3 = [p3];
203
+ }
204
+
205
+ // 左下角圆弧
206
+ if(rbl > 0) {
207
+ let arc = this.graph.createShape(jmArc,{radius:rbl,anticlockwise:false});
208
+ arc.center = {x:p4.x + rbl, y:p4.y - rbl};
209
+ arc.startAngle = q;
210
+ arc.endAngle = Math.PI;
211
+ var ps4 = arc.initPoints();
212
+ }
213
+ else {
214
+ var ps4 = [p4];
215
+ }
138
216
  this.points = ps1.concat(ps2,ps3,ps4);
139
217
  }
140
218
  else {