3
3
*/
4
4
import { flux } from '../Firefly.js' ;
5
5
6
- import { updateSet , updateMerge } from '../util/WebUtil.js' ;
7
- import { get , has , omit , omitBy , isUndefined , isString } from 'lodash' ;
6
+ import { updateSet , updateMerge , updateDelete } from '../util/WebUtil.js' ;
7
+ import { get , has , omit , omitBy , isEmpty , isUndefined , isString } from 'lodash' ;
8
8
9
9
import { doFetchTable , getColumn , getTblById , isFullyLoaded , cloneRequest } from '../tables/TableUtil.js' ;
10
10
import * as TablesCntlr from '../tables/TablesCntlr.js' ;
@@ -149,7 +149,8 @@ export function loadPlotData (rawAction) {
149
149
150
150
if ( ! serverCallNeeded ) {
151
151
const tableModel = getTblById ( tblId ) ;
152
- xyPlotParams = getUpdatedParams ( xyPlotParams , tableModel ) ;
152
+ const dataBoundaries = getDataBoundaries ( chartModel . xyPlotData ) ;
153
+ xyPlotParams = getUpdatedParams ( xyPlotParams , tableModel , dataBoundaries ) ;
153
154
}
154
155
155
156
dispatch ( { type : LOAD_PLOT_DATA , payload : { chartId, tblId, xyPlotParams, tblSource, serverCallNeeded} } ) ;
@@ -188,6 +189,20 @@ function updatePlotData(data) {
188
189
189
190
export function reduceXYPlot ( state = { } , action = { } ) {
190
191
switch ( action . type ) {
192
+ case ( TablesCntlr . TABLE_LOADED ) :
193
+ {
194
+ const { tbl_id, invokedBy} = action . payload ;
195
+ let updatedState = state ;
196
+ if ( invokedBy !== TablesCntlr . TABLE_SORT ) {
197
+ Object . keys ( state ) . forEach ( ( cid ) => {
198
+ if ( state [ cid ] . tblId === tbl_id && get ( state , [ cid , 'xyPlotParams' , 'boundaries' ] ) ) {
199
+ // do we need hard boundaries, which do not go away on new table data?
200
+ updatedState = updateDelete ( updatedState , [ cid , 'xyPlotParams' ] , 'boundaries' ) ;
201
+ }
202
+ } ) ;
203
+ }
204
+ return updatedState ;
205
+ }
191
206
case ( TablesCntlr . TABLE_REMOVE ) :
192
207
{
193
208
const tbl_id = action . payload . tbl_id ;
@@ -287,8 +302,46 @@ function getServerCallParameters(xyPlotParams) {
287
302
return [ xyPlotParams . x . columnOrExpr , xyPlotParams . y . columnOrExpr , maxBins , xyRatio , xMin , xMax , yMin , yMax ] ;
288
303
}
289
304
305
+ function getDataBoundaries ( xyPlotData ) {
306
+ if ( ! isEmpty ( xyPlotData ) ) {
307
+ return omitBy ( {
308
+ xMin : xyPlotData . xMin ,
309
+ xMax : xyPlotData . xMax ,
310
+ yMin : xyPlotData . yMin ,
311
+ yMax : xyPlotData . yMax
312
+ } , isUndefined ) ;
313
+ }
314
+ }
290
315
291
316
317
+ /**
318
+ * Pad and round data boundaries
319
+ * @param {Object } boundaries - object with xMin, xMax, yMin, yMax props
320
+ * @param {Number } factor - part of the range to add on both sides
321
+ */
322
+ function getPaddedBoundaries ( boundaries , factor = 100 ) {
323
+ if ( ! isEmpty ( boundaries ) ) {
324
+ let { xMin, xMax, yMin, yMax} = boundaries ;
325
+ const xRange = xMax - xMin ;
326
+
327
+ if ( xRange > 0 ) {
328
+ const xPad = xRange / factor ;
329
+ xMin = xMin - xPad ;
330
+ xMax = xMax + xPad ;
331
+ }
332
+ const yRange = yMax - yMin ;
333
+ if ( yRange > 0 ) {
334
+ const yPad = yRange / factor ;
335
+ yMin = yMin - yPad ;
336
+ yMax = yMax + yPad ;
337
+ }
338
+ if ( xRange > 0 || yRange > 0 ) {
339
+ return { xMin, xMax, yMin, yMax} ;
340
+ }
341
+ }
342
+ return boundaries ;
343
+ }
344
+
292
345
/**
293
346
* fetches xy plot data
294
347
* set isColStatsReady to true once done.
@@ -352,7 +405,7 @@ function fetchPlotData(dispatch, tblId, xyPlotParams, chartId) {
352
405
xyPlotParams,
353
406
xyPlotData,
354
407
chartId,
355
- newParams : getUpdatedParams ( xyPlotParams , tableModel )
408
+ newParams : getUpdatedParams ( xyPlotParams , tableModel , getDataBoundaries ( xyPlotData ) )
356
409
} ) ) ;
357
410
}
358
411
) . catch (
@@ -368,32 +421,44 @@ function fetchPlotData(dispatch, tblId, xyPlotParams, chartId) {
368
421
* derive them from existing parameters or tableModel.
369
422
* No selection should be present in updated parameters
370
423
*/
371
- function getUpdatedParams ( xyPlotParams , tableModel ) {
424
+ function getUpdatedParams ( xyPlotParams , tableModel , dataBoundaries ) {
372
425
let newParams = xyPlotParams ;
373
426
374
427
if ( ! get ( xyPlotParams , 'x.label' ) ) {
375
428
newParams = updateSet ( newParams , 'x.label' , get ( xyPlotParams , 'x.columnOrExpr' ) ) ;
376
429
}
377
430
if ( ! get ( xyPlotParams , 'x.unit' ) ) {
378
431
const xColumn = getColumn ( tableModel , get ( xyPlotParams , 'x.columnOrExpr' ) ) ;
379
- const xUnit = get ( xColumn , 'units' ) ;
380
- if ( xUnit ) {
381
- newParams = updateSet ( newParams , 'x.unit' , xUnit ) ;
382
- }
432
+ const xUnit = get ( xColumn , 'units' , '' ) ;
433
+ newParams = updateSet ( newParams , 'x.unit' , xUnit ) ;
383
434
}
384
435
if ( ! get ( xyPlotParams , 'y.label' ) ) {
385
436
newParams = updateSet ( newParams , 'y.label' , get ( xyPlotParams , 'y.columnOrExpr' ) ) ;
386
437
}
387
438
if ( ! get ( xyPlotParams , 'y.unit' ) ) {
388
439
const yColumn = getColumn ( tableModel , get ( xyPlotParams , 'y.columnOrExpr' ) ) ;
389
- const yUnit = get ( yColumn , 'units' ) ;
390
- if ( yUnit ) {
391
- newParams = updateSet ( newParams , 'y.unit' , yUnit ) ;
392
- }
440
+ const yUnit = get ( yColumn , 'units' , '' ) ;
441
+ newParams = updateSet ( newParams , 'y.unit' , yUnit ) ;
393
442
}
394
443
if ( get ( xyPlotParams , 'selection' ) ) {
395
444
newParams = updateSet ( newParams , 'selection' , undefined ) ;
396
445
}
446
+
447
+ // set plot boundaries,
448
+ // if user set boundaries are undefined, use data boundaries
449
+ const userSetBoundaries = get ( xyPlotParams , 'userSetBoundaries' , { } ) ;
450
+ const boundaries = Object . assign ( { } , userSetBoundaries ) ;
451
+ if ( Object . keys ( boundaries ) . length < 4 && ! isEmpty ( dataBoundaries ) ) {
452
+ const paddedDataBoundaries = getPaddedBoundaries ( dataBoundaries ) ;
453
+ const [ xMin , xMax , yMin , yMax ] = [ 'xMin' , 'xMax' , 'yMin' , 'yMax' ] . map ( ( v ) => {
454
+ return ( Number . isFinite ( boundaries [ v ] ) ? boundaries [ v ] : paddedDataBoundaries [ v ] ) ;
455
+ } ) ;
456
+ const newBoundaries = omitBy ( { xMin, xMax, yMin, yMax} , isUndefined ) ;
457
+ if ( ! isEmpty ( newBoundaries ) ) {
458
+ newParams = updateSet ( newParams , 'boundaries' , newBoundaries ) ;
459
+ }
460
+ }
461
+
397
462
return newParams ;
398
463
}
399
464
0 commit comments