@@ -96,31 +96,59 @@ export function mouseDown(chart, event) {
9696 addHandler ( chart , window . document , 'keydown' , keyDown ) ;
9797}
9898
99- export function computeDragRect ( chart , mode , beginPointEvent , endPointEvent ) {
99+ function applyAspectRatio ( endPoint , beginPoint , aspectRatio ) {
100+ let width = endPoint . x - beginPoint . x ;
101+ let height = endPoint . y - beginPoint . y ;
102+ const ratio = Math . abs ( width / height ) ;
103+
104+ if ( ratio > aspectRatio ) {
105+ width = Math . sign ( width ) * Math . abs ( height * aspectRatio ) ;
106+ } else if ( ratio < aspectRatio ) {
107+ height = Math . sign ( height ) * Math . abs ( width / aspectRatio ) ;
108+ }
109+
110+ endPoint . x = beginPoint . x + width ;
111+ endPoint . y = beginPoint . y + height ;
112+ }
113+
114+ function applyMinMaxProps ( rect , beginPoint , endPoint , { min, max, prop} ) {
115+ rect [ min ] = Math . max ( 0 , Math . min ( beginPoint [ prop ] , endPoint [ prop ] ) ) ;
116+ rect [ max ] = Math . max ( beginPoint [ prop ] , endPoint [ prop ] ) ;
117+ }
118+
119+ function getReplativePoints ( chart , points , maintainAspectRatio ) {
120+ const beginPoint = getPointPosition ( points . dragStart , chart ) ;
121+ const endPoint = getPointPosition ( points . dragEnd , chart ) ;
122+
123+ if ( maintainAspectRatio ) {
124+ const aspectRatio = chart . chartArea . width / chart . chartArea . height ;
125+ applyAspectRatio ( endPoint , beginPoint , aspectRatio ) ;
126+ }
127+
128+ return { beginPoint, endPoint} ;
129+ }
130+
131+ export function computeDragRect ( chart , mode , points , maintainAspectRatio ) {
100132 const xEnabled = directionEnabled ( mode , 'x' , chart ) ;
101133 const yEnabled = directionEnabled ( mode , 'y' , chart ) ;
102- let { top, left, right, bottom, width : chartWidth , height : chartHeight } = chart . chartArea ;
134+ const { top, left, right, bottom, width : chartWidth , height : chartHeight } = chart . chartArea ;
135+ const rect = { top, left, right, bottom} ;
103136
104- const beginPoint = getPointPosition ( beginPointEvent , chart ) ;
105- const endPoint = getPointPosition ( endPointEvent , chart ) ;
137+ const { beginPoint, endPoint} = getReplativePoints ( chart , points , maintainAspectRatio && xEnabled && yEnabled ) ;
106138
107139 if ( xEnabled ) {
108- left = Math . max ( 0 , Math . min ( beginPoint . x , endPoint . x ) ) ;
109- right = Math . min ( chart . width , Math . max ( beginPoint . x , endPoint . x ) ) ;
140+ applyMinMaxProps ( rect , beginPoint , endPoint , { min : 'left' , max : 'right' , prop : 'x' } ) ;
110141 }
111142
112143 if ( yEnabled ) {
113- top = Math . max ( 0 , Math . min ( beginPoint . y , endPoint . y ) ) ;
114- bottom = Math . min ( chart . height , Math . max ( beginPoint . y , endPoint . y ) ) ;
144+ applyMinMaxProps ( rect , beginPoint , endPoint , { min : 'top' , max : 'bottom' , prop : 'y' } ) ;
115145 }
116- const width = right - left ;
117- const height = bottom - top ;
146+
147+ const width = rect . right - rect . left ;
148+ const height = rect . bottom - rect . top ;
118149
119150 return {
120- left,
121- top,
122- right,
123- bottom,
151+ ...rect ,
124152 width,
125153 height,
126154 zoomX : xEnabled && width ? 1 + ( ( chartWidth - width ) / chartWidth ) : 1 ,
@@ -135,8 +163,8 @@ export function mouseUp(chart, event) {
135163 }
136164
137165 removeHandler ( chart , 'mousemove' ) ;
138- const { mode, onZoomComplete, drag : { threshold = 0 } } = state . options . zoom ;
139- const rect = computeDragRect ( chart , mode , state . dragStart , event ) ;
166+ const { mode, onZoomComplete, drag : { threshold = 0 , maintainAspectRatio } } = state . options . zoom ;
167+ const rect = computeDragRect ( chart , mode , { dragStart : state . dragStart , dragEnd : event } , maintainAspectRatio ) ;
140168 const distanceX = directionEnabled ( mode , 'x' , chart ) ? rect . width : 0 ;
141169 const distanceY = directionEnabled ( mode , 'y' , chart ) ? rect . height : 0 ;
142170 const distance = Math . sqrt ( distanceX * distanceX + distanceY * distanceY ) ;
0 commit comments