
Research
GemStuffer Campaign Abuses RubyGems as Exfiltration Channel Targeting UK Local Government
GemStuffer abuses RubyGems as an exfiltration channel, packaging scraped UK council portal data into junk gems published from new accounts.
zebulon-grid
Advanced tools
React pivot grid component for large data sets. Manage measures (aggregated figures) by dimensions (axises) in rows or columns directly on the grid.
Install zebulon-grid using npm.
npm install zebulon-grid --save
And in your code:
import ZebulonGrid from 'zebulon-grid'
import React, { Component } from "react";
import ReactDOM from "react-dom";
import ZebulonGrid from "zebulon-grid";
const buildData = (n0, n1, n2) => {
let data = [];
for (let i0 = 0; i0 < n0; i0++) {
for (let i1 = 0; i1 < n1; i1++) {
for (let i2 = 0; i2 < n2; i2++) {
data.push({
totoId: i0,
totoLabel: `toto${i0}`,
titi: i1,
tutu: `tutu${i2}`,
qty: Math.round(50 * Math.random()) + 1,
amt: Math.round(150 * Math.random()) + 3
});
}
}
}
return data;
};
const buildConfiguration = () => ({
measureHeaders: "columns",
width: 1000,
height: 800,
cellHeight: 30,
cellWidth: 100,
dimensions: [
{
id: "toto",
caption: "Toto",
keyAccessor: "totoId",
labelAccessor: "totoLabel",
sort: {
keyAccessor: "totoLabel"
}
},
{
id: "titi",
caption: "Titi",
keyAccessor: "titi"
},
{
id: "tutu",
caption: "Tutu",
keyAccessor: "tutu"
}
],
measures: [
{
valueAccessor: "qty",
id: "qty",
caption: "Quantity",
aggregation: "sum"
},
{
valueAccessor: "amt",
id: "amt",
caption: "Amount",
aggregation: "sum"
}
],
axis:{
columns: ["tutu"],
rows: ["toto", "titi"],
measures: ["qty", "amt"],
measureHeaders: "columns"
}
});
class MyPivotGrid extends Component {
constructor(props) {
super(props);
this.state = {};
}
data = buildData(20, 12, 7);
configuration = buildConfiguration();
render() {
return (
<ZebulonGrid
data={this.data}
configuration={this.configuration}
sizes={{
height: 600,
width: 1000,
cellWidth: 80,
cellHeight: 28,
zoom: 0.9
}}
/>
);
}
}
ReactDOM.render(<MyPivotGrid />, document.getElementById("root"));
| Property | Type | Description |
|---|---|---|
| configuration | PropTypes.object | Meta description of the multidimensional matrix linked to the data set |
| menuFunctions | PropTypes.object | Custom functions callable from the data cell area contextual menu. |
| configurationFunctions | PropTypes.object | Named custom formats, accessors, sorts and aggregations. |
| data | PropTypes.arrayOf(PropTypes.object) | Data set as an array of objects or a promise. |
| pushedData] | PropTypes.arrayOf(PropTypes.object) | Data set as an array of objects. |
| sizes | PropTypes.object) | sizes of the grid (height, width), zoom, default cell sizes |
The data set (data property) can be either an array of similar objects or a promise that will be resolved as an array of objects.
[
{
totoId: 25,
totoLabel: "toto25",
titi: 3,
tutu: "tutuA",
qty: 100,
amt: 12456
},
{
totoId: 154,
totoLabel: "toto154",
titi: 12,
tutu: "tutuS",
qty: 22,
amt: 2539
},
...
]
Rows can be added dynamically to the data set using the pushedData property. Changed data cells will be highlighted using the corresponding CSS.
The configuration property is an object describing the pivot grid objects as measure or dimensions and their links with the data set properties.
Accessors are used to get the appropriate values from the data set. They can be :
Accessors can be defined for:
Formats are functions used to format the displayed values They can be:
Formats can be defined for
Aggregation are functions used the calculate the measures called for each cell with an array of values returned by its accessor for each data rows to be computed (at the intersection of the dimension values in rows and columns). They can be:
N.B. Aggregations (as weighted average) may require several data. In this case its accessor must return each needed data.
Sorts are objects thay may contains
Dimensions are the dimensions of the multidimentional matrix managed by the component. Dimensions have:
dimensions: [
{
id: "toto",
caption: "Toto",
keyAccessor: "totoId",
labelAccessor: "totoLabel",
sort: {
keyAccessor: "totoId"
},
format:x=>x.toUpperCase()
},
{
id: "titi",
caption: "Titi",
keyAccessor: "titi",
},
...]
Measures are the calculations, using aggregation function, of the projections of the matrix on the required dimensions. Measures have:
measures: [
{
valueAccessor: "qty",
id: "qty",
caption: "Quantity",
format: value =>(
<div style={{ color: "blue", textAlign: "right" }}>
{Number(value).toFixed(0)}
</div>
),
aggregation: "sum"
},
{
valueAccessor: "amt",
id: "amt",
caption: "Amount",
aggregation: "sum",
format: "amount"
},...]
Displayed dimensions and measures are assigned (ordered) either in row or in column. All measures must be on the same axis.
{
axis:{
columns: ["titi"],
rows: ["toto"],
measures: ["qty", "amt"],
measureHeaders: "columns"}
}
Features provided by the component are available by default on the grid. They can be disabled by changing the values from "enabled" to anything else.
features = {
dimensions: "enabled",
measures: "enabled",
resize: "enabled",
expandCollapse: "enabled",
totals: "enabled",
filters: "enabled",
sorting: "enabled",
configuration: "enabled"
}
Collapses, sizes and filters can be defined in the configuration property
The configurationFunctions property can bu used to define named custom formats, accessors, sorts and aggregations
{
formats: {amount:...},
accessors: {...},
sorts: {...},
aggregations: {...}
}
Custom functions that can be dynamically added to contectual menus on the data cells area:
Cell functions are called with a cell description object as parameter:
Range functions are called with a range description object as parameter:
Range functions are called with a range description object as parameter:
Grid functions are called with a configuration object as parameter:
{
dataCellFunctions: {
drilldown: cell => {...},
otherDrilldown: cell => {...}
},
rangeFunctions: { range: range => {...} },
gridFunctions: {...}
}
FAQs
Pivot grid written in React
The npm package zebulon-grid receives a total of 18 weekly downloads. As such, zebulon-grid popularity was classified as not popular.
We found that zebulon-grid demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
GemStuffer abuses RubyGems as an exfiltration channel, packaging scraped UK council portal data into junk gems published from new accounts.

Company News
Socket was named to the Rising in Cyber 2026 list, recognizing 30 private cybersecurity startups selected by CISOs and security executives.

Research
Socket detected 84 compromised TanStack npm package artifacts modified with suspected CI credential-stealing malware.