Skip to content

Commit f8c3fb9

Browse files
authored
Merge pull request #708 from finos/hypergrid-edit
Editing for `@finos/perspective-viewer-hypergrid`
2 parents 2ea4753 + 3b3d5c7 commit f8c3fb9

File tree

16 files changed

+529
-134
lines changed

16 files changed

+529
-134
lines changed

cpp/perspective/src/cpp/emscripten.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,8 +1047,8 @@ namespace binding {
10471047
break;
10481048
}
10491049
case DTYPE_TIME: {
1050-
col->set_nth<std::int64_t>(
1051-
idx, static_cast<std::int64_t>(value.as<double>()), STATUS_VALID);
1050+
auto elem = static_cast<std::int64_t>(value.call<t_val>("getTime").as<double>()); // dcol[i].as<T>();
1051+
col->set_nth(idx, elem, STATUS_VALID);
10521052
break;
10531053
}
10541054
case DTYPE_UINT8:

packages/perspective-viewer-d3fc/src/js/charts/candlestick.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ candlestick.plugin = {
1919
type: "number",
2020
count: 4,
2121
names: ["Open", "Close", "High", "Low"]
22-
}
22+
},
23+
selectMode: "toggle"
2324
};
2425

2526
export default candlestick;

packages/perspective-viewer-d3fc/src/js/charts/ohlc.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ ohlc.plugin = {
1919
type: "number",
2020
count: 4,
2121
names: ["Open", "Close", "High", "Low"]
22-
}
22+
},
23+
selectMode: "toggle"
2324
};
2425

2526
export default ohlc;

packages/perspective-viewer-d3fc/src/js/charts/xy-scatter.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ xyScatter.plugin = {
101101
type: "number",
102102
count: 2,
103103
names: ["X Axis", "Y Axis", "Color", "Size"]
104-
}
104+
},
105+
selectMode: "toggle"
105106
};
106107

107108
export default xyScatter;

packages/perspective-viewer-hypergrid/src/js/PerspectiveDataModel.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,26 @@ module.exports = require("datasaur-local").extend("PerspectiveDataModel", {
134134
}
135135
},
136136

137+
getCellEditorAt: function(columnIndex, rowIndex, declaredEditorName, options) {
138+
if (!declaredEditorName) {
139+
return;
140+
}
141+
const offset = this.grid.renderer.dataWindow.top;
142+
const editor = this.grid.cellEditors.create(declaredEditorName, options);
143+
const args = {
144+
start_row: rowIndex + offset - 1,
145+
end_row: rowIndex + offset,
146+
start_col: columnIndex,
147+
end_col: columnIndex + 1,
148+
index: true
149+
};
150+
editor._row = this._view.to_json(args);
151+
editor.el.addEventListener("blur", () => setTimeout(() => editor.cancelEditing()));
152+
editor._table = this._table;
153+
editor._data = this.data;
154+
return editor;
155+
},
156+
137157
getCell: function(config, rendererName) {
138158
var nextRow, depthDelta;
139159
if (config.isUserDataArea) {
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/******************************************************************************
2+
*
3+
* Copyright (c) 2017, the Perspective Authors.
4+
*
5+
* This file is part of the Perspective library, distributed under the terms of
6+
* the Apache License 2.0. The full license can be found in the LICENSE file.
7+
*
8+
*/
9+
10+
const Textfield = require("fin-hypergrid/src/cellEditors/Textfield");
11+
12+
function px(n) {
13+
return n + "px";
14+
}
15+
16+
function validateEditorValueDate(x) {
17+
const d = new Date(x);
18+
return !(d instanceof Date && !isNaN(d));
19+
}
20+
21+
function setBoundsDate(cellBounds) {
22+
const style = this.el.style;
23+
style.left = px(cellBounds.x + 4);
24+
style.top = px(cellBounds.y - 3);
25+
style.width = px(cellBounds.width + 50);
26+
style.height = px(cellBounds.height);
27+
}
28+
29+
function setBoundsText(cellBounds) {
30+
const style = this.el.style;
31+
style.left = px(cellBounds.x + 4);
32+
style.top = px(cellBounds.y - 3);
33+
style.width = px(cellBounds.width - 10);
34+
style.height = px(cellBounds.height);
35+
}
36+
37+
function setEditorValueDate(x) {
38+
if (x === null) {
39+
return;
40+
}
41+
const now = +new Date(x);
42+
const day = ("0" + now.getDate()).slice(-2);
43+
const month = ("0" + (now.getMonth() + 1)).slice(-2);
44+
this.input.value = `${now.getFullYear()}-${month}-${day}`;
45+
}
46+
47+
function setEditorValueDatetime(x) {
48+
if (x === null) {
49+
return;
50+
}
51+
const now = new Date(x);
52+
const day = ("0" + now.getDate()).slice(-2);
53+
const month = ("0" + (now.getMonth() + 1)).slice(-2);
54+
const hour = ("0" + now.getHours()).slice(-2);
55+
const minute = ("0" + now.getMinutes()).slice(-2);
56+
const ss = ("0" + now.getSeconds()).slice(-2);
57+
this.input.value = `${now.getFullYear()}-${month}-${day}T${hour}:${minute}:${ss}`;
58+
}
59+
60+
function setEditorValueText(updated) {
61+
if (updated === null) {
62+
return "";
63+
} else {
64+
this.input.value = this.localizer.format(updated);
65+
return updated;
66+
}
67+
}
68+
69+
function getEditorValueText(updated) {
70+
this._row.then(([old]) => {
71+
const index = old.__INDEX__;
72+
delete old["__INDEX__"];
73+
const colname = Object.keys(old)[0];
74+
this._table.update([{__INDEX__: index, [colname]: updated}]);
75+
});
76+
return this.localizer.format(updated);
77+
}
78+
79+
function getEditorValueNumber(updated) {
80+
this._row.then(([old]) => {
81+
const index = old.__INDEX__;
82+
delete old["__INDEX__"];
83+
const colname = Object.keys(old)[0];
84+
this._table.update([{__INDEX__: index, [colname]: Number(updated.replace(/,/g, ""))}]);
85+
});
86+
return this.localizer.format(updated);
87+
}
88+
89+
function getEditorValueDate(updated) {
90+
updated = new Date(updated);
91+
this._row.then(([old]) => {
92+
const index = old.__INDEX__;
93+
delete old["__INDEX__"];
94+
const colname = Object.keys(old)[0];
95+
this._table.update([{__INDEX__: index, [colname]: updated}]);
96+
});
97+
return this.localizer.format(updated);
98+
}
99+
100+
function saveEditorValue(x) {
101+
var save = !(x && x === this.initialValue) && this.grid.fireBeforeCellEdit(this.event.gridCell, this.initialValue, x, this);
102+
if (save) {
103+
this._data[this.event.gridCell.y - 1][this.event.gridCell.x] = x;
104+
}
105+
}
106+
107+
export function set_editors(grid) {
108+
const date = Textfield.extend("perspective-date", {
109+
localizer: grid.localization.get("chromeDate"),
110+
template: "<input class='hypergrid-textfield' type='date'>",
111+
getEditorValue: getEditorValueDate,
112+
setEditorValue: setEditorValueDate,
113+
validateEditorValue: validateEditorValueDate,
114+
setBounds: setBoundsDate,
115+
selectAll: () => {},
116+
saveEditorValue
117+
});
118+
119+
const datetime = Textfield.extend("perspective-datetime", {
120+
localizer: grid.localization.get("chromeDate"),
121+
template: "<input class='hypergrid-textfield' type='datetime-local'>",
122+
getEditorValue: getEditorValueDate,
123+
setEditorValue: setEditorValueDatetime,
124+
validateEditorValue: validateEditorValueDate,
125+
setBounds: setBoundsDate,
126+
selectAll: () => {},
127+
saveEditorValue
128+
});
129+
130+
const text = Textfield.extend("perspective-text", {
131+
setBounds: setBoundsText,
132+
setEditorValue: setEditorValueText,
133+
getEditorValue: getEditorValueText,
134+
saveEditorValue
135+
});
136+
137+
const number = Textfield.extend("perspective-number", {
138+
setBounds: setBoundsText,
139+
setEditorValue: setEditorValueText,
140+
getEditorValue: getEditorValueNumber,
141+
validateEditorValue: x => isNaN(Number(x.replace(/,/g, ""))),
142+
saveEditorValue
143+
});
144+
145+
grid.cellEditors.add(number);
146+
grid.cellEditors.add(date);
147+
grid.cellEditors.add(datetime);
148+
grid.cellEditors.add(text);
149+
}

0 commit comments

Comments
 (0)