UNPKG

canvas-datagrid

Version:

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.

863 lines (862 loc) 110 kB
/*jslint browser: true*/ /*globals canvasDatagrid: false */ window.tutorials = {}; window.tutorials['Create a new grid|A grid is created and data is set in one command. Data can be an array of objects, an array of arrays or a mixed array of objects, arrays and primitives.'] = function (parentNode) { // create a new grid var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); }; window.tutorials['Set data after instantiation|A grid is created, then data is set afterwards. You can set data using <i>grid.data = &lt;data&gt;;</i> at anytime. Data can be an array of objects, an array of arrays or a mixed array of objects, arrays and primitives.'] = function (parentNode) { // create a new grid var grid = canvasDatagrid({ parentNode: parentNode }); grid.data = [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ]; }; window.tutorials['Format data|Data is formatted using the data type setting in the schema. The data type is mapped to the `grid.formatters` object. In the following example col2 is data type `date` which will format data using the `grid.formatters.date` function. By default the string formatter is used to format all data. This method of formatting is faster than using the <i>rendertext</i> event.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 1501744914661, col3: 'a'}, {col1: 'bar', col2: 1301744914661, col3: 'b'}, {col1: 'baz', col2: 1401744914661, col3: 'c'} ], schema: [ { name: 'col1' }, { name: 'col2', type: 'date' }, { name: 'col3' }, ] }); grid.formatters.date = function (e) { return new Date(e.cell.value).toISOString(); }; }; window.tutorials['Format data using rendertext event|Attach to the <i>rendertext</i> event.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 1501744914661, col3: 'a'}, {col1: 'bar', col2: 1301744914661, col3: 'b'}, {col1: 'baz', col2: 1401744914661, col3: 'c'} ], schema: [ { name: 'col1' }, { name: 'col2', type: 'date' }, { name: 'col3' }, ] }); grid.addEventListener('rendertext', function (e) { if (e.cell.rowIndex > -1) { if (e.cell.header.name === 'col2') { e.cell.formattedValue = new Date(e.cell.value).toISOString(); } } }); }; window.tutorials['Use a textarea to edit cells instead of an input.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, multiLine: true, data: [ {col1: 'foo\nbar', col2: 0, col3: 'a'}, {col1: 'bar\nfoo\nbar', col2: 1, col3: 'b'}, {col1: 'baz\nfoo\nbar', col2: 2, col3: 'c'} ] }); grid.style.cellHeight = 80; }; window.tutorials['Use select instead of input for edits|When a column in the schema includes an <i>enum</i> property, a drop down menu will appear instead of the normal input or textarea.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, schema: [ { name: 'col1', enum: [ ['foo', 'Foo'], ['bar', 'Bar'], ['baz', 'Baz'] ] }, { name: 'col2' }, { name: 'col3' }, ], data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); }; window.tutorials['Detect clicks|Detect which cell was clicked using the <i>click</i> event.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.addEventListener('click', function (e) { if (!e.cell) { return; } grid.data[0][grid.schema[0].name] = 'Clicked on ' + e.cell.value; }); }; window.tutorials['Detect cell over/out|Detect when a cell has been entered using <i>cellmouseover</i> and <i>cellmouseout</i> events.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.addEventListener('cellmouseover', function (e) { if (!e.cell) { return; } grid.data[0][grid.schema[0].name] = 'Just arrived at ' + e.cell.columnIndex + ', ' + e.cell.rowIndex; }); grid.addEventListener('cellmouseout', function (e) { if (!e.cell) { return; } grid.data[1][grid.schema[0].name] = 'Just came from ' + e.cell.columnIndex + ', ' + e.cell.rowIndex; }); }; window.tutorials['Get data via XHR function.|Fetch data from data.gov and parse the JSON.'] = function (parentNode) { var xhr = new XMLHttpRequest(), grid = canvasDatagrid({ parentNode: parentNode }); function parseOpenData(openData) { var data, schema = openData.meta.view.columns; data = openData.data.map(function (row) { var r = {}; schema.forEach(function (column, index) { r[column.name] = row[index]; }); return r; }); return { data: data, schema: schema }; } xhr.addEventListener('progress', function (e) { grid.data = [{ status: 'Loading data: ' + e.loaded + ' of ' + (e.total || 'unknown') + ' bytes...'}]; }); xhr.addEventListener('load', function (e) { grid.data = [{ status: 'Loading data ' + e.loaded + '...'}]; var openData = parseOpenData(JSON.parse(this.responseText)); grid.schema = openData.schema; grid.data = openData.data; }); xhr.open('GET', 'https://data.cityofchicago.org/api/views/xzkq-xp2w/rows.json?accessType=DOWNLOAD'); xhr.send(); }; window.tutorials['Set filter function|By default, the filter is a RegExp string, you can alter this per data type by adding a function to the object <i>grid.filters.&lt;type&gt;</i>.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.schema = [{name: 'id', type: 'number'}, {name: 'offendit', type: 'string'}]; grid.data = [ {id: 0, offendit: 'foo'}, {id: 1, offendit: 'bar'}, {id: 2, offendit: 'baz'}, ]; grid.filters.number = function (value, filterFor) { if (!filterFor) { return true; } console.log('number filter executed'); return value === filterFor; }; grid.setFilter('id', 1); }; window.tutorials['Simple context menu|Add your own items to the context menu.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.addEventListener('contextmenu', function (e) { e.items.push({ title: 'Select all', click: function (ev) { grid.selectArea({ top: 0, bottom: grid.data.length - 1, left: 0, right: grid.schema.length - 1 }); grid.draw(); } }); }); }; window.tutorials['Hierarchal context menus|Add hierarchal items to the context menu.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.addEventListener('contextmenu', function (e) { e.items.push({ title: 'Top level item', items: [ { title: 'Child item #1', click: function (ev) { grid.data[0].col1 = e.cell.value; grid.draw(); } }, { title: 'Child item #2', click: function (ev) { grid.data[0].col1 = e.cell.value; grid.draw(); } } ] }); e.items.push({ title: 'You have ' + grid.selectedRows.filter(function (row) { return !!row; }).length + ' rows selected' }); }); }; window.tutorials['Context menu using a function for items|Instead of using an array, you can use a function that returns an array.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.addEventListener('contextmenu', function (e) { e.items.push({ title: 'Function based child context menu item', items: function () { return [{ title: 'I was added via a function', click: function () { return; } }]; } }); }); }; window.tutorials['Asynchronous context items|Instead of an array, you can use a function that invokes a callback. When you invoke the callback you pass an array to it to add items to the context menu asynchronously.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.addEventListener('contextmenu', function (e) { e.items.push({ title: 'Asynchronous child context menu item', items: function (callback) { setTimeout(function () { callback([{ title: 'I was added later', click: function () { return; } }]); }, 500); } }); }); }; window.tutorials['Remove context menu items|You can mutate the existing items in the context menu.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.addEventListener('contextmenu', function (e) { e.items.splice(0, e.items.length); e.items.push({ title: 'Just me now' }); }); }; window.tutorials['Create complex context menu|If you set the value of title to a HTML element reference, you can add complex functionality to the context menu. To prevent the context menu from closing call <i>e.stopPropagation</i> on the object clicked on.'] = function (parentNode) { var content = document.createElement('div'), upButton = document.createElement('button'), downButton = document.createElement('button'), grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'}, {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'}, {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'}, {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); content.appendChild(upButton); content.appendChild(downButton); upButton.innerHTML = 'Scroll Up'; downButton.innerHTML = 'Scroll Down'; upButton.addEventListener('click', function (e) { grid.scrollTop -= 10; e.stopPropagation(); }); downButton.addEventListener('click', function (e) { grid.scrollTop += 10; e.stopPropagation(); }); content.addEventListener('click', function (e) { e.stopPropagation(); }); grid.addEventListener('contextmenu', function (e) { e.items.splice(0, e.items.length); e.items.push({ title: content }); }); }; window.tutorials['Alter runtime style|Change styles after the grid has been instantiated. All styles can be changed at any time.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.style.columnHeaderCellBackgroundColor = 'dodgerblue'; grid.style.columnHeaderCellColor = 'white'; }; window.tutorials['Canvas fill styles|An example of using complex fill styles on the canvas.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }), gradient = grid.ctx.createLinearGradient(0, 0, 1300, 1300); gradient.addColorStop(0, 'dodgerblue'); gradient.addColorStop(1, 'chartreuse'); grid.style.cellBackgroundColor = gradient; grid.style.gridBackgroundColor = gradient; }; window.tutorials['Alter startup styles|Change the styles during instantiation.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, style: { cellBackgroundColor: 'navy', cellColor: 'wheat' }, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.data = [ {Ei: 'principes', melius: 'causae'}, {Ei: 'omittam', melius: 'audire'}, {Ei: 'mea', melius: 'quot'}, {Ei: 'pericula', melius: 'offendit'} ]; }; window.tutorials['Replace all styles at runtime|Replace the entire style object at runtime.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.style = { cellBackgroundColor: 'darkred', cellColor: 'goldenrod' }; }; window.tutorials['Selection Mode Row|Prevents the selection of individual cells forcing the row to become selected.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.attributes.selectionMode = 'row'; }; window.tutorials['Scroll to a cell'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'}, {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'}, {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'}, {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.scrollIntoView(2, 2); }; window.tutorials['Conditionally set colors|Change styles during the <i>rendercell</i> event.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode }); grid.addEventListener('rendercell', function (e) { if (e.cell.header.name === 'Ei' && /omittam/.test(e.cell.value)) { e.ctx.fillStyle = '#AEEDCF'; } }); grid.data = [ {Ei: 'principes', melius: 'causae'}, {Ei: 'omittam', melius: 'audire'}, {Ei: 'mea', melius: 'quot'}, {Ei: 'pericula', melius: 'offendit'} ]; }; window.tutorials['Validate input|In this example, by using the <i>beforeendedit</i> event you can prevent digits from being entered.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 'a', col3: 'a'}, {col1: 'bar', col2: 'b', col3: 'b'}, {col1: 'baz', col2: 'c', col3: 'c'} ] }); grid.addEventListener('beforeendedit', function (e) { if (/\d+/.test(e.newValue)) { alert('NO DIGITS!'); e.preventDefault(); } }); }; window.tutorials['Edit a cell|Use the interface to focus a cell, then begin editing a cell.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'}, {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'}, {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'}, {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.scrollIntoView(2, 3); grid.beginEditAt(2, 3); }; window.tutorials['Set the width of a column'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.setColumnWidth(0, 60); grid.setColumnWidth(1, 200); }; window.tutorials['Order by a column|By providing the order method with a column name and order (default ascending) you can change the sort order.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.order(grid.schema[0].name, 'asc'); }; window.tutorials['Select an area|Select an area of the grid using a <i>rect</i> object.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a', col4: 'z'}, {col1: 'bar', col2: 1, col3: 'b', col4: 'x'}, {col1: 'baz', col2: 2, col3: 'c', col4: 'w'}, {col1: 'foo', col2: 0, col3: 'a', col4: 'u'}, {col1: 'bar', col2: 1, col3: 'b', col4: 'l'}, {col1: 'baz', col2: 2, col3: 'c', col4: 'e'}, {col1: 'foo', col2: 0, col3: 'a', col4: 'c'}, {col1: 'bar', col2: 1, col3: 'b', col4: 'n'}, {col1: 'baz', col2: 2, col3: 'c', col4: 'b'} ] }); grid.selectArea({ top: 2, bottom: 6, left: 1, right: 2 }); grid.draw(); }; window.tutorials['Remove all rows|Just get rid of all the data. It is silly data anyway.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.data = []; }; window.tutorials['Allow new rows|Allow the input of new rows at the bottom of the grid.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.attributes.showNewRow = true; }; window.tutorials['Create a web component grid'] = function (parentNode) { var grid = document.createElement('canvas-datagrid'); parentNode.appendChild(grid); grid.data = [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ]; }; window.tutorials['Change a columns\'s title'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.schema[0].title = 'foo'; grid.draw(); }; window.tutorials['Add a column|There is also an insert version of this function.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.addColumn({ defaultValue: function (e) { return new Date().toString(); }, title: 'Bar', type: 'date', name: 'bar' }); }; window.tutorials['Add a row|There is also an insert version of this function.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.addRow({ col1: 'a ' + new Date().toString(), col2: 'a ' + new Date().toString(), col3: 'a ' + new Date().toString() }); }; window.tutorials['Draw HTML via Event|This draws HTML into an SVG object, takes a picture of it and caches it into the grid, then draws it into the cell. In other words, it works, but it\'s slow.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.addEventListener('afterrendercell', function (e) { if (e.cell.columnIndex === 1 && e.cell.rowIndex > -1) { e.cell.innerHTML = '<div style="display: inline-block; color: dodgerblue; font-size: 2em;">' + e.cell.value + '</div>' + '<div style="display: inline-block; margin: -20px -20px; filter: blur(5px); font-size: 2em;">' + e.cell.value + '</div>'; } }); grid.draw(); }; window.tutorials['Draw HTML via data type|This draws HTML into an SVG object, takes a picture of it and caches it into the grid, then draws it into the cell. In other words, it works, but it\'s slow.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.schema = [{name: 'id', type: 'number'}, {name: 'offendit', type: 'html'}]; grid.data = [ {id: 0, offendit: 'number'}, {id: 0, offendit: 'number'}, ]; grid.draw(); }; window.tutorials['Open a tree|Open a tree grid on a specific row. Use the <i>expandtree</i> event to control the data and settings of the tree grid.'] = function (parentNode) { function createData() { var x, y, d = []; for (x = 0; x < 2000; x += 1) { d[x] = {}; for (y = 0; y < 20; y += 1) { d[x][y] = y * x; } } return d; } var grid = canvasDatagrid({ parentNode: parentNode, data: createData() }); grid.addEventListener('expandtree', function expandTree(e) { e.treeGrid.data = createData(); // prevent repeated executions of this example code from blowing things up e.treeGrid.removeEventListener('expandtree', expandTree); }); grid.expandTree(2); }; window.tutorials['Allow users to open trees|Allows users to open trees. Use the <i>expandtree</i> event to control the data and settings of the tree grid.'] = function (parentNode) { function createData() { var x, y, d = []; for (x = 0; x < 2000; x += 1) { d[x] = {}; for (y = 0; y < 20; y += 1) { d[x][y] = y * x; } } return d; } var grid = canvasDatagrid({ parentNode: parentNode, data: createData() }); grid.attributes.tree = true; function expandTree(e) { e.treeGrid.addEventListener('expandtree', expandTree); e.treeGrid.attributes.tree = true; e.treeGrid.data = createData(); } grid.addEventListener('expandtree', expandTree); }; window.tutorials['Multiple filters|Create filters on more than one column at a time.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode }), x, data = [], d, i, c, r = 'The,quick,brown,fox,jumps,over,the,lazy,dog'; grid.data = []; c = r.split(',').map(function (i) { return i.trim(); }); r = r.split(',').map(function (i) { return i.trim(); }); for (x = 0; x < 10000; x += 1) { d = {}; for (i = 0; i < r.length; i += 1) { d[r[i]] = c[Math.floor(Math.random() * 1000) % (c.length - 1)]; } data.push(d); } // add the data to the grid grid.data = data.concat(grid.data); grid.setFilter('quick', '/the/i'); grid.setFilter('brown', 'quick'); }; window.tutorials['Draw a picture|Draw a picture into a cell. First hook into <i>rendertext</i> to show the text "No Image" text if there is no image. Then hook into <i>afterrendercell</i> to actually create an image element, hook into the image load event and draw the image once it\'s loaded.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode }), // place to store Image objects imgs = {}; // stop the cell from rendering text grid.addEventListener('rendertext', function (e) { if (e.cell.rowIndex > -1) { if (e.cell.header.name === 'image') { e.cell.formattedValue = e.cell.value ? '' : 'No Image'; } } }); // after the cell is rendered, draw on top of it grid.addEventListener('afterrendercell', function (e) { var i, contextGrid = this; if (e.cell.header.name === 'image' && e.cell.value && e.cell.rowIndex > -1) { // if we haven't already made an image for this, do it now if (!imgs[e.cell.value]) { // create a new image object and store it in the imgs object i = imgs[e.cell.value] = new Image(); // get the image path from the cell's value i.src = e.cell.value; // when the image finally loads // call draw() again to run the else path i.onload = function (parentNode) { contextGrid.draw(); }; return; } // if we have an image already, draw it. i = imgs[e.cell.value]; if (i.width !== 0) { i.targetHeight = e.cell.height; i.targetWidth = e.cell.height * (i.width / i.height); e.ctx.drawImage(i, e.cell.x, e.cell.y, i.targetWidth, i.targetHeight); } } }); // add some images grid.data = [ { image: 'https://imgfly.me/content/images/system/home_cover_1487462088616_671176.jpg', melius: 'causae' }, { image: 'https://imgfly.me/content/images/system/home_cover_1487462024769_865e94.jpg', melius: 'omittam' }, { image: 'https://imgfly.me/content/images/system/home_cover_1487462098680_a9930c.jpg', melius: 'explicari' }, { image: '', melius: 'principes' } ]; // set the column widths and row heights grid.setColumnWidth(0, 300); grid.data.forEach(function (d, index) { grid.setRowHeight(index, 200); }); }; window.tutorials['Toggle debug data|Show fun debugging information. What are all these numbers? File a bug ticket to find out!'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode, data: [ {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'}, {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'}, {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'}, {col1: 'foo', col2: 0, col3: 'a'}, {col1: 'bar', col2: 1, col3: 'b'}, {col1: 'baz', col2: 2, col3: 'c'} ] }); grid.attributes.debug = !grid.attributes.debug; }; window.tutorials['Display unicode samples|Unicode works if it is properly encoded using \\u escape sequences.'] = function (parentNode) { var grid = canvasDatagrid({ parentNode: parentNode }); grid.data = [ {'Block': 'Basic Latin', 'Sample': '! " # $ % & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \\ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~'}, {'Block': 'Latin-1 Supplement', 'Sample': ' \u00A1 \u00A2 \u00A3 \u00A4 \u00A5 \u00A6 \u00A7 \u00A8 \u00A9 \u00AA \u00AB \u00AC \u00AD \u00AE \u00AF \u00B0 \u00B1 \u00B2 \u00B3 \u00B4 \u00B5 \u00B6 \u00B7 \u00B8 \u00B9 \u00BA \u00BB \u00BC \u00BD \u00BE \u00BF \u00C0 \u00C1 \u00C2 \u00C3 \u00C4 \u00C5 \u00C6 \u00C7 \u00C8 \u00C9 \u00CA \u00CB \u00CC \u00CD \u00CE \u00CF \u00D0 \u00D1 \u00D2 \u00D3 \u00D4 \u00D5 \u00D6 \u00D7 \u00D8 \u00D9 \u00DA \u00DB \u00DC \u00DD \u00DE \u00DF \u00E0 \u00E1 \u00E2 \u00E3 \u00E4 \u00E5 \u00E6 \u00E7 \u00E8 \u00E9 \u00EA \u00EB \u00EC \u00ED \u00EE \u00EF \u00F0 \u00F1 \u00F2 \u00F3 \u00F4 \u00F5 \u00F6 \u00F7 \u00F8 \u00F9 \u00FA \u00FB \u00FC \u00FD \u00FE \u00FF'}, {'Block': 'Latin Extended-A', 'Sample': '\u0100 \u0101 \u0102 \u0103 \u0104 \u0105 \u0106 \u0107 \u0108 \u0109 \u010A \u010B \u010C \u010D \u010E \u010F \u0110 \u0111 \u0112 \u0113 \u0114 \u0115 \u0116 \u0117 \u0118 \u0119 \u011A \u011B \u011C \u011D \u011E \u011F \u0120 \u0121 \u0122 \u0123 \u0124 \u0125 \u0126 \u0127 \u0128 \u0129 \u012A \u012B \u012C \u012D \u012E \u012F \u0130 \u0131 \u0132 \u0133 \u0134 \u0135 \u0136 \u0137 \u0138 \u0139 \u013A \u013B \u013C \u013D \u013E \u013F \u0140 \u0141 \u0142 \u0143 \u0144 \u0145 \u0146 \u0147 \u0148 \u0149 \u014A \u014B \u014C \u014D \u014E \u014F \u0150 \u0151 \u0152 \u0153 \u0154 \u0155 \u0156 \u0157 \u0158 \u0159 \u015A \u015B \u015C \u015D \u015E \u015F \u0160 \u0161 \u0162 \u0163 \u0164 \u0165 \u0166 \u0167 \u0168 \u0169 \u016A \u016B \u016C \u016D \u016E \u016F \u0170 \u0171 \u0172 \u0173 \u0174 \u0175 \u0176 \u0177 \u0178 \u0179 \u017A \u017B \u017C \u017D \u017E \u017F'}, {'Block': 'Latin Extended-B', 'Sample': '\u0180 \u0181 \u0182 \u0183 \u0184 \u0185 \u0186 \u0187 \u0188 \u0189 \u018A \u018B \u018C \u018D \u018E \u018F \u0190 \u0191 \u0192 \u0193 \u0194 \u0195 \u0196 \u0197 \u0198 \u0199 \u019A \u019B \u019C \u019D \u019E \u019F \u01A0 \u01A1 \u01A2 \u01A3 \u01A4 \u01A5 \u01A6 \u01A7 \u01A8 \u01A9 \u01AA \u01AB \u01AC \u01AD \u01AE \u01AF \u01B0 \u01B1 \u01B2 \u01B3 \u01B4 \u01B5 \u01B6 \u01B7 \u01B8 \u01B9 \u01BA \u01BB \u01BC \u01BD \u01BE \u01BF \u01C0 \u01C1 \u01C2 \u01C3 \u01C4 \u01C5 \u01C6 \u01C7 \u01C8 \u01C9 \u01CA \u01CB \u01CC \u01CD \u01CE \u01CF \u01D0 \u01D1 \u01D2 \u01D3 \u01D4 \u01D5 \u01D6 \u01D7 \u01D8 \u01D9 \u01DA \u01DB \u01DC \u01DD \u01DE \u01DF \u01E0 \u01E1 \u01E2 \u01E3 \u01E4 \u01E5 \u01E6 \u01E7 \u01E8 \u01E9 \u01EA \u01EB \u01EC \u01ED \u01EE \u01EF \u01F0 \u01F1 \u01F2 \u01F3 \u01F4 \u01F5 \u01F6 \u01F7 \u01F8 \u01F9 \u01FA \u01FB \u01FC \u01FD \u01FE \u01FF ...'}, {'Block': 'IPA Extensions', 'Sample': '\u0250 \u0251 \u0252 \u0253 \u0254 \u0255 \u0256 \u0257 \u0258 \u0259 \u025A \u025B \u025C \u025D \u025E \u025F \u0260 \u0261 \u0262 \u0263 \u0264 \u0265 \u0266 \u0267 \u0268 \u0269 \u026A \u026B \u026C \u026D \u026E \u026F \u0270 \u0271 \u0272 \u0273 \u0274 \u0275 \u0276 \u0277 \u0278 \u0279 \u027A \u027B \u027C \u027D \u027E \u027F \u0280 \u0281 \u0282 \u0283 \u0284 \u0285 \u0286 \u0287 \u0288 \u0289 \u028A \u028B \u028C \u028D \u028E \u028F \u0290 \u0291 \u0292 \u0293 \u0294 \u0295 \u0296 \u0297 \u0298 \u0299 \u029A \u029B \u029C \u029D \u029E \u029F \u02A0 \u02A1 \u02A2 \u02A3 \u02A4 \u02A5 \u02A6 \u02A7 \u02A8 \u02A9 \u02AA \u02AB \u02AC \u02AD'}, {'Block': 'Spacing Modifier Letters', 'Sample': '\u02B0 \u02B1 \u02B2 \u02B3 \u02B4 \u02B5 \u02B6 \u02B7 \u02B8 \u02B9 \u02BA \u02BB \u02BC \u02BD \u02BE \u02BF \u02C0 \u02C1 \u02C2 \u02C3 \u02C4 \u02C5 \u02C6 \u02C7 \u02C8 \u02C9 \u02CA \u02CB \u02CC \u02CD \u02CE \u02CF \u02D0 \u02D1 \u02D2 \u02D3 \u02D4 \u02D5 \u02D6 \u02D7 \u02D8 \u02D9 \u02DA \u02DB \u02DC \u02DD \u02DE \u02DF \u02E0 \u02E1 \u02E2 \u02E3 \u02E4 \u02E5 \u02E6 \u02E7 \u02E8 \u02E9 \u02EA \u02EB \u02EC \u02ED \u02EE'}, {'Block': 'Combining Diacritical Marks', 'Sample': '\u0300 \u0301 \u0302 \u0303 \u0304 \u0305 \u0306 \u0307 \u0308 \u0309 \u030A \u030B \u030C \u030D \u030E \u030F \u0310 \u0311 \u0312 \u0313 \u0314 \u0315 \u0316 \u0317 \u0318 \u0319 \u031A \u031B \u031C \u031D \u031E \u031F \u0320 \u0321 \u0322 \u0323 \u0324 \u0325 \u0326 \u0327 \u0328 \u0329 \u032A \u032B \u032C \u032D \u032E \u032F \u0330 \u0331 \u0332 \u0333 \u0334 \u0335 \u0336 \u0337 \u0338 \u0339 \u033A \u033B \u033C \u033D \u033E \u033F \u0340 \u0341 \u0342 \u0343 \u0344 \u0345 \u0346 \u0347 \u0348 \u0349 \u034A \u034B \u034C \u034D \u034E \u034F \u0360 \u0361 \u0362 \u0363 \u0364 \u0365 \u0366 \u0367 \u0368 \u0369 \u036A \u036B \u036C \u036D \u036E \u036F'}, {'Block': 'Greek and Coptic', 'Sample': '\u0374 \u0375 \u037A \u037E \u0384 \u0385 \u0386 \u0387 \u0388 \u0389 \u038A \u038C \u038E \u038F \u0390 \u0391 \u0392 \u0393 \u0394 \u0395 \u0396 \u0397 \u0398 \u0399 \u039A \u039B \u039C \u039D \u039E \u039F \u03A0 \u03A1 \u03A3 \u03A4 \u03A5 \u03A6 \u03A7 \u03A8 \u03A9 \u03AA \u03AB \u03AC \u03AD \u03AE \u03AF \u03B0 \u03B1 \u03B2 \u03B3 \u03B4 \u03B5 \u03B6 \u03B7 \u03B8 \u03B9 \u03BA \u03BB \u03BC \u03BD \u03BE \u03BF \u03C0 \u03C1 \u03C2 \u03C3 \u03C4 \u03C5 \u03C6 \u03C7 \u03C8 \u03C9 \u03CA \u03CB \u03CC \u03CD \u03CE \u03D0 \u03D1 \u03D2 \u03D3 \u03D4 \u03D5 \u03D6 \u03D7 \u03D8 \u03D9 \u03DA \u03DB \u03DC \u03DD \u03DE \u03DF \u03E0 \u03E1 \u03E2 \u03E3 \u03E4 \u03E5 \u03E6 \u03E7 \u03E8 \u03E9 \u03EA \u03EB \u03EC \u03ED \u03EE \u03EF \u03F0 \u03F1 \u03F2 \u03F3 \u03F4 \u03F5 \u03F6'}, {'Block': 'Cyrillic', 'Sample': '\u0400 \u0401 \u0402 \u0403 \u0404 \u0405 \u0406 \u0407 \u0408 \u0409 \u040A \u040B \u040C \u040D \u040E \u040F \u0410 \u0411 \u0412 \u0413 \u0414 \u0415 \u0416 \u0417 \u0418 \u0419 \u041A \u041B \u041C \u041D \u041E \u041F \u0420 \u0421 \u0422 \u0423 \u0424 \u0425 \u0426 \u0427 \u0428 \u0429 \u042A \u042B \u042C \u042D \u042E \u042F \u0430 \u0431 \u0432 \u0433 \u0434 \u0435 \u0436 \u0437 \u0438 \u0439 \u043A \u043B \u043C \u043D \u043E \u043F \u0440 \u0441 \u0442 \u0443 \u0444 \u0445 \u0446 \u0447 \u0448 \u0449 \u044A \u044B \u044C \u044D \u044E \u044F \u0450 \u0451 \u0452 \u0453 \u0454 \u0455 \u0456 \u0457 \u0458 \u0459 \u045A \u045B \u045C \u045D \u045E \u045F \u0460 \u0461 \u0462 \u0463 \u0464 \u0465 \u0466 \u0467 \u0468 \u0469 \u046A \u046B \u046C \u046D \u046E \u046F \u0470 \u0471 \u0472 \u0473 \u0474 \u0475 \u0476 \u0477 \u0478 \u0479 \u047A \u047B \u047C \u047D \u047E \u047F ...'}, {'Block': 'Cyrillic Supplementary', 'Sample': '\u0500 \u0501 \u0502 \u0503 \u0504 \u0505 \u0506 \u0507 \u0508 \u0509 \u050A \u050B \u050C \u050D \u050E \u050F'}, {'Block': 'Armenian', 'Sample': '\u0531 \u0532 \u0533 \u0534 \u0535 \u0536 \u0537 \u0538 \u0539 \u053A \u053B \u053C \u053D \u053E \u053F \u0540 \u0541 \u0542 \u0543 \u0544 \u0545 \u0546 \u0547 \u0548 \u0549 \u054A \u054B \u054C \u054D \u054E \u054F \u0550 \u0551 \u0552 \u0553 \u0554 \u0555 \u0556 \u0559 \u055A \u055B \u055C \u055D \u055E \u055F \u0561 \u0562 \u0563 \u0564 \u0565 \u0566 \u0567 \u0568 \u0569 \u056A \u056B \u056C \u056D \u056E \u056F \u0570 \u0571 \u0572 \u0573 \u0574 \u0575 \u0576 \u0577 \u0578 \u0579 \u057A \u057B \u057C \u057D \u057E \u057F \u0580 \u0581 \u0582 \u0583 \u0584 \u0585 \u0586 \u0587 \u0589 \u058A'}, {'Block': 'Hebrew', 'Sample': '\u0591 \u0592 \u0593 \u0594 \u0595 \u0596 \u0597 \u0598 \u0599 \u059A \u059B \u059C \u059D \u059E \u059F \u05A0 \u05A1 \u05A3 \u05A4 \u05A5 \u05A6 \u05A7 \u05A8 \u05A9 \u05AA \u05AB \u05AC \u05AD \u05AE \u05AF \u05B0 \u05B1 \u05B2 \u05B3 \u05B4 \u05B5 \u05B6 \u05B7 \u05B8 \u05B9 \u05BB \u05BC \u05BD \u05BE \u05BF \u05C0 \u05C1 \u05C2 \u05C3 \u05C4 \u05D0 \u05D1 \u05D2 \u05D3 \u05D4 \u05D5 \u05D6 \u05D7 \u05D8 \u05D9 \u05DA \u05DB \u05DC \u05DD \u05DE \u05DF \u05E0 \u05E1 \u05E2 \u05E3 \u05E4 \u05E5 \u05E6 \u05E7 \u05E8 \u05E9 \u05EA \u05F0 \u05F1 \u05F2 \u05F3 \u05F4'}, {'Block': 'Arabic', 'Sample': '\u060C \u061B \u061F \u0621 \u0622 \u0623 \u0624 \u0625 \u0626 \u0627 \u0628 \u0629 \u062A \u062B \u062C \u062D \u062E \u062F \u0630 \u0631 \u0632 \u0633 \u0634 \u0635 \u0636 \u0637 \u0638 \u0639 \u063A \u0640 \u0641 \u0642 \u0643 \u0644 \u0645 \u0646 \u0647 \u0648 \u0649 \u064A \u064B \u064C \u064D \u064E \u064F \u0650 \u0651 \u0652 \u0653 \u0654 \u0655 \u0660 \u0661 \u0662 \u0663 \u0664 \u0665 \u0666 \u0667 \u0668 \u0669 \u066A \u066B \u066C \u066D \u066E \u066F \u0670 \u0671 \u0672 \u0673 \u0674 \u0675 \u0676 \u0677 \u0678 \u0679 \u067A \u067B \u067C \u067D \u067E \u067F \u0680 \u0681 \u0682 \u0683 \u0684 \u0685 \u0686 \u0687 \u0688 \u0689 \u068A \u068B \u068C \u068D \u068E \u068F \u0690 \u0691 \u0692 \u0693 \u0694 \u0695 \u0696 \u0697 \u0698 \u0699 \u069A \u069B \u069C \u069D \u069E \u069F \u06A0 \u06A1 \u06A2 \u06A3 \u06A4 \u06A5 \u06A6 \u06A7 \u06A8 \u06A9 \u06AA \u06AB \u06AC ...'}, {'Block': 'Syriac', 'Sample': '\u0700 \u0701 \u0702 \u0703 \u0704 \u0705 \u0706 \u0707 \u0708 \u0709 \u070A \u070B \u070C \u070D \u070F \u0710 \u0711 \u0712 \u0713 \u0714 \u0715 \u0716 \u0717 \u0718 \u0719 \u071A \u071B \u071C \u071D \u071E \u071F \u0720 \u0721 \u0722 \u0723 \u0724 \u0725 \u0726 \u0727 \u0728 \u0729 \u072A \u072B \u072C \u0730 \u0731 \u0732 \u0733 \u0734 \u0735 \u0736 \u0737 \u0738 \u0739 \u073A \u073B \u073C \u073D \u073E \u073F \u0740 \u0741 \u0742 \u0743 \u0744 \u0745 \u0746 \u0747 \u0748 \u0749 \u074A'}, {'Block': 'Thaana', 'Sample': '\u0780 \u0781 \u0782 \u0783 \u0784 \u0785 \u0786 \u0787 \u0788 \u0789 \u078A \u078B \u078C \u078D \u078E \u078F \u0790 \u0791 \u0792 \u0793 \u0794 \u0795 \u0796 \u0797 \u0798 \u0799 \u079A \u079B \u079C \u079D \u079E \u079F \u07A0 \u07A1 \u07A2 \u07A3 \u07A4 \u07A5 \u07A6 \u07A7 \u07A8 \u07A9 \u07AA \u07AB \u07AC \u07AD \u07AE \u07AF \u07B0 \u07B1'}, {'Block': 'Devanagari', 'Sample': '\u0901 \u0902 \u0903 \u0905 \u0906 \u0907 \u0908 \u0909 \u090A \u090B \u090C \u090D \u090E \u090F \u0910 \u0911 \u0912 \u0913 \u0914 \u0915 \u0916 \u0917 \u0918 \u0919 \u091A \u091B \u091C \u091D \u091E \u091F \u0920 \u0921 \u0922 \u0923 \u0924 \u0925 \u0926 \u0927 \u0928 \u0929 \u092A \u092B \u092C \u092D \u092E \u092F \u0930 \u0931 \u0932 \u0933 \u0934 \u0935 \u0936 \u0937 \u0938 \u0939 \u093C \u093D \u093E \u093F \u0940 \u0941 \u0942 \u0943 \u0944 \u0945 \u0946 \u0947 \u0948 \u0949 \u094A \u094B \u094C \u094D \u0950 \u0951 \u0952 \u0953 \u0954 \u0958 \u0959 \u095A \u095B \u095C \u095D \u095E \u095F \u0960 \u0961 \u0962 \u0963 \u0964 \u0965 \u0966 \u0967 \u0968 \u0969 \u096A \u096B \u096C \u096D \u096E \u096F \u0970'}, {'Block': 'Bengali', 'Sample': '\u0981 \u0982 \u0983 \u0985 \u0986 \u0987 \u0988 \u0989 \u098A \u098B \u098C \u098F \u0990 \u0993 \u0994 \u0995 \u0996 \u0997 \u0998 \u0999 \u099A \u099B \u099C \u099D \u099E \u099F \u09A0 \u09A1 \u09A2 \u09A3 \u09A4 \u09A5 \u09A6 \u09A7 \u09A8 \u09AA \u09AB \u09AC \u09AD \u09AE \u09AF \u09B0 \u09B2 \u09B6 \u09B7 \u09B8 \u09B9 \u09BC \u09BE \u09BF \u09C0 \u09C1 \u09C2 \u09C3 \u09C4 \u09C7 \u09C8 \u09CB \u09CC \u09CD \u09D7 \u09DC \u09DD \u09DF \u09E0 \u09E1 \u09E2 \u09E3 \u09E6 \u09E7 \u09E8 \u09E9 \u09EA \u09EB \u09EC \u09ED \u09EE \u09EF \u09F0 \u09F1 \u09F2 \u09F3 \u09F4 \u09F5 \u09F6 \u09F7 \u09F8 \u09F9 \u09FA'}, {'Block': 'Gurmukhi', 'Sample': '\u0A02 \u0A05 \u0A06 \u0A07 \u0A08 \u0A09 \u0A0A \u0A0F \u0A10 \u0A13 \u0A14 \u0A15 \u0A16 \u0A17 \u0A18 \u0A19 \u0A1A \u0A1B \u0A1C \u0A1D \u0A1E \u0A1F \u0A20 \u0A21 \u0A22 \u0A23 \u0A24 \u0A25 \u0A26 \u0A27 \u0A28 \u0A2A \u0A2B \u0A2C \u0A2D \u0A2E \u0A2F \u0A30 \u0A32 \u0A33 \u0A35 \u0A36 \u0A38 \u0A39 \u0A3C \u0A3E \u0A3F \u0A40 \u0A41 \u0A42 \u0A47 \u0A48 \u0A4B \u0A4C \u0A4D \u0A59 \u0A5A \u0A5B \u0A5C \u0A5E \u0A66 \u0A67 \u0A68 \u0A69 \u0A6A \u0A6B \u0A6C \u0A6D \u0A6E \u0A6F \u0A70 \u0A71 \u0A72 \u0A73 \u0A74'}, {'Block': 'Gujarati', 'Sample': '\u0A81 \u0A82 \u0A83 \u0A85 \u0A86 \u0A87 \u0A88 \u0A89 \u0A8A \u0A8B \u0A8D \u0A8F \u0A90 \u0A91 \u0A93 \u0A94 \u0A95 \u0A96 \u0A97 \u0A98 \u0A99 \u0A9A \u0A9B \u0A9C \u0A9D \u0A9E \u0A9F \u0AA0 \u0AA1 \u0AA2 \u0AA3 \u0AA4 \u0AA5 \u0AA6 \u0AA7 \u0AA8 \u0AAA \u0AAB \u0AAC \u0AAD \u0AAE \u0AAF \u0AB0 \u0AB2 \u0AB3 \u0AB5 \u0AB6 \u0AB7 \u0AB8 \u0AB9 \u0ABC \u0ABD \u0ABE \u0ABF \u0AC0 \u0AC1 \u0AC2 \u0AC3 \u0AC4 \u0AC5 \u0AC7 \u0AC8 \u0AC9 \u0ACB \u0ACC \u0ACD \u0AD0 \u0AE0 \u0AE6 \u0AE7 \u0AE8 \u0AE9 \u0AEA \u0AEB \u0AEC \u0AED \u0AEE \u0AEF'}, {'Block': 'Oriya', 'Sample': '\u0B01 \u0B02 \u0B03 \u0B05 \u0B06 \u0B07 \u0B08 \u0B09 \u0B0A \u0B0B \u0B0C \u0B0F \u0B10 \u0B13 \u0B14 \u0B15 \u0B16 \u0B17 \u0B18 \u0B19 \u0B1A \u0B1B \u0B1C \u0B1D \u0B1E \u0B1F \u0B20 \u0B21 \u0B22 \u0B23 \u0B24 \u0B25 \u0B26 \u0B27 \u0B28 \u0B2A \u0B2B \u0B2C \u0B2D \u0B2E \u0B2F \u0B30 \u0B32 \u0B33 \u0B36 \u0B37 \u0B38 \u0B39 \u0B3C \u0B3D \u0B3E \u0B3F \u0B40 \u0B41 \u0B42 \u0B43 \u0B47 \u0B48 \u0B4B \u0B4C \u0B4D \u0B56 \u0B57 \u0B5C \u0B5D \u0B5F \u0B60 \u0B61 \u0B66 \u0B67 \u0B68 \u0B69 \u0B6A \u0B6B \u0B6C \u0B6D \u0B6E \u0B6F \u0B70'}, {'Block': 'Tamil', 'Sample': '\u0B82 \u0B83 \u0B85 \u0B86 \u0B87 \u0B88 \u0B89 \u0B8A \u0B8E \u0B8F \u0B90 \u0B92 \u0B93 \u0B94 \u0B95 \u0B99 \u0B9A \u0B9C \u0B9E \u0B9F \u0BA3 \u0BA4 \u0BA8 \u0BA9 \u0BAA \u0BAE \u0BAF \u0BB0 \u0BB1 \u0BB2 \u0BB3 \u0BB4 \u0BB5 \u0BB7 \u0BB8 \u0BB9 \u0BBE \u0BBF \u0BC0 \u0BC1 \u0BC2 \u0BC6 \u0BC7 \u0BC8 \u0BCA \u0BCB \u0BCC \u0BCD \u0BD7 \u0BE7 \u0BE8 \u0BE9 \u0BEA \u0BEB \u0BEC \u0BED \u0BEE \u0BEF \u0BF0 \u0BF1 \u0BF2'}, {'Block': 'Telugu', 'Sample': '\u0C01 \u0C02 \u0C03 \u0C05 \u0C06 \u0C07 \u0C08 \u0C09 \u0C0A \u0C0B \u0C0C \u0C0E \u0C0F \u0C10 \u0C12 \u0C13 \u0C14 \u0C15 \u0C16 \u0C17 \u0C18 \u0C19 \u0C1A \u0C1B \u0C1C \u0C1D \u0C1E \u0C1F \u0C20 \u0C21 \u0C22 \u0C23 \u0C24 \u0C25 \u0C26 \u0C27 \u0C28 \u0C2A \u0C2B \u0C2C \u0C2D \u0C2E \u0C2F \u0C30 \u0C31 \u0C32 \u0C33 \u0C35 \u0C36 \u0C37 \u0C38 \u0C39 \u0C3E \u0C3F \u0C40 \u0C41 \u0C42 \u0C43 \u0C44 \u0C46 \u0C47 \u0C48 \u0C4A \u0C4B \u0C4C \u0C4D \u0C55 \u0C56 \u0C60 \u0C61 \u0C66 \u0C67 \u0C68 \u0C69 \u0C6A \u0C6B \u0C6C \u0C6D \u0C6E \u0C6F'}, {'Block': 'Kannada', 'Sample': '\u0C82 \u0C83 \u0C85 \u0C86 \u0C87 \u0C88 \u0C89 \u0C8A \u0C8B \u0C8C \u0C8E \u0C8F \u0C90 \u0C92 \u0C93 \u0C94 \u0C95 \u0C96 \u0C97 \u0C98 \u0C99 \u0C9A \u0C9B \u0C9C \u0C9D \u0C9E \u0C9F \u0CA0 \u0CA1 \u0CA2 \u0CA3 \u0CA4 \u0CA5 \u0CA6 \u0CA7 \u0CA8 \u0CAA \u0CAB \u0CAC \u0CAD \u0CAE \u0CAF \u0CB0 \u0CB1 \u0CB2 \u0CB3 \u0CB5 \u0CB6 \u0CB7 \u0CB8 \u0CB9 \u0CBE \u0CBF \u0CC0 \u0CC1 \u0CC2 \u0CC3 \u0CC4 \u0CC6 \u0CC7 \u0CC8 \u0CCA \u0CCB \u0CCC \u0CCD \u0CD5 \u0CD6 \u0CDE \u0CE0 \u0CE1 \u0CE6 \u0CE7 \u0CE8 \u0CE9 \u0CEA \u0CEB \u0CEC \u0CED \u0CEE \u0CEF'}, {'Block': 'Malayalam', 'Sample': '\u0D02 \u0D03 \u0D05 \u0D06 \u0D07 \u0D08 \u0D09 \u0D0A \u0D0B \u0D0C \u0D0E \u0D0F \u0D10 \u0D12 \u0D13 \u0D14 \u0D15 \u0D16 \u0D17 \u0D18 \u0D19 \u0D1A \u0D1B \u0D1C \u0D1D \u0D1E \u0D1F \u0D20 \u0D21 \u0D22 \u0D23 \u0D24 \u0D25 \u0D26 \u0D27 \u0D28 \u0D2A \u0D2B \u0D2C \u0D2D \u0D2E \u0D2F \u0D30 \u0D31 \u0D32 \u0D33 \u0D34 \u0D35 \u0D36 \u0D37 \u0D38 \u0D39 \u0D3E \u0D3F \u0D40 \u0D41 \u0D42 \u0D43 \u0D46 \u0D47 \u0D48 \u0D4A \u0D4B \u0D4C \u0D4D \u0D57 \u0D60 \u0D61 \u0D66 \u0D67 \u0D68 \u0D69 \u0D6A \u0D6B \u0D6C \u0D6D \u0D6E \u0D6F'}, {'Block': 'Sinhala', 'Sample': '\u0D82 \u0D83 \u0D85 \u0D86 \u0D87 \u0D88 \u0D89 \u0D8A \u0D8B \u0D8C \u0D8D \u0D8E \u0D8F \u0D90 \u0D91 \u0D92 \u0D93 \u0D94 \u0D95 \u0D96 \u0D9A \u0D9B \u0D9C \u0D9D \u0D9E \u0D9F \u0DA0 \u0DA1 \u0DA2 \u0DA3 \u0DA4 \u0DA5 \u0DA6 \u0DA7 \u0DA8 \u0DA9 \u0DAA \u0DAB \u0DAC \u0DAD \u0DAE \u0DAF \u0DB0 \u0DB1 \u0DB3 \u0DB4 \u0DB5 \u0DB6 \u0DB7 \u0DB8 \u0DB9 \u0DBA \u0DBB \u0DBD \u0DC0 \u0DC1 \u0DC2 \u0DC3 \u0DC4 \u0DC5 \u0DC6 \u0DCA \u0DCF \u0DD0 \u0DD1 \u0DD2 \u0DD3 \u0DD4 \u0DD6 \u0DD8 \u0DD9 \u0DDA \u0DDB \u0DDC \u0DDD \u0DDE \u0DDF \u0DF2 \u0DF3 \u0DF4'}, {'Block': 'Thai', 'Sample': '\u0E01 \u0E02 \u0E03 \u0E04 \u0E05 \u0E06 \u0E07 \u0E08 \u0E09 \u0E0A \u0E0B \u0E0C \u0E0D \u0E0E \u0E0F \u0E10 \u0E11 \u0E12 \u0E13 \u0E14 \u0E15 \u0E16 \u0E17 \u0E18 \u0E19 \u0E1A \u0E1B \u0E1C \u0E1D \u0E1E \u0E1F \u0E20 \u0E21 \u0E22 \u0E23 \u0E24 \u0E25 \u0E26 \u0E27 \u0E28 \u0E29 \u0E2A \u0E2B \u0E2C \u0E2D \u0E2E \u0E2F \u0E30 \u0E31 \u0E32 \u0E33 \u0E34 \u0E35 \u0E36 \u0E37 \u0E38 \u0E39 \u0E3A \u0E3F \u0E40 \u0E41 \u0E42 \u0E43 \u0E44 \u0E45 \u0E46 \u0E47 \u0E48 \u0E49 \u0E4A \u0E4B \u0E4C \u0E4D \u0E4E \u0E4F \u0E50 \u0E51 \u0E52 \u0E53 \u0E54 \u0E55 \u0E56 \u0E57 \u0E58 \u0E59 \u0E5A \u0E5B'}, {'Block': 'Lao', 'Sample': '\u0E81 \u0E82 \u0E84 \u0E87 \u0E88 \u0E8A \u0E8D \u0E94 \u0E95 \u0E96 \u0E97 \u0E99 \u0E9A \u0E9B \u0E9C \u0E9D \u0E9E \u0E9F \u0EA1 \u0EA2 \u0EA3 \u0EA5 \u0EA7 \u0EAA \u0EAB \u0EAD \u0EAE \u0EAF \u0EB0 \u0EB1 \u0EB2 \u0EB3 \u0EB4 \u0EB5 \u0EB6 \u0EB7 \u0EB8 \u0EB9 \u0EBB \u0EBC \u0EBD \u0EC0 \u0EC1 \u0EC2 \u0EC3 \u0EC4 \u0EC6 \u0EC8 \u0EC9 \u0ECA \u0ECB \u0ECC \u0ECD \u0ED0 \u0ED1 \u0ED2 \u0ED3 \u0ED4 \u0ED5 \u0ED6 \u0ED7 \u0ED8 \u0ED9 \u0EDC \u0EDD'}, {'Block': 'Tibetan', 'Sample': '\u0F00 \u0F01 \u0F02 \u0F03 \u0F04 \u0F05 \u0F06 \u0F07 \u0F08 \u0F09 \u0F0A \u0F0B \u0F0C \u0F0D \u0F0E \u0F0F \u0F10 \u0F11 \u0F12 \u0F13 \u0F14 \u0F15 \u0F16 \u0F17 \u0F18 \u0F19 \u0F1A \u0F1B \u0F1C \u0F1D \u0F1E \u0F1F \u0F20 \u0F21 \u0F22 \u0F23 \u0F24 \u0F25 \u0F26 \u0F27 \u0F28 \u0F29 \u0F2A \u0F2B \u0F2C \u0F2D \u0F2E \u0F2F \u0F30 \u0F31 \u0F32 \u0F33 \u0F34 \u0F35 \u0F36 \u0F37 \u0F38 \u0F39 \u0F3A \u0F3B \u0F3C \u0F3D \u0F3E \u0F3F \u0F40 \u0F41 \u0F42 \u0F43 \u0F44 \u0F45 \u0F46 \u0F47 \u0F49 \u0F4A \u0F4B \u0F4C \u0F4D \u0F4E \u0F4F \u0F50 \u0F51 \u0F52 \u0F53 \u0F54 \u0F55 \u0F56 \u0F57 \u0F58 \u0F59 \u0F5A \u0F5B \u0F5C \u0F5D \u0F5E \u0F5F \u0F60 \u0F61 \u0F62 \u0F63 \u0F64 \u0F65 \u0F66 \u0F67 \u0F68 \u0F69 \u0F6A \u0F71 \u0F72 \u0F73 \u0F74 \u0F75 \u0F76 \u0F77 \u0F78 \u0F79 \u0F7A \u0F7B \u0F7C \u0F7D \u0F7E \u0F7F \u0F80 \u0F81 \u0F82 \u0F83 \u0F84 \u0F85 \u0F86 ...'}, {'Block': 'Myanmar', 'Sample': '\u1000 \u1001 \u1002 \u1003 \u1004 \u1005 \u1006 \u1007 \u1008 \u1009 \u100A \u100B \u100C \u100D \u100E \u100F \u1010 \u1011 \u1012 \u1013 \u1014 \u1015 \u1016 \u1017 \u1018 \u1019 \u101A \u101B \u101C \u101D \u101E \u101F \u1020 \u1021 \u1023 \u1024 \u1025 \u1026 \u1027 \u1029 \u102A \u102C \u102D \u102E \u102F \u1030 \u1031 \u1032 \u1036 \u1037 \u1038 \u1039 \u1040 \u1041 \u1042 \u1043 \u1044 \u1045 \u1046 \u1047 \u1048 \u1049 \u104A \u104B \u104C \u104D \u104E \u104F \u1050 \u1051 \u1052 \u1053 \u1054 \u1055 \u1056 \u1057 \u1058 \u1059'}, {'Block': 'Georgian', 'Sample': '\u10A0 \u10A1 \u10A2 \u10A3 \u10A4 \u10A5 \u10A6 \u10A7 \u10A8 \u10A9 \u10AA \u10AB \u10AC \u10AD \u10AE