3
3
*/
4
4
5
5
import { has , get , isUndefined , omit } from 'lodash' ;
6
+ import shallowequal from 'shallowequal' ;
6
7
7
8
import { flux } from '../Firefly.js' ;
8
- import { updateSet , updateMerge } from '../util/WebUtil.js' ;
9
+ import { updateDelete , updateSet , updateMerge } from '../util/WebUtil.js' ;
9
10
10
11
import * as TablesCntlr from '../tables/TablesCntlr.js' ;
12
+ import { reduceXYPlot } from './XYPlotCntlr.js' ;
13
+ import { reduceHistogram } from './HistogramCntlr.js' ;
11
14
12
15
export const CHART_SPACE_PATH = 'charts' ;
13
16
export const UI_PREFIX = `${ CHART_SPACE_PATH } .ui` ;
@@ -62,57 +65,125 @@ export function dispatchDelete(tblId, chartId, chartType, dispatcher= flux.proce
62
65
const uniqueId = ( chartId , chartType ) => { return `${ chartType } |${ chartId } ` ; } ;
63
66
const isChartType = ( uChartId , chartType ) => { return uChartId . startsWith ( chartType ) ; } ;
64
67
68
+
69
+ /*
70
+ Possible structure of store:
71
+ /ui
72
+ expanded: Object - the information about expanded chart
73
+ {
74
+ chartId: string
75
+ tblId: string
76
+ chartType: string, ex. 'scatter', 'histogram'
77
+ }
78
+ /tbl
79
+ tblId: Object - the name of this node matches table id
80
+ {
81
+ uChartId: Object - the name of this node matches 'chartType|chartId'
82
+ {
83
+ mounted: boolean,
84
+ n: number, undefined means 1
85
+ }
86
+ }
87
+ /xyplot - parameters and data for scatter plot, see XYPlotCntlr
88
+ /histogram - parameters and data for histogram plot, see HistogramCntlr
89
+ */
90
+
91
+ export function reducer ( state = { ui :{ } , tbl : { } , xyplot :{ } , histogram :{ } } , action = { } ) {
92
+
93
+ if ( ! action . type . startsWith ( TablesCntlr . DATA_PREFIX ) && ! action . type . startsWith ( CHART_SPACE_PATH ) ) {
94
+ return state ;
95
+ }
96
+
97
+ const nstate = { ...state } ;
98
+
99
+ nstate . xyplot = reduceXYPlot ( state [ 'xyplot' ] , action ) ;
100
+ nstate . histogram = reduceHistogram ( state [ 'histogram' ] , action ) ;
101
+
102
+ // generic for all chart types
103
+ nstate . ui = reduceUI ( state [ 'ui' ] , action ) ;
104
+ // organized by table id
105
+ nstate . tbl = reduceByTbl ( state [ 'tbl' ] , action ) ;
106
+
107
+ if ( shallowequal ( state , nstate ) ) {
108
+ return state ;
109
+ } else {
110
+ return nstate ;
111
+ }
112
+ }
113
+
65
114
const chartActions = [ CHART_UI_EXPANDED , CHART_MOUNTED , CHART_UNMOUNTED , DELETE ] ;
66
115
67
- export function reducer ( state = { ui :{ } } , action = { } ) {
116
+ /**
117
+ * @param state - ui part of chart state
118
+ * @param action - action
119
+ * @returns {* } - updated ui part of the state
120
+ */
121
+ function reduceUI ( state = { } , action = { } ) {
122
+ if ( chartActions . indexOf ( action . type ) > - 1 ) {
123
+ const { chartId, tblId, chartType} = action . payload ;
124
+ switch ( action . type ) {
125
+ case ( CHART_UI_EXPANDED ) :
126
+ return updateSet ( state , 'expanded' , { chartId, tblId, chartType} ) ;
127
+ default :
128
+ return state ;
129
+ }
130
+ } else {
131
+ return state ;
132
+ }
133
+
134
+ }
135
+
136
+
137
+ /**
138
+ *
139
+ * @param state - by table part of chart state, stores info which charts are mounted
140
+ * @param action - action
141
+ * @returns {* } - new by table part of chart state
142
+ */
143
+ function reduceByTbl ( state = { } , action = { } ) {
68
144
if ( action . type === TablesCntlr . TABLE_REMOVE ) {
69
145
const { tbl_id} = action . payload ;
70
146
if ( has ( state , tbl_id ) ) {
71
- return Object . assign ( { } , omit ( state , [ tbl_id ] ) ) ;
147
+ return omit ( state , [ tbl_id ] ) ;
72
148
}
73
149
return state ;
74
150
} else if ( chartActions . indexOf ( action . type ) > - 1 ) {
75
151
const { chartId, tblId, chartType} = action . payload ;
76
152
const uChartId = uniqueId ( chartId , chartType ) ;
77
153
switch ( action . type ) {
78
-
79
- case ( CHART_UI_EXPANDED ) :
80
- //return updateSet(root, 'expanded', {chartId, tblId});
81
- return updateSet ( state , 'ui.expanded' , { chartId, tblId, chartType} ) ;
82
154
case ( CHART_MOUNTED ) :
83
-
84
- if ( ! has ( state , [ 'tbl' , tblId ] ) ) {
85
- return updateSet ( state , [ 'tbl' , tblId ] , { [ uChartId ] : { mounted : true } } ) ;
155
+ if ( ! has ( state , tblId ) ) {
156
+ return updateSet ( state , tblId , { [ uChartId ] : { mounted : true } } ) ;
86
157
} else {
87
- if ( get ( state , [ 'tbl' , tblId , uChartId , 'mounted' ] ) ) {
158
+ if ( get ( state , [ tblId , uChartId , 'mounted' ] ) ) {
88
159
//other version of the same chart is mounted
89
- let n = get ( state , [ 'tbl' , tblId , uChartId , 'n' ] ) ;
160
+ let n = get ( state , [ tblId , uChartId , 'n' ] ) ;
90
161
n = n ? Number ( n ) : 1 ;
91
- return updateMerge ( state , [ 'tbl' , tblId , uChartId ] , { upToDate : true , n : n + 1 } ) ;
162
+ return updateMerge ( state , [ tblId , uChartId ] , { upToDate : true , n : n + 1 } ) ;
92
163
} else {
93
- return updateSet ( state , [ 'tbl' , tblId , uChartId ] , { mounted : true } ) ;
164
+ return updateSet ( state , [ tblId , uChartId ] , { mounted : true } ) ;
94
165
}
95
166
}
96
167
case ( CHART_UNMOUNTED ) :
97
- if ( has ( state , [ 'tbl' , tblId ] ) ) {
98
- if ( get ( state , [ 'tbl' , tblId , uChartId , 'mounted' ] ) ) {
99
- let n = get ( state , [ 'tbl' , tblId , uChartId , 'n' ] ) ;
168
+ if ( has ( state , [ tblId ] ) ) {
169
+ if ( get ( state , [ tblId , uChartId , 'mounted' ] ) ) {
170
+ let n = get ( state , [ tblId , uChartId , 'n' ] ) ;
100
171
n = n ? Number ( n ) : 1 ;
101
172
if ( n > 1 ) {
102
173
//multiple versions of the same chart are mounted
103
- return updateMerge ( state , [ 'tbl' , tblId , uChartId ] , { n : n - 1 } ) ;
174
+ return updateMerge ( state , [ tblId , uChartId ] , { n : n - 1 } ) ;
175
+ } else {
176
+ return updateSet ( state , [ tblId , uChartId ] , { mounted : false } ) ;
104
177
}
105
- } else {
106
- return updateSet ( state , [ 'tbl' , tblId , uChartId ] , { mounted : false } ) ;
107
178
}
108
179
}
109
180
return state ;
110
181
case ( DELETE ) :
111
- if ( has ( state , [ 'tbl' , tblId , uChartId ] ) ) {
112
- if ( Object . keys ( state [ 'tbl' ] [ tblId ] ) . length > 1 ) {
113
- return updateSet ( state , [ 'tbl' , tblId ] , omit ( state [ 'tbl' ] [ tblId ] , [ uChartId ] ) ) ;
182
+ if ( has ( state , [ tblId , uChartId ] ) ) {
183
+ if ( Object . keys ( state [ tblId ] ) . length > 1 ) {
184
+ return updateDelete ( state , tblId , uChartId ) ;
114
185
} else {
115
- return updateSet ( state , 'tbl' , omit ( state [ 'tbl' ] , [ tblId ] ) ) ;
186
+ return omit ( state , [ tblId ] ) ;
116
187
}
117
188
}
118
189
return state ;
@@ -122,6 +193,7 @@ export function reducer(state={ui:{}}, action={}) {
122
193
} else {
123
194
return state ;
124
195
}
196
+
125
197
}
126
198
127
199
@@ -154,4 +226,4 @@ export function getNumRelatedCharts(tblId, mounted, chartType) {
154
226
export function isChartMounted ( tblId , chartId , chartType ) {
155
227
const uChartId = uniqueId ( chartId , chartType ) ;
156
228
return Boolean ( get ( flux . getState ( ) , [ CHART_SPACE_PATH , 'tbl' , tblId , uChartId , 'mounted' ] ) ) ;
157
- }
229
+ }
0 commit comments