1- import { ColumnType , type Cell , Board , ColumnDef } from './board' ; // replace with the actual path to your 'board' module
1+ import { ColumnType , SumType , type Cell , Board , ColumnDef } from './board' ; // replace with the actual path to your 'board' module
22import { decodeHashFromBase64 } from "@holochain/client" ;
33import type { EntryHash } from "@holochain/client" ;
44import { stringToColor } from './util' ; // replace with the actual path to your 'util' module
@@ -53,4 +53,277 @@ export async function getValueOfCell(tableHash: EntryHash, rowId: string, column
5353 }
5454 } , reject ) ;
5555 } ) ;
56+ }
57+
58+ export async function getValueOfColumnSummary ( tableHash : EntryHash , columnId : string , sumType :SumType , store : TablesStore , query : string = "true" , ) {
59+ return new Promise ( ( resolve , reject ) => {
60+ store . boardList . boardData2 . get ( tableHash ) . subscribe ( ( boardData ) => {
61+ if ( ! boardData ) {
62+ throw new Error ( `Table with id ${ tableHash } not found` ) ;
63+ }
64+
65+ if ( ! boardData . value || ! boardData . value . latestState ) {
66+ throw new Error ( `No latest state found for table ${ tableHash } ` ) ;
67+ }
68+
69+ const def = boardData . value . latestState . columnDefs . find ( def => def . id === columnId ) ;
70+ if ( ! def ) {
71+ throw new Error ( `Column definition for column id ${ columnId } not found in table ${ tableHash } ` ) ;
72+ }
73+
74+ let querriedData = boardData . value . latestState . rows . filter ( row => {
75+ let subbedQuery = query
76+ Object . keys ( row . cells ) . forEach ( ( cellId ) => {
77+ let value : any = '"' + row . cells [ cellId ] ?. value + '"'
78+ if ( boardData . value . latestState . columnDefs . find ( ( col ) => col . id === cellId ) ?. type === 1 ) {
79+ const tempValue = parseInt ( row . cells [ cellId ] ?. value )
80+ if ( ! isNaN ( tempValue ) ) {
81+ value = tempValue
82+ }
83+ }
84+ subbedQuery = subbedQuery . replace ( new RegExp ( cellId , 'g' ) , value ) ;
85+ subbedQuery = subbedQuery . replace ( new RegExp ( 'contains' , 'g' ) , 'includes' ) ;
86+ } )
87+ try {
88+ return eval ( subbedQuery ) ? true : false
89+ } catch {
90+ return false
91+ }
92+ } )
93+
94+ switch ( Number ( sumType ) ) {
95+ case SumType . Sum :
96+ let sum = Object . values ( querriedData ) . reduce ( ( acc , row ) => {
97+ const cell = row . cells [ def . id ] ;
98+ if ( cell && cell . value ) {
99+ return acc + Number ( cell . value . replace ( / [ ^ 0 - 9 - .] / g, '' ) ) ;
100+ }
101+ return acc ;
102+ } , 0 )
103+ resolve ( sum ) ;
104+ break
105+ case SumType . Count :
106+ resolve ( querriedData . length ) ;
107+ break ;
108+ case SumType . Average :
109+ console . log ( "average" )
110+ let sum2 = Object . values ( querriedData ) . reduce ( ( acc , row ) => {
111+ const cell = row . cells [ def . id ] ;
112+ if ( cell && cell . value ) {
113+ return acc + Number ( cell . value . replace ( / [ ^ 0 - 9 - .] / g, '' ) ) ;
114+ }
115+ return acc ;
116+ } , 0 )
117+ console . log ( "sum2" , sum2 )
118+ resolve ( sum2 / querriedData . length ) ;
119+ break ;
120+
121+ case SumType . Max :
122+ let max = Object . values ( querriedData ) . reduce ( ( acc , row ) => {
123+ const cell = row . cells [ def . id ] ;
124+ if ( cell && cell . value ) {
125+ return Math . max ( acc , Number ( cell . value . replace ( / [ ^ 0 - 9 - .] / g, '' ) ) ) ;
126+ }
127+ return acc ;
128+ } , Number . MIN_SAFE_INTEGER )
129+ resolve ( max ) ;
130+ break ;
131+
132+ case SumType . Min :
133+ let min = Object . values ( querriedData ) . reduce ( ( acc , row ) => {
134+ const cell = row . cells [ def . id ] ;
135+ if ( cell && cell . value ) {
136+ return Math . min ( acc , Number ( cell . value . replace ( / [ ^ 0 - 9 - .] / g, '' ) ) ) ;
137+ }
138+ return acc ;
139+ } , Number . MAX_SAFE_INTEGER )
140+ resolve ( min ) ;
141+ break ;
142+
143+ case SumType . Median :
144+ let values = Object . values ( querriedData ) . map ( ( row ) => {
145+ const cell = row . cells [ def . id ] ;
146+ if ( cell && cell . value ) {
147+ return Number ( cell . value . replace ( / [ ^ 0 - 9 - .] / g, '' ) ) ;
148+ }
149+ return 0 ;
150+ } )
151+ values . sort ( ( a , b ) => a - b ) ;
152+ let median = 0 ;
153+ if ( values . length % 2 === 0 ) {
154+ median = ( values [ values . length / 2 - 1 ] + values [ values . length / 2 ] ) / 2 ;
155+ } else {
156+ median = values [ ( values . length - 1 ) / 2 ] ;
157+ }
158+ resolve ( median ) ;
159+ break ;
160+
161+ case SumType . Mode :
162+ let modeMap = { } ;
163+ let maxCount = 0 ;
164+ let modes = [ ] ;
165+ Object . values ( querriedData ) . forEach ( ( row ) => {
166+ const cell = row . cells [ def . id ] ;
167+ if ( cell && cell . value ) {
168+ let val = Number ( cell . value . replace ( / [ ^ 0 - 9 - .] / g, '' ) ) ;
169+ modeMap [ val ] = ( modeMap [ val ] || 0 ) + 1 ;
170+ if ( modeMap [ val ] > maxCount ) {
171+ modes = [ val ] ;
172+ maxCount = modeMap [ val ] ;
173+ } else if ( modeMap [ val ] === maxCount ) {
174+ modes . push ( val ) ;
175+ }
176+ }
177+ } )
178+ resolve ( modes ) ;
179+ break ;
180+
181+ case SumType . Range :
182+ let values2 = Object . values ( querriedData ) . map ( ( row ) => {
183+ const cell = row . cells [ def . id ] ;
184+ if ( cell && cell . value ) {
185+ return Number ( cell . value . replace ( / [ ^ 0 - 9 - .] / g, '' ) ) ;
186+ }
187+ return 0 ;
188+ } )
189+ values2 . sort ( ( a , b ) => a - b ) ;
190+ let range = values2 [ values2 . length - 1 ] - values2 [ 0 ] ;
191+ resolve ( range ) ;
192+ break ;
193+
194+ case SumType . StDeviation :
195+ let values3 = Object . values ( querriedData ) . map ( ( row ) => {
196+ const cell = row . cells [ def . id ] ;
197+ if ( cell && cell . value ) {
198+ return Number ( cell . value . replace ( / [ ^ 0 - 9 - .] / g, '' ) ) ;
199+ }
200+ return 0 ;
201+ } )
202+ let mean = values3 . reduce ( ( acc , val ) => acc + val , 0 ) / values3 . length ;
203+ let stDeviation = Math . sqrt ( values3 . reduce ( ( acc , val ) => acc + ( val - mean ) ** 2 , 0 ) / values3 . length ) ;
204+ resolve ( stDeviation ) ;
205+ break ;
206+
207+ case SumType . Filled :
208+ let filled = Object . values ( querriedData ) . reduce ( ( acc , row ) => {
209+ const cell = row . cells [ def . id ] ;
210+ if ( cell && cell . value ) {
211+ return acc + 1 ;
212+ }
213+ return acc ;
214+ } , 0 )
215+ resolve ( filled ) ;
216+ break ;
217+
218+ case SumType . Empty :
219+ let empty = Object . values ( querriedData ) . reduce ( ( acc , row ) => {
220+ const cell = row . cells [ def . id ] ;
221+ if ( ! cell || ! cell . value ) {
222+ return acc + 1 ;
223+ }
224+ return acc ;
225+ } , 0 )
226+ resolve ( empty ) ;
227+ break ;
228+
229+ case SumType . Unique :
230+ let unique = new Set ( Object . values ( querriedData ) . map ( ( row ) => {
231+ const cell = row . cells [ def . id ] ;
232+ if ( cell && cell . value ) {
233+ return cell . value ;
234+ }
235+ return "" ;
236+ } ) ) . size ;
237+ resolve ( unique ) ;
238+ break ;
239+
240+ default :
241+ resolve ( "--" ) ;
242+ break
243+
244+ }
245+ } , reject ) ;
246+ } ) ;
247+ }
248+
249+ export async function getColumnValues ( tableHash : EntryHash , columnId : string , store : TablesStore ) {
250+ return new Promise ( ( resolve , reject ) => {
251+ store . boardList . boardData2 . get ( tableHash ) . subscribe ( ( boardData ) => {
252+ if ( ! boardData ) {
253+ throw new Error ( `Table with id ${ tableHash } not found` ) ;
254+ }
255+
256+ if ( ! boardData . value || ! boardData . value . latestState ) {
257+ throw new Error ( `No latest state found for table ${ tableHash } ` ) ;
258+ }
259+
260+ const def = boardData . value . latestState . columnDefs . find ( def => def . id === columnId ) ;
261+ if ( ! def ) {
262+ throw new Error ( `Column definition for column id ${ columnId } not found in table ${ tableHash } ` ) ;
263+ }
264+
265+ const values = Object . values ( boardData . value . latestState . rows ) . map ( row => {
266+ const cell = row . cells [ columnId ] ;
267+ if ( cell && cell . value ) {
268+ return cell . value ;
269+ }
270+ return "" ;
271+ } ) ;
272+
273+ resolve ( values ) ;
274+ } , reject ) ;
275+ } ) ;
276+ }
277+
278+ export async function getRowValues ( tableHash : EntryHash , rowId : string , store : TablesStore ) {
279+ return new Promise ( ( resolve , reject ) => {
280+ store . boardList . boardData2 . get ( tableHash ) . subscribe ( ( boardData ) => {
281+ if ( ! boardData ) {
282+ throw new Error ( `Table with id ${ tableHash } not found` ) ;
283+ }
284+
285+ if ( ! boardData . value || ! boardData . value . latestState ) {
286+ throw new Error ( `No latest state found for table ${ tableHash } ` ) ;
287+ }
288+
289+ const row = boardData . value . latestState . rows . find ( r => r . id === rowId ) ;
290+ if ( ! row ) {
291+ throw new Error ( `Row with id ${ rowId } not found in table ${ tableHash } ` ) ;
292+ }
293+
294+ const values = Object . values ( row . cells ) . map ( cell => {
295+ if ( cell && cell . value ) {
296+ return cell . value ;
297+ }
298+ return "" ;
299+ } ) ;
300+
301+ resolve ( values ) ;
302+ } , reject ) ;
303+ } ) ;
304+ }
305+
306+ export async function getTableValues ( tableHash : EntryHash , store : TablesStore ) {
307+ return new Promise ( ( resolve , reject ) => {
308+ store . boardList . boardData2 . get ( tableHash ) . subscribe ( ( boardData ) => {
309+ if ( ! boardData ) {
310+ throw new Error ( `Table with id ${ tableHash } not found` ) ;
311+ }
312+
313+ if ( ! boardData . value || ! boardData . value . latestState ) {
314+ throw new Error ( `No latest state found for table ${ tableHash } ` ) ;
315+ }
316+
317+ const values = Object . values ( boardData . value . latestState . rows ) . map ( row => {
318+ return Object . values ( row . cells ) . map ( cell => {
319+ if ( cell && cell . value ) {
320+ return cell . value ;
321+ }
322+ return "" ;
323+ } ) ;
324+ } ) ;
325+
326+ resolve ( values ) ;
327+ } , reject ) ;
328+ } ) ;
56329}
0 commit comments