aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/DataVizBox/components/TableBox.tsx
blob: 64c6dc940b2564b19eb3163d70b2823f460fb41c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
import { action, computed, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc } from '../../../../../fields/Doc';
import { Id } from '../../../../../fields/FieldSymbols';
import { List } from '../../../../../fields/List';
import { emptyFunction, returnFalse, setupMoveUpEvents, Utils } from '../../../../../Utils';
import { DragManager } from '../../../../util/DragManager';
import { DocumentView } from '../../DocumentView';
import { DataVizView } from '../DataVizBox';
import { LinkManager } from '../../../../util/LinkManager';
import { Cast, DocCast } from '../../../../../fields/Types';
import { EditableText, Size, Type } from 'browndash-components';
import './Chart.scss';
import { listSpec } from '../../../../../fields/Schema';

interface TableBoxProps {
    rootDoc: Doc;
    pairs: { [key: string]: any }[];
    selectAxes: (axes: string[]) => void;
    axes: string[];
    width: number;
    height: number;
    margin: {
        top: number;
        right: number;
        bottom: number;
        left: number;
    };
    docView?: () => DocumentView | undefined;
}

@observer
export class TableBox extends React.Component<TableBoxProps> {
    @observable editableHeaders = this.columns;
    @observable editableCells = this._tableData;

    @computed get _tableData() {
        if (this.incomingLinks.length! <= 0) return this.props.pairs;
        /// StrListCast(this.incomingLinks[0].anchor_1.selected) ==> list of guids that the parent has selected
        return this.props.pairs?.filter(pair => (Array.from(Object.keys(pair)).some(key => pair[key] && key.startsWith('select'))))
    }

    @computed get incomingLinks() {
        return LinkManager.Instance.getAllRelatedLinks(this.props.rootDoc) // out of all links
            .filter(link => {
                return link.link_anchor_1 == this.props.rootDoc.draggedFrom}) // get links where this chart doc is the target of the link
            .map(link => DocCast(link.link_anchor_1)); // then return the source of the link
    }

    @computed get columns() {
        // return this.props.pairs.length ? Array.from(Object.keys(this.props.pairs[0])) : [];
        return this._tableData.length ? Array.from(Object.keys(this._tableData[0])) : [];
    }

    // render() {
    //     return (
    //         <div className="table-container" style={{height: this.props.height+this.props.margin.top+this.props.margin.bottom}}>
    //             <table className="table">
    //                 <thead>
    //                     <tr className="table-row">
    //                         {this.editableHeaders
    //                             .filter(col => !col.startsWith('select'))
    //                             .map(col => {
    //                                 const header = React.createRef<HTMLElement>();
    //                                 const displayColName = col;
    //                                 return (
    //                                     <th
    //                                         key={this.editableHeaders.indexOf(col)}
    //                                         ref={header as any}
    //                                         style={{
    //                                             color: this.props.axes.slice().reverse().lastElement() === col ? 'green' : this.props.axes.lastElement() === col ? 'red' : undefined,
    //                                             fontWeight: this.props.axes.includes(col) ? 'bolder' : 'normal',
    //                                         }}
    //                                         onPointerDown={e => {
    //                                             const downX = e.clientX;
    //                                             const downY = e.clientY;
    //                                             setupMoveUpEvents(
    //                                                 {},
    //                                                 e,
    //                                                 e => {
    //                                                     const sourceAnchorCreator = () => this.props.docView?.()!.rootDoc!;
    //                                                     const targetCreator = (annotationOn: Doc | undefined) => {
    //                                                         const embedding = Doc.MakeEmbedding(this.props.docView?.()!.rootDoc!);
    //                                                         embedding._dataVizView = DataVizView.LINECHART;
    //                                                         embedding._data_vizAxes = new List<string>([col, col]);
    //                                                         embedding._draggedFrom = this.props.docView?.()!.rootDoc!;
    //                                                         embedding.annotationOn = annotationOn; //this.props.docView?.()!.rootDoc!;
    //                                                         return embedding;
    //                                                     };
    //                                                     if (this.props.docView?.() && !Utils.isClick(e.clientX, e.clientY, downX, downY, Date.now())) {
    //                                                         DragManager.StartAnchorAnnoDrag([header.current!], new DragManager.AnchorAnnoDragData(this.props.docView()!, sourceAnchorCreator, targetCreator), downX, downY, {
    //                                                             dragComplete: e => {
    //                                                                 if (!e.aborted && e.annoDragData && e.annoDragData.linkSourceDoc && e.annoDragData.dropDocument && e.linkDocument) {
    //                                                                     e.linkDocument.link_displayLine = true;
    //                                                                     e.linkDocument.link_matchEmbeddings = true;
    //                                                                     // e.annoDragData.linkSourceDoc.followLinkToggle = e.annoDragData.dropDocument.annotationOn === this.props.rootDoc;
    //                                                                     // e.annoDragData.linkSourceDoc.followLinkZoom = false;
    //                                                                 }
    //                                                             },
    //                                                         });
    //                                                         return true;
    //                                                     }
    //                                                     return false;
    //                                                 },
    //                                                 emptyFunction,
    //                                                 action(e => {
    //                                                     const newAxes = this.props.axes;
    //                                                     if (newAxes.includes(col)) {
    //                                                         newAxes.splice(newAxes.indexOf(col), 1);
    //                                                     } else if (newAxes.length >= 1) {
    //                                                         newAxes[1] = col;
    //                                                     } else {
    //                                                         newAxes[0] = col;
    //                                                     }
    //                                                     this.props.selectAxes(newAxes);
    //                                                 })
    //                                             );
    //                                         }}>
    //                                         <EditableText
    //                                             val={displayColName}
    //                                             setVal={action(val => {
    //                                                 this.editableHeaders[this.editableHeaders.indexOf(col)] = val as string
    //                                                 this.props.pairs.map(pair => {
    //                                                     pair[val as string] = pair[col];
    //                                                     delete pair[col]
    //                                                 })
    //                                             })}
    //                                             color={"black"}
    //                                             size={Size.LARGE}
    //                                         />
    //                                     </th>
    //                                 );
    //                             })}
    //                     </tr>
    //                 </thead>
    //                 <tbody>
    //                     {this._tableData?.map((p, i) => {
    //                         return (
    //                             <tr key={i} className="table-row" onClick={action(e => (p['select' + this.props.docView?.()?.rootDoc![Id]] = !p['select' + this.props.docView?.()?.rootDoc![Id]]))}>
    //                                 {this.editableHeaders.map(col => (
    //                                     <td key={this.editableHeaders.indexOf(col)} style={{ fontWeight: p['select' + this.props.docView?.()?.rootDoc![Id]] ? 'bold' : '' }}>
    //                                         {p[col]}
    //                                     </td>
    //                                 ))}
    //                             </tr>
    //                         );
    //                     })}
    //                 </tbody>
    //             </table>
    //         </div>
    //     );
    // }


    render() {
        return (
            <div className="table-container" style={{height: this.props.height+this.props.margin.top+this.props.margin.bottom}}>
                <table className="table">
                    <thead>
                        <tr className="table-row">
                            {this.columns
                                .filter(col => !col.startsWith('select'))
                                .map(col => {
                                    const header = React.createRef<HTMLElement>();
                                    return (
                                        <th
                                            key={this.columns.indexOf(col)}
                                            ref={header as any}
                                            style={{
                                                color: this.props.axes.slice().reverse().lastElement() === col ? 'green' : this.props.axes.lastElement() === col ? 'red' : undefined,
                                                fontWeight: this.props.axes.includes(col) ? 'bolder' : 'normal',
                                            }}
                                            onPointerDown={e => {
                                                const downX = e.clientX;
                                                const downY = e.clientY;
                                                setupMoveUpEvents(
                                                    {},
                                                    e,
                                                    e => {
                                                        const sourceAnchorCreator = () => this.props.docView?.()!.rootDoc!;
                                                        const targetCreator = (annotationOn: Doc | undefined) => {
                                                            const embedding = Doc.MakeEmbedding(this.props.docView?.()!.rootDoc!);
                                                            embedding._dataVizView = DataVizView.LINECHART;
                                                            embedding._data_vizAxes = new List<string>([col, col]);
                                                            embedding._draggedFrom = this.props.docView?.()!.rootDoc!;
                                                            embedding.annotationOn = annotationOn; //this.props.docView?.()!.rootDoc!;
                                                            return embedding;
                                                        };
                                                        if (this.props.docView?.() && !Utils.isClick(e.clientX, e.clientY, downX, downY, Date.now())) {
                                                            DragManager.StartAnchorAnnoDrag([header.current!], new DragManager.AnchorAnnoDragData(this.props.docView()!, sourceAnchorCreator, targetCreator), downX, downY, {
                                                                dragComplete: e => {
                                                                    if (!e.aborted && e.annoDragData && e.annoDragData.linkSourceDoc && e.annoDragData.dropDocument && e.linkDocument) {
                                                                        e.linkDocument.link_displayLine = true;
                                                                        e.linkDocument.link_matchEmbeddings = true;
                                                                        // e.annoDragData.linkSourceDoc.followLinkToggle = e.annoDragData.dropDocument.annotationOn === this.props.rootDoc;
                                                                        // e.annoDragData.linkSourceDoc.followLinkZoom = false;
                                                                    }
                                                                },
                                                            });
                                                            return true;
                                                        }
                                                        return false;
                                                    },
                                                    emptyFunction,
                                                    action(e => {
                                                        const newAxes = this.props.axes;
                                                        if (newAxes.includes(col)) {
                                                            newAxes.splice(newAxes.indexOf(col), 1);
                                                        } else if (newAxes.length >= 1) {
                                                            newAxes[1] = col;
                                                        } else {
                                                            newAxes[0] = col;
                                                        }
                                                        this.props.selectAxes(newAxes);
                                                    })
                                                );
                                            }}>
                                            {col}
                                        </th>
                                    );
                                })}
                        </tr>
                    </thead>
                    <tbody>
                        {this._tableData?.map((p, i) => {
                            return (
                                <tr key={i} className="table-row" onClick={action(e => {
                                        // if (!this.props.docView?.()!.layoutDoc.selected) 
                                        //     this.props.docView!.()!.layoutDoc.selected = new List<string>();
                                        // const selected = Cast(this.props.docView?.()!.layoutDoc.selected, listSpec("string"), null);
                                        //                    // StrListCast(this.props.docView?.()!.layoutDoc.selected)
                                        // selected.push(p.guid);
                                        (p['select' + this.props.docView?.()?.rootDoc![Id]] = !p['select' + this.props.docView?.()?.rootDoc![Id]])
                                    })}>
                                    {this.columns.map(col => (
                                        <td key={this.columns.indexOf(col)} style={{ fontWeight: p['select' + this.props.docView?.()?.rootDoc![Id]] ? 'bold' : '' }}>
                                            {p[col]}
                                        </td>
                                    ))}
                                </tr>
                            );
                        })}
                    </tbody>
                </table>
            </div>
        );
    }



}