This demo contains sample code showing how to paint custom cell borders as an alterative to using Hypergrid's grid lines feature.
This example uses the default grid lines feature, where grid rule lines are painted between cells after each grid render.
This example uses the Borders
overlay cell renderer, defined herein, which is controlled by optionally defined properties borderTop
, borderTop
, borderBottom
, and borderLeft
, all of which take a CSS color spec. Defining the bottom and right of each cell produces the following result, which is very similar to the default grid lines feature. (These are defined on the grid.properties
object, which each cell has in its properties scope.)
This example also uses the Borders
cell renderer but only defines some borders on selected cells.
This example again uses the Borders
cell renderer, combining examples 2 and 3 above by setting the the properties set by both.
This example uses a different cell renderer, OpaqueBorders
, controlled by a single property, border
whose properties are "opaque" (have no scope). See the discussion below for more details.
var RED = 'red'; var rect = { // cell properties for use with Borders cell renderer data: { // subgrid key 1: { // row index prevclose: { borderLeft: RED, borderTop: RED }, name: { borderTop: RED, borderRight: RED } }, 2: { // row index prevclose: { borderLeft: RED, borderBottom: RED }, name: { borderBottom: RED, borderRight: RED } } } }; var opaqueRect = { // cell properties for use with OpaqueBorders cell renderer data: { // subgrid key 1: { // row index prevclose: { border: { left: RED, top: RED } }, name: { border: { top: RED, right: RED } } }, 2: { // row index prevclose: { border: { left: RED, bottom: RED } }, name: { border: { bottom: RED, right: RED } } } } };
cells
grid property
The cells
grid property is a dynamic property (an accessor),
implemented specifically for use with setState/addState calls.
This is not however the only way to set cell properties; they can also be set programmatically.
Both methods set the cell metadata for you.
Another way is to load the metadata directly.
The definitions used herein, rect
and opaqueRect
are excerpted at right (or see
GitHub).
Borders
vs. OpaqueBorders
It is worth studying the cell renderer examples provided here.
These are both overlay cell renderers in that they perform additional rendering after an initial background cell renderer (in this case SimpleCell
, the default cell renderer).
Disclaimer: As the saying goes, there are "many ways to skin a cat." Likewise, there are many ways to implement cell borders and to write cell renderers. The examples given here are just that: examples. In particular, as with all Hypergrid coding, performance is always in issue. In general, cell borders are never going to be anywhere as performant as Hypergrid's grid lines feature — which renders grid rule lines after all the cells have been rendered.
The Borders
overlay cell renderer
(file or
GitHub)
uses flat properties borderTop
, borderRight
, borderBottom
, and borderLeft
, which have scope up the prototype chain of properties
objects (which typically looks like grid.properties
← column.properties
← cell.properties
) and will "cascade" when a more local definition is lacking.
The OpaqueBorders
overlay cell renderer
(file or
GitHub)
uses a complex (nested) property called border
which may have top
, right
, bottom
, and/or left
properties. But because the border
property itself has no prototype chain, these properties have no scope and will not cascade. The implication of this is that the most local definition of border
must fully describe the cell's borders. This is best explained by observing the difference between the final two examples above (examples 4 and 5). (Note how the grid.properties.border
object is obscured by the cell's border
object.)
A final note: If we were to properly set up the prototype chain of these border
objects (with Object.create
or Object.setPrototypeOf
), then the OpaqueBorders
renderer would produce the same results as the Borders
and we wouldn't need both. However, although this can be demonstrated, doing so in practice would be unmanageable (not to mention subtle and obscure).
Hypergrid's grid lines feature does not paint a grid line at the right of the final column but the cell border is appearing there. To avoid painting this line, we could have "undefined" the final column's borderRight
property to obscure the underlying grid.properties.borderRight
property value, for example by including the columns
dynamic grid property in the addState
call, like this: columns: { name: { borderRight: undefine } }
Module standards in JavaScript are all over the place. There are many ways to split up code into separate files, both at build time as well as in the server. For this demo, I wanted to split up the code into distinctly served .js
files so I could link to them here. To avoid a build just to bundle them, I've defined a window.onload
handler in each, called in the order referenced in `index.html` when the page is loaded.