GithubHelp home page GithubHelp logo

tonygermaneri / canvas-datagrid Goto Github PK

View Code? Open in Web Editor NEW
1.4K 40.0 182.0 51.65 MB

Canvas based data grid web component. Capable of displaying millions of contiguous hierarchical rows and columns without paging or loading, on a single canvas element.

License: BSD 3-Clause "New" or "Revised" License

JavaScript 97.50% HTML 1.60% CSS 0.89%
datagrid datatable component web-component

canvas-datagrid's Introduction

canvas-datagrid

Demo

canvas-datagrid

NPM License Published on webcomponents.org

  • Works with Firefox, Edge, Safari and Chrome.
  • Native support for touch devices (phones and tablets).
  • Rich documentation, tutorials, and slack support.
  • Single canvas element, drawn in immediate mode, data size does not impact performance.
  • Support for unlimited rows and columns without paging or loading.
  • Rich API of events, methods and properties using the familiar W3C DOM interface.
  • Extensible styling, filtering, formatting, resizing, selecting, and ordering.
  • Support for hierarchal drill in style row level inner grids as well grids in cells.
  • Customizable hierarchal context menu.
  • Built in and custom styles.
  • W3C Web Component. Works in all frameworks.
  • Per-user styles, column sizes, row sizes, view preferences and settings using localStorage.
  • Small file size

Documentation

Tutorials

Slack Support (message author for invite)

Style Builder

Download latest version (minified)

Tests

Source Code

Latest Test Coverage

Installation

With npm

npm install canvas-datagrid

Place the single source file ./dist/canvas-datagrid.js in your web page using a script tag that points to the source or use webpack.

<script src="dist/canvas-datagrid.js"></script>

Alternatively, instead of downloading and installing, you can link directly to an NPM CDN like unpkg.com.

<script src="https://unpkg.com/canvas-datagrid"></script>

A function will be added to the global scope of the web page called canvasDatagrid as well as module loader definitions.

Getting started

Works with webpack, without webpack or as a web component. No matter how you load it, canvasDatagrid is declared in the global scope.

Canvas-datagrid is a Web Component when in a compatible browser, otherwise it is a <canvas> tag.

Using pure JavaScript

var grid = canvasDatagrid();
document.body.appendChild(grid);
grid.data = [
  { col1: 'row 1 column 1', col2: 'row 1 column 2', col3: 'row 1 column 3' },
  { col1: 'row 2 column 1', col2: 'row 2 column 2', col3: 'row 2 column 3' },
];

Using Web Component

<canvas-datagrid class="myGridStyle" data="data can go here too"
  >[ {"col1": "row 1 column 1", "col2": "row 1 column 2", "col3": "row 1 column
  3"}, {"col1": "row 2 column 1", "col2": "row 2 column 2", "col3": "row 2
  column 3"} ]</canvas-datagrid
>

or

var grid = document.createElement('canvas-datagrid');
grid.data = [
  { col1: 'row 1 column 1', col2: 'row 1 column 2', col3: 'row 1 column 3' },
  { col1: 'row 2 column 1', col2: 'row 2 column 2', col3: 'row 2 column 3' },
];

Using Vue

<canvas-datagrid :data.prop="[{"col1": "row 1 column 1"}]"></canvas-datagrid>

More Demos

Note about XHR paging demo: Thanks to jservice for the use of the free paging API. You must "load unsafe scripts" or relevant command to allow HTTPS (github) to make XHR requests to HTTP (Jeopardy Questions API). There is nothing unsafe about this.

Building & Testing

To install development dependencies. Required to build or test.

npm install

To build production and debug versions:

npm run build

To build documentation:

npm run build:docs

To build types:

npm run build:types

To run tests. Note: Headless tests will mostly fail due to lack of headless canvas pixel detection support. Use VM testing or your browser.

npm test

Windows 10 WSL Testing

This is info for wsl version 1. v2 seems to be different.

  • CHROME_BIN needs to be set to the location of your Google Chrome exe in Windows. (e.g. /mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe) in WSL, export CHROME_BIN='path/to/chrome'
  • Chrome needs access to karma's temp folder.
    • Create a tmp folder on the same Windows drive as your repo.
    • set TEMP to a folder that exists on the same Windows drive as your repo. (matching capitalization probably matters) in WSL, export TEMP='/Temp/karma', if your repo is on drive C, then create folder C:\Temp\karma
  • karma.conf.js needs to be edited
    • Change the browser from ChromeHeadless to Chrome
    • Modify to run ChromeHeadless without sandboxing. This is not ideal, but it seems to be necessary in WSL and Linux containers (see also)
      • Add a custom launcher
        customLaunchers: {
          ChromeHeadlessNoSandbox: {
              base: 'ChromeHeadless',
              flags: ['--no-sandbox']
          }
        }
        
      • Change the browser from ChromeHeadless to ChromeHeadlessNoSandbox

canvas-datagrid's People

Contributors

betososa avatar blacktea1105 avatar boukeversteegh avatar cthurston avatar dependabot[bot] avatar dflock avatar dijonkitchen avatar gjchentw avatar hackwaly avatar hangxingliu avatar hitomitenshi avatar iamwill avatar ilyaem avatar johanrd avatar josh-hemphill avatar jswolf19 avatar jtsymon avatar mdebrauw avatar ndrsn avatar romanstetsyk avatar slominskir avatar stevewillard avatar tim-vandecasteele avatar tmaroschik avatar tonygermaneri avatar twojtylak avatar velitasali avatar xianzhi3 avatar yaojiu19 avatar yuanliwei avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

canvas-datagrid's Issues

Strange cell grid row height auto assignment when combined with trees on very complex objects

It's just crazy.

var grid = canvasDatagrid({
    parentNode: document.body,
    tree: true
});
grid.data = [
    {'a': 0, 'b': 1, 'c': 2},
    {'a': 4, 'b': {'a': 0, 'b': 1, 'c': 2}, 'c': 6},
    {'a': 7, 'b': 8, 'c': 9}
];
grid.addEventListener('expandtree', function (e) {
    e.treeGrid.data = [
        {'a': 0, 'b': 1, 'c': 2},
        {'a': 4, 'b': {'a': 0, 'b': 1, 'c': 2}, 'c': 6},
        {'a': 7, 'b': 8, 'c': 9}
    ];
});

The defect is that somehow the auto assignment for either tree or cell is applied the the header row of a nested tree or grid cell, can't tell which at that point.

Fixing this specific use case is super low priority because it seems incredible that anyone would do such a thing. If someone actually complains about this, I will fix it. At a later date I'll check if it doesn't get fixed while resolving a more sane bug.

Add cut

So close.

lib/events.js line 883

    self.cut = function (e) {
        self.copy(e);
        //TODO remove selected data
    };

Mouse position failure after 3rd hierarchy

Because I suck at math, I can't figure out how to properly detect the position of the mouse when it enters the 3rd hierarchy child grid.

If anyone is interested in fixing this very difficult bug, please contact me for more info.

Drag selection bug

When a drag selection is initiated on a cell that is already selected, the cell under the mouse cursor becomes de-selected improperly.

Better support for data in web component

Right now, JSON must be passed to the data. It would be cool if you could pass a url, csv, or whatever to the data attribute and have it interpret the data correctly. Url seems like the best.

dragging columns into gutter causes issues with horizontal scroll

You can get stuck when scrolling to the right to columns off the screen.

When dragging a column,
1- drop said column into the column for row numbers (accidentally I guess, one too far to the left),
2- scroll all the way to the right
3- attempt to scroll back to the left will fail with the error below.

Uncaught TypeError: Cannot read property 'title' of undefined
    at drawHeaderRow (canvas-datagrid.js:1602)
    at draw (canvas-datagrid.js:1882)
    at scroll (canvas-datagrid.js:2145)
    at Object.set (canvas-datagrid.js:3771)
    at HTMLCanvasElement.scrollWheel (canvas-datagrid.js:3530)

discovered with Chrome 58.0.3029.110 (64-bit)

Row ordering

Ability to click and drag rows to reorder them, row order should be stored a new orders array and saved to local store on change so it can be recalled on page refresh. Reordering only effects the appearance of the grid, the interface will be left unchanged besides an order index number in the data[].row items.

Tree grid arrow click detection sucks

It really does, not sure why. You need to be way to the left of the arrow to activate it sometimes, so this is most likely related to general mouse detection bugs.

Edit: appears to be related to DOM offsets.

Samples

Currently there is only a single sample page with a not-very-helpful grid demo. This should be exploded into a sample site broken into categories. The sample site should exist in this repo (probably under samples?) and should be published via gh-pages and linkable from the docs.

It would be cool to have a "live" sample site like jsfiddle. It's all client side so it shouldn't be to hard.

Samples should cover at the very least the topics in the readme and can probably just be copied and pasted in there.

Touch editing should be more mobile friendly

Rather than inline edit, a dedicated edit row should appear below the grid with the ability to confirm or exit your edit. Additional event handlers for adding buttons like the confirm and exit buttons should be added as well.

Strange scroll bar "skipping/snapping" when using scrollPointerLock

In some cases the scroll bar is skipping or snapping around. You can see this behavior in the test called "Scroll horizontally left via margin click" where the scroll bar is set via grid.scrollLeft = grid.scrollWidth; then the test clicks the margin of the horizontal scroll bar on the left to scroll. You'll see it jump to what appears to be an impossible position then scroll normally after 10ms.

I assume this is a miscalculation on the part of the scroll bars scrollWidth getter. And maybe another additional bug in the stop/start when using scrollPointerLock (default behavior).

This can occur when the scroll bar has been set programmatically, then interacted with, or when scrollPointerLock true and some regions are grabbed to start with.

Style argument/property does not property replace values

Currently the style argument and property can only be used to effect one key or to effect the whole object. Style argument should properly override provided values without killing the base object. Style property should be a setter that does the same as the argument.

Support jagged data sets

Currently, data setter will create a temp schema based on the first row. Instead, data setter should scan the rows to find the max columns and create a temp schema from that row instead.

Scroll bar improvement?

because the scroll bar isn't a "real" scroll bar, leaving the document will cause mouse move events to stop firing. One solution is to capture the mouse and read deltas, but its unnerving because it causes your cursor to disappear. Maybe a "fake" cursor can be drawn while captured scrolling occurs? This may not work out and it may be the current scrolling system is the best we can do without dom.

Not able to scroll in IE11

Grid renders nicely, but nothing happens on scrolling.

Get error: SCRIPT5022: ScrollTop value must be a number
intf.js (895,1)

Tests

Not even sure how to do this atm. Canvas pixel checks I assume. :(

Multi filter

Allow for one filter per column to be applied and driven from the context menu.

Copy/Paste functionalities

First of all, I really appreciate the great job you're doing with this fast and nice grid.
Do you plan to add a copy/paste functionality on the grid (I've seen that "copy" works fine, but "paste" don't) ? Do you think it will be possible to have on the bottom-right corner of the cell(s) an icon to drag the current content on multiple cells (horizontally or vertically) ? I've looked for these features on your documentation but I've not found it, maybe I missed it ?

Web component should use css classes

Even though it doesn't implement css, I can still read css values from css classes and have class names applied to an attribute called class/className.

Autocomplete filter not working in IE11

SCRIPT445: Object doesn't support this action contextMenu.js (281,1). The only "unusual" thing around there is an event dispatcher. I'm guessing IE11 does not support HTMLElement.dispatchEvent(new Event('keyup')); It can be raised in another way that should work with new and older browsers.

Column reordering

Ability to click and drag columns to reorder them, column order should be stored a new orders array and saved to local store on change so it can be recalled on page refresh. Reordering only effects the appearance of the grid, the interface will be left unchanged besides an order index number in the schema[].header items.

Child grid bad scroll behaviors.

After opening several child row/tree grids the scroll bar of the parent nodes appears to get confused and stop working. Not sure the cause.

Mobile UX is junk

Trying to use the mobile is not a good experience. This needs to be nice and buttery before V1. Specifically easing animations are very poorly executed, lots of jittery behavior due to poor point per second calculations and/or touch end animations. This should probably be completely refactored.

Nested grid scroll dom miscalculation.

When in a nested element with a scroll bar, the DOM elements related to the grid are not properly calculated. This used to work.

To reproduce, put a div in a div. Add the grid to the innermost div. Set overflow: auto; height: 200px;padding-top:200px; on the outer div. Now scroll down to the grid and try and use the context menu or edit input. Offsets are incorrect. These elements use the getPosition or some such function to figure out where they go, a dom walking function that collects scroll offsets already exists and just needs to be applied to the resize method of these elements.

More themes

Themes are complete instances of the canvasDatagrid.style class. They should be stored in a ./themes folder as JSON files.

Support more complex searches in filter by default

Currently, it is not clear the filter is a regexp interface. This means laymen cannot search for strings that contain reserved characters (such as parentheses). Instead of just straight regexp interface, we should use a string pattern to switch regex on and off. /<pat>/<flags> is the standard pattern. So any string matching this pattern will be considered regexp and parsed accordingly. Further, on error of regexp self.invalidFilterRegEx = e; should be set to the regexp error. If not using regex (pattern does not match /<pat>/<flags>) then self.invalidFilterRegEx = false; should be set to boolean false. When using regex and no error has been detected self.invalidFilterRegEx = true; should be set to boolean true to give a visual cue to the user that they are using regex and not just string matching.

Reorder column dragging draws incorrectly

On the second reorder, the marker bar is not drawn in the correct location. This is probably related to looking at the wrong column index to calculate when to appear. There is the "real" index and the "view" index (what the user has reordered to), it needs to use the later.

Row header resize inconsistency

On instantiation, row header autosize differs from using autosize column function (double click on row header resize border). They should be identical.

Break code file apart

Break code file apart and rebuild with browserify producing two artifacts that should be put in /redist directory. At least I think it's redist. Anyhow the common nomenclature should be researched and used.

Logical points to break code file apart at:

name description example
top doc section just about every line above 500
draw any function related to drawing drawScrollBars, drawSelectionBorders, drawCell, drawRow, drawRowHeader, drawOrderByArrow, radiusRect
scroll bar interface code that handles the scroll bar, but not drawing the scroll bar initScrollBox
context menu code related to the context menu
cell edit code related to editing cells
key handlers (related closely to cell edit, might be better kept together) code related to handling keystrokes
public interface and getter setters public interface intf binding and intf getter setters.
initialization, dom related anything touching dom elements not covered by another function attachCss, appendTo, clipElement
primary events events that interact with dom event handlers mouse move, click, mouse up, mouse down
secondary events events dreamed up by the grid authors dragResizeColumn, scrollGrid, resize
non-altering methods methods that don't "change" anything on the grid getCellAt, getClippingRect, getHeaderByName
altering methods methods that alter the behavior or appearance of the grid expandTree, selectRow, fitColumnToValues

Documentation

I've forked the https://github.com/TonyGermaneri/docstrap project. Live docs will be added there giving live tutorials instead of the static tutorials.

Docs must be committed in the gh-pages branch, not the master branch. Keep docs out of the master branch.

To build docs, run npm install to get jsdoc and docstrap. Then run

jsdoc -u ./tutorials -d ./docs -c ./jsdoc.json -t ./node_modules/ink-docstrap/template -R README.md -r ./lib

When a child grid is closed, its mouse events still fire in the parent grid.

When a child grid (cell or row) is closed/removed its mouse events still fire in the same position as if it was open. Ideally the child grid module would unsubscribe from the events until it is open again. Less ideal would be for it to notice that it is closed and abort at the top of event listeners.

This is pretty annoying because it makes the parent grid nearly useless after closing the child.

Zoom in mobile

Mobile/touch should be able to zoom in/out via touch.

Event refactoring

Event signatures presently look like this:

(e, arg1, arg2, arg3)

and should look like

(e)

and e should contain e.arg1, e.arg2, e.arg3

This is a major breaking change.

Scrolling event on 3rd level hierarchy fails to move input box

When you open the 3rd level of a tree (or cell with tree), the scroll event that is supposed call resizeEditInput fails to do so at the correct time resulting in the input not moving to the correct position. It always appears in the previous scroll position, leading me to believe its a race condition on calling resizeEditInput.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.