@@ -30,7 +30,9 @@ import { CoordinateSystemMaster, CoordinateSystem } from './CoordinateSystem';
30
30
import GlobalModel from '../model/Global' ;
31
31
import { ParsedModelFinder , ParsedModelFinderKnown } from '../util/model' ;
32
32
import { parsePercent } from '../util/number' ;
33
- import type ExtensionAPI from '../core/ExtensionAPI' ;
33
+ import { RoamOptionMixin } from '../util/types' ;
34
+ import { clone } from 'zrender/src/core/util' ;
35
+ import ExtensionAPI from '../core/ExtensionAPI' ;
34
36
35
37
const v2ApplyTransform = vector . applyTransform ;
36
38
@@ -65,17 +67,20 @@ class View extends Transformable implements CoordinateSystemMaster, CoordinateSy
65
67
/**
66
68
* This is a user specified point on the source, which will be
67
69
* located to the center of the `View['_viewRect']`.
68
- * The unit this the same as ` View['_rect']`.
70
+ * The unit and the origin of this point is the same as that of `[ View['_rect']`.
69
71
*/
70
72
private _center : number [ ] ;
73
+ private _centerOption : RoamOptionMixin [ 'center' ] ;
74
+
71
75
private _zoom : number ;
72
76
73
77
/**
74
78
* The rect of the source, where the measure is used by "data" and "center".
75
79
* Has nothing to do with roam/zoom.
76
80
* The unit is defined by the source. For example,
77
- * for geo source the unit is lat/lng,
78
- * for SVG source the unit is the same as the width/height defined in SVG.
81
+ * - for geo source the unit is lat/lng,
82
+ * - for SVG source the unit is the same as the width/height defined in SVG.
83
+ * - for series.graph/series.tree/series.sankey the uiit is px.
79
84
*/
80
85
private _rect : BoundingRect ;
81
86
/**
@@ -91,6 +96,7 @@ class View extends Transformable implements CoordinateSystemMaster, CoordinateSy
91
96
92
97
setBoundingRect ( x : number , y : number , width : number , height : number ) : BoundingRect {
93
98
this . _rect = new BoundingRect ( x , y , width , height ) ;
99
+ this . _updateCenterAndZoom ( ) ;
94
100
return this . _rect ;
95
101
}
96
102
@@ -126,16 +132,33 @@ class View extends Transformable implements CoordinateSystemMaster, CoordinateSy
126
132
}
127
133
128
134
/**
129
- * Set center of view
135
+ * [NOTICE]
136
+ * The definition of this center has always been irrelevant to some other series center like
137
+ * 'series-pie.center' - this center is a point on the same coord sys as `View['_rect'].x/y`,
138
+ * rather than canvas viewport, and the unit is not necessarily pixel (e.g., in geo case).
139
+ * @see {View['_center']} for details.
130
140
*/
131
- setCenter ( centerCoord : ( number | string ) [ ] , api : ExtensionAPI ) : void {
132
- if ( ! centerCoord ) {
133
- return ;
141
+ setCenter (
142
+ centerCoord : RoamOptionMixin [ 'center' ] ,
143
+ opt ?: {
144
+ // Only for backward compat.
145
+ ecModel ?: GlobalModel
146
+ api ?: ExtensionAPI
147
+ }
148
+ ) : void {
149
+ // #16904 introcuded percentage string here, such as '33%'. But it was based on canvas
150
+ // width/height, which is not reasonable - the unit may incorrect, and it is unpredictable if
151
+ // the `View['_rect']` is not calculated based on the current canvas rect. Therefore the percentage
152
+ // value is changed to based on `View['_rect'].width/height` since v6. Under this definition, users
153
+ // can use '0%' to map the top-left of `View['_rect']` to the center of `View['_viewRect']`.
154
+ if ( opt && opt . api && opt . ecModel && opt . ecModel . getShallow ( 'legacyViewCoordSysCenterBase' ) && centerCoord ) {
155
+ centerCoord = [
156
+ parsePercent ( centerCoord [ 0 ] , opt . api . getWidth ( ) ) ,
157
+ parsePercent ( centerCoord [ 1 ] , opt . api . getWidth ( ) )
158
+ ] ;
134
159
}
135
- this . _center = [
136
- parsePercent ( centerCoord [ 0 ] , api . getWidth ( ) ) ,
137
- parsePercent ( centerCoord [ 1 ] , api . getHeight ( ) )
138
- ] ;
160
+
161
+ this . _centerOption = clone ( centerCoord ) ;
139
162
this . _updateCenterAndZoom ( ) ;
140
163
}
141
164
@@ -181,9 +204,19 @@ class View extends Transformable implements CoordinateSystemMaster, CoordinateSy
181
204
}
182
205
183
206
/**
184
- * Remove roam
207
+ * Ensure this method is idempotent, since it should be called when
208
+ * every relevant prop (e.g. _centerOption/_zoom/_rect/_viewRect) changed.
185
209
*/
186
210
private _updateCenterAndZoom ( ) : void {
211
+ const centerOption = this . _centerOption ;
212
+ const rect = this . _rect ;
213
+ if ( centerOption && rect ) {
214
+ this . _center = [
215
+ parsePercent ( centerOption [ 0 ] , rect . width , rect . x ) ,
216
+ parsePercent ( centerOption [ 1 ] , rect . height , rect . y )
217
+ ] ;
218
+ }
219
+
187
220
// Must update after view transform updated
188
221
const rawTransformMatrix = this . _rawTransformable . getLocalTransform ( ) ;
189
222
const roamTransform = this . _roamTransformable ;
0 commit comments