@@ -3,7 +3,7 @@ import Element from '../core/core.element';
33import { each , noop , isNullOrUndef , isArray , _elementsEqual } from '../helpers/helpers.core' ;
44import { toFont , toPadding } from '../helpers/helpers.options' ;
55import { getRtlAdapter , overrideTextDirection , restoreTextDirection } from '../helpers/helpers.rtl' ;
6- import { distanceBetweenPoints } from '../helpers/helpers.math' ;
6+ import { distanceBetweenPoints , _limitValue } from '../helpers/helpers.math' ;
77import { drawPoint } from '../helpers' ;
88
99/**
@@ -211,76 +211,67 @@ function getTooltipSize(tooltip, options) {
211211 return { width, height} ;
212212}
213213
214- /**
215- * Helper to get the alignment of a tooltip given the size
216- */
217- function determineAlignment ( chart , options , size ) {
218- const { x, y, width, height} = size ;
219- const chartArea = chart . chartArea ;
220- let xAlign = 'center' ;
221- let yAlign = 'center' ;
214+ function determineYAlign ( chart , size ) {
215+ const { y, height} = size ;
222216
223217 if ( y < height / 2 ) {
224- yAlign = 'top' ;
218+ return 'top' ;
225219 } else if ( y > ( chart . height - height / 2 ) ) {
226- yAlign = 'bottom' ;
220+ return 'bottom' ;
227221 }
222+ return 'center' ;
223+ }
228224
229- let lf , rf ; // functions to determine left, right alignment
230- const midX = ( chartArea . left + chartArea . right ) / 2 ;
231- const midY = ( chartArea . top + chartArea . bottom ) / 2 ;
225+ function doesNotFitWithAlign ( xAlign , chart , options , size ) {
226+ const { x, width} = size ;
227+ const caret = options . caretSize + options . caretPadding ;
228+ if ( xAlign === 'left' && x + width + caret > chart . width ) {
229+ return true ;
230+ }
232231
233- if ( yAlign === 'center' ) {
234- lf = ( value ) => value <= midX ;
235- rf = ( value ) => value > midX ;
236- } else {
237- lf = ( value ) => value <= ( width / 2 ) ;
238- rf = ( value ) => value >= ( chart . width - ( width / 2 ) ) ;
232+ if ( xAlign === 'right' && x - width - caret < 0 ) {
233+ return true ;
239234 }
235+ }
240236
241- // functions to determine if left/right alignment causes tooltip to go outside chart
242- const olf = ( value ) => value + width + options . caretSize + options . caretPadding > chart . width ;
243- const orf = ( value ) => value - width - options . caretSize - options . caretPadding < 0 ;
244- // function to get the y alignment if the tooltip goes outside of the left or right edges
245- const yf = ( value ) => value <= midY ? 'top' : 'bottom' ;
237+ function determineXAlign ( chart , options , size , yAlign ) {
238+ const { x, width} = size ;
239+ const { width : chartWidth , chartArea : { left, right} } = chart ;
240+ let xAlign = 'center' ;
246241
247- if ( lf ( x ) ) {
242+ if ( yAlign === 'center' ) {
243+ xAlign = x <= ( left + right ) / 2 ? 'left' : 'right' ;
244+ } else if ( x <= width / 2 ) {
248245 xAlign = 'left' ;
249-
250- // Is tooltip too wide and goes over the right side of the chart.?
251- if ( olf ( x ) ) {
252- xAlign = 'center' ;
253- yAlign = yf ( y ) ;
254- }
255- } else if ( rf ( x ) ) {
246+ } else if ( x >= chartWidth - width / 2 ) {
256247 xAlign = 'right' ;
248+ }
257249
258- // Is tooltip too wide and goes outside left edge of canvas?
259- if ( orf ( x ) ) {
260- xAlign = 'center' ;
261- yAlign = yf ( y ) ;
262- }
250+ if ( doesNotFitWithAlign ( xAlign , chart , options , size ) ) {
251+ xAlign = 'center' ;
263252 }
264253
254+ return xAlign ;
255+ }
256+
257+ /**
258+ * Helper to get the alignment of a tooltip given the size
259+ */
260+ function determineAlignment ( chart , options , size ) {
261+ const yAlign = options . yAlign || determineYAlign ( chart , size ) ;
262+
265263 return {
266- xAlign : options . xAlign ? options . xAlign : xAlign ,
267- yAlign : options . yAlign ? options . yAlign : yAlign
264+ xAlign : options . xAlign || determineXAlign ( chart , options , size , yAlign ) ,
265+ yAlign
268266 } ;
269267}
270268
271- function alignX ( size , xAlign , chartWidth ) {
272- // eslint-disable-next-line prefer-const
269+ function alignX ( size , xAlign ) {
273270 let { x, width} = size ;
274271 if ( xAlign === 'right' ) {
275272 x -= width ;
276273 } else if ( xAlign === 'center' ) {
277274 x -= ( width / 2 ) ;
278- if ( x + width > chartWidth ) {
279- x = chartWidth - width ;
280- }
281- if ( x < 0 ) {
282- x = 0 ;
283- }
284275 }
285276 return x ;
286277}
@@ -307,7 +298,7 @@ function getBackgroundPoint(options, size, alignment, chart) {
307298 const paddingAndSize = caretSize + caretPadding ;
308299 const radiusAndPadding = cornerRadius + caretPadding ;
309300
310- let x = alignX ( size , xAlign , chart . width ) ;
301+ let x = alignX ( size , xAlign ) ;
311302 const y = alignY ( size , yAlign , paddingAndSize ) ;
312303
313304 if ( yAlign === 'center' ) {
@@ -322,7 +313,10 @@ function getBackgroundPoint(options, size, alignment, chart) {
322313 x += radiusAndPadding ;
323314 }
324315
325- return { x, y} ;
316+ return {
317+ x : _limitValue ( x , 0 , chart . width - size . width ) ,
318+ y : _limitValue ( y , 0 , chart . height - size . height )
319+ } ;
326320}
327321
328322function getAlignedX ( tooltip , align , options ) {
0 commit comments