Skip to content

Commit 2a33fe6

Browse files
Merge pull request #291 from jupytercalpoly/dev
0.7.4
2 parents a984570 + e3db469 commit 2a33fe6

File tree

12 files changed

+1960
-2856
lines changed

12 files changed

+1960
-2856
lines changed

PROGRESS.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ An account of tasks and features that are completed or planned
1818
- [x] CSV launcher
1919
- [x] Multi row/column insert/remove
2020
- [x] Ghost row/column
21-
- [ ] Data type detection
21+
- [x] Data type detection (format data mode)
2222
---
2323
**Potential Future Features**
24+
- [ ] Fill handle
25+
- [ ] Freeze rows/columns
2426
- [ ] Moving cells
2527
- [ ] Multi row/column move
2628
- [ ] Filter
@@ -30,6 +32,16 @@ An account of tasks and features that are completed or planned
3032

3133
## Current Progress
3234

35+
### 08/24/20 - 08/28/20
36+
#### [Final Presentation](https://docs.google.com/presentation/d/12M3riXxlj1GouMA5mIt6B1QbdA7MSt_KNf8h545I2oI/edit?usp=sharing)
37+
- Bug fixes and cleanup - Kalen/Logan
38+
- Project Documentation - Ryan
39+
40+
### 08/17/20 - 08/21/20
41+
- Format data mode - Kalen
42+
- Data type icons - Logan
43+
- README updates - Ryan
44+
3345
### 08/10/20 - 08/14/20
3446
- CSV launcher - Kalen
3547
- Unsaved changes dialog - Kalen

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "jupyterlab-tabular-data-editor",
3-
"version": "0.7.3",
3+
"version": "0.7.4",
44
"description": "EXPERIMENTAL: JupyterLab Tabular Data Editor for CSV files",
55
"keywords": [
66
"jupyter",

src/drag.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,21 +80,25 @@ export class BoundedDrag extends Drag {
8080
return;
8181
}
8282
if (this._boundingRegion || this._initializing) {
83-
let sudoClientX = clientX - this._mouseOffsetX;
84-
let sudoClientY = clientY - this._mouseOffsetY;
85-
[sudoClientX, sudoClientY] = this.bound(sudoClientX, sudoClientY);
83+
const { left, top } = this.bound(clientX, clientY);
8684
const style = this.dragImage.style;
87-
style.top = `${sudoClientY}px`;
88-
style.left = `${sudoClientX}px`;
85+
style.top = `${left}px`;
86+
style.left = `${top}px`;
8987
this._initializing = false;
9088
}
9189
}
9290

93-
bound(x: number, y: number): Array<number> {
91+
bound(clientX: number, clientY: number): { left: number; top: number } {
92+
// Adjust the position of there are mouse offsets.
93+
let left = clientX - this._mouseOffsetX;
94+
let top = clientY - this._mouseOffsetY;
95+
96+
// Return early if we do not have a bounding region.
9497
if (!this._boundingRegion) {
95-
return [x, y];
98+
return { left, top };
9699
}
97-
// unpack the bounding region
100+
101+
// Unpack the bounding region.
98102
const {
99103
topBound,
100104
bottomBound,
@@ -109,10 +113,10 @@ export class BoundedDrag extends Drag {
109113
const width = parseFloat(style.width);
110114
const height = parseFloat(style.height);
111115

112-
// Bound
113-
x = Math.max(leftBound, Math.min(x, rightBound - width));
114-
y = Math.max(topBound, Math.min(y, bottomBound - height));
115-
return [x, y];
116+
// Bound.
117+
left = Math.max(leftBound, Math.min(left, rightBound - width));
118+
top = Math.max(topBound, Math.min(top, bottomBound - height));
119+
return { left, top };
116120
}
117121

118122
manualPositionUpdate(xLocation?: number, yLocation?: number): void {

src/grid.ts

Lines changed: 117 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { DataGrid } from 'tde-datagrid';
1+
import { DataGrid, SelectionModel } from 'tde-datagrid';
22
import { LabIcon, addIcon } from '@jupyterlab/ui-components';
3-
import { EditorModel } from './newmodel';
3+
import { EditorModel } from './model';
44

55
export class PaintedGrid extends DataGrid {
66
constructor(options: PaintedGrid.IOptions) {
@@ -45,6 +45,30 @@ export class PaintedGrid extends DataGrid {
4545
return this.defaultSizes.columnWidth;
4646
}
4747

48+
/**
49+
* Selects cells using the selection model
50+
* @param row The row being selected
51+
* @param column The column being selected
52+
*/
53+
selectCells(selection: SelectionModel.Selection): void {
54+
// Bail if no selection
55+
if (!selection) {
56+
return;
57+
}
58+
59+
const { r1, r2, c1, c2 } = selection;
60+
const select: SelectionModel.SelectArgs = {
61+
r1,
62+
r2,
63+
c1,
64+
c2,
65+
cursorRow: r1,
66+
cursorColumn: c1,
67+
clear: 'all'
68+
};
69+
this.selectionModel.select(select);
70+
}
71+
4872
/**
4973
* @override paints on the ghost row and column as well after painting the other regions.
5074
* Paint the grid content for the given dirty rect.
@@ -86,13 +110,17 @@ export class PaintedGrid extends DataGrid {
86110
// Draw the icons.
87111
const model = this.dataModel as EditorModel;
88112
if (model && model.isDataFormatted) {
89-
this._drawIcons(rx, ry, rw, rh);
113+
this._paintDatatypeIcons(rx, ry, rw, rh);
90114
this.drawCornerHeaderRegion(0, 0, this.headerWidth, this.headerHeight);
91115
}
92116
}
93117

94118
/**
95119
* Draw the ghost row.
120+
* @param rx
121+
* @param ry
122+
* @param rw
123+
* @param rh
96124
*/
97125
private _drawGhostRow(rx: number, ry: number, rw: number, rh: number): void {
98126
// Get the visible content dimensions.
@@ -136,6 +164,10 @@ export class PaintedGrid extends DataGrid {
136164

137165
/**
138166
* Draw the ghost column.
167+
* @param rx
168+
* @param ry
169+
* @param rw
170+
* @param rh
139171
*/
140172
private _drawGhostColumn(
141173
rx: number,
@@ -182,6 +214,13 @@ export class PaintedGrid extends DataGrid {
182214
this.canvasGC.fillRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
183215
}
184216

217+
/**
218+
* Draw the ghost row header
219+
* @param rx
220+
* @param ry
221+
* @param rw
222+
* @param rh
223+
*/
185224
private _drawGhostRowHeader(
186225
rx: number,
187226
ry: number,
@@ -226,9 +265,16 @@ export class PaintedGrid extends DataGrid {
226265
this.canvasGC.fillStyle = this._extraStyle.ghostRowColor;
227266
this.canvasGC.fillRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
228267

229-
this._drawGhostRowIcon();
268+
this._paintGhostRowIcon();
230269
}
231270

271+
/**
272+
* Draw the ghost column header
273+
* @param rx
274+
* @param ry
275+
* @param rw
276+
* @param rh
277+
*/
232278
private _drawGhostColumnHeader(
233279
rx: number,
234280
ry: number,
@@ -272,10 +318,13 @@ export class PaintedGrid extends DataGrid {
272318
// Fill the region with the specified color.
273319
this.canvasGC.fillStyle = this._extraStyle.ghostColumnColor;
274320
this.canvasGC.fillRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
275-
this._drawColumnIcon();
321+
this._paintGhostColumnIcon();
276322
}
277323

278-
private _drawGhostRowIcon(): void {
324+
/**
325+
* Paints the ghost row icon
326+
*/
327+
private _paintGhostRowIcon(): void {
279328
// Get the dimensions for the cell.
280329
const cellH = this.defaultSizes.rowHeight;
281330

@@ -286,41 +335,20 @@ export class PaintedGrid extends DataGrid {
286335
if (!iconArgs) {
287336
return;
288337
}
289-
// Get the current transform state.
290-
const transform = this.canvasGC.getTransform();
291338

292339
// Unpack the icon arguments.
293340
const { icon, color, size, top, left } = iconArgs;
294341

295-
// Parse the icon path from the icon string.
296-
const { defaultSize, path } = Private.parseSVG(icon.svgstr);
297-
298-
// Create a path 2d object from the path string.
299-
const canvasPath = new Path2D(path);
300-
301-
// Solve for the scaling factor using the provided width or the default.
302-
const scale = size / defaultSize;
303-
304-
// Orient the canvas to the desired origin for the icon.
305-
this.canvasGC.translate(
306-
left,
307-
this.headerHeight + this.bodyHeight - cellH + top - this.scrollY
308-
);
342+
// Calculate the y position for the icon
343+
const y = this.headerHeight + this.bodyHeight - cellH + top - this.scrollY;
309344

310-
// Scale the canvas.
311-
this.canvasGC.scale(scale, scale);
312-
313-
// Set the canvas fill style.
314-
this.canvasGC.fillStyle = color;
315-
316-
// Draw the icon.
317-
this.canvasGC.fill(canvasPath, 'nonzero');
318-
319-
// Reset the canvas to it's default position.
320-
this.canvasGC.setTransform(transform);
345+
this._drawIcon(left, y, size, color, icon.svgstr);
321346
}
322347

323-
private _drawColumnIcon(): void {
348+
/**
349+
* Paints the ghost column icon
350+
*/
351+
private _paintGhostColumnIcon(): void {
324352
// Get the dimensions for the cell.
325353
const cellW = this.defaultSizes.columnWidth;
326354

@@ -332,38 +360,13 @@ export class PaintedGrid extends DataGrid {
332360
return;
333361
}
334362

335-
// Get the current transform state.
336-
const transform = this.canvasGC.getTransform();
337-
338363
// Unpack the icon arguments.
339364
const { icon, color, size, left, top } = iconArgs;
340365

341-
// Parse the icon path from the icon string.
342-
const { defaultSize, path } = Private.parseSVG(icon.svgstr);
366+
// Calculate x position for the icon
367+
const x = this.headerWidth + this.bodyWidth - cellW + left - this.scrollX;
343368

344-
// Create a path 2d object from the path string.
345-
const canvasPath = new Path2D(path);
346-
347-
// Solve for the scaling factor using the provided width or the default.
348-
const scale = size / defaultSize;
349-
350-
// Orient to the desired origin for the icon.
351-
this.canvasGC.translate(
352-
this.headerWidth + this.bodyWidth - cellW + left - this.scrollX,
353-
top
354-
);
355-
356-
// Scale the canvas.
357-
this.canvasGC.scale(scale, scale);
358-
359-
// Set the canvas fill style.
360-
this.canvasGC.fillStyle = color;
361-
362-
// Draw the icon.
363-
this.canvasGC.fill(canvasPath, 'nonzero');
364-
365-
// Reset the transform to the initial state
366-
this.canvasGC.setTransform(transform);
369+
this._drawIcon(x, top, size, color, icon.svgstr);
367370
}
368371

369372
private _drawOverCorner(
@@ -412,7 +415,19 @@ export class PaintedGrid extends DataGrid {
412415
this.canvasGC.fillRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
413416
}
414417

415-
private _drawIcons(rx: number, ry: number, rw: number, rh: number): void {
418+
/**
419+
* Paints the datatype icons (string, number, boolean, date)
420+
* @param rx
421+
* @param ry
422+
* @param rw
423+
* @param rh
424+
*/
425+
private _paintDatatypeIcons(
426+
rx: number,
427+
ry: number,
428+
rw: number,
429+
rh: number
430+
): void {
416431
// Get the visible content dimensions.
417432
const contentW = this.bodyWidth - this.scrollX;
418433
const contentH = this.headerHeight;
@@ -548,36 +563,54 @@ export class PaintedGrid extends DataGrid {
548563
// Unpack the icon arguments.
549564
const { icon, color, size, left, top } = iconArgs;
550565

551-
// Parse the icon path from the icon string.
552-
const { defaultSize, path } = Private.parseSVG(icon.svgstr);
566+
this._drawIcon(x + left, y + top, size, color, icon.svgstr);
567+
568+
// Increment the running X coordinate.
569+
x += columnSize;
570+
}
571+
}
553572

554-
// Create a path 2d object from the path string.
555-
const canvasPath = new Path2D(path);
573+
/**
574+
* Utilizes the canvas GC to draw the icon in the correct position with the correct styles
575+
* @param x The horizontal position of the icon
576+
* @param y The vertical position of the icon
577+
* @param size The original size of the icon
578+
* @param color The fill color for the icon
579+
* @param svgstr A string containing the raw contents of the svg file
580+
*/
581+
private _drawIcon(
582+
x: number,
583+
y: number,
584+
size: number,
585+
color: string,
586+
svgstr: string
587+
): void {
588+
// Parse the icon path from the icon string.
589+
const { defaultSize, path } = Private.parseSVG(svgstr);
556590

557-
// Get the default position of the canvas drawer.
558-
const transform = this.canvasGC.getTransform();
591+
// Solve for the scaling factor using the provided width or the default.
592+
const scale = size / defaultSize;
559593

560-
// Orient to the desired origin for the icon.
561-
this.canvasGC.translate(x + left, y + top);
594+
// Create a path 2d object from the path string.
595+
const canvasPath = new Path2D(path);
562596

563-
// Solve for the scaling factor using the provided width or the default.
564-
const scale = size / defaultSize;
597+
// Get the current transform state.
598+
const transform = this.canvasGC.getTransform();
565599

566-
// Scale the canvas.
567-
this.canvasGC.scale(scale, scale);
600+
// Orient to the desired origin for the icon.
601+
this.canvasGC.translate(x, y);
568602

569-
// Set the canvas fill style.
570-
this.canvasGC.fillStyle = color;
603+
// Scale the canvas.
604+
this.canvasGC.scale(scale, scale);
571605

572-
// Draw the icon.
573-
this.canvasGC.fill(canvasPath, 'nonzero');
606+
// Set the canvas fill style.
607+
this.canvasGC.fillStyle = color;
574608

575-
// Reset the transform to the initial state
576-
this.canvasGC.setTransform(transform);
609+
// Draw the icon.
610+
this.canvasGC.fill(canvasPath, 'nonzero');
577611

578-
// Increment the running X coordinate.
579-
x += columnSize;
580-
}
612+
// Reset the transform to the initial state
613+
this.canvasGC.setTransform(transform);
581614
}
582615

583616
private _extraStyle: PaintedGrid.ExtraStyle;

0 commit comments

Comments
 (0)