Unified JSON datasets and TypeScript libraries for drawing tablets, pens, drivers, and their relationships.
| Entity | Records | Brands |
|---|---|---|
| Brands | 11 | All |
| Tablets | 290 | GAOMON, HUION, UGEE, WACOM, XENCELABS, XPPEN |
| Pens | 104 | HUION, SAMSUNG, WACOM, XENCELABS, XPPEN |
| Pen Families | 10 | WACOM |
| Tablet Families | 18 | WACOM |
| Pen Compatibility | 100 groups | HUION, SAMSUNG, WACOM, XENCELABS, XPPEN |
| Drivers | 246 | WACOM |
| Pressure Response | 124 sessions | HUION, SAMSUNG, WACOM, XENCELABS, XPPEN |
| Inventory | 263 items | Per-user (sevenpens) |
Pin a specific version of the data in your project:
git submodule add https://github.com/TheSevenPens/DrawTabData.git data-repogit clone https://github.com/TheSevenPens/DrawTabData.git data-repoDownload and copy the data/ and lib/ folders directly into your project.
No local files needed — load data at runtime:
// From GitHub Pages
const ds = await loadAllFromURL("https://thesevenpens.github.io/DrawTabData/data");
// From raw.githubusercontent
const ds = await loadAllFromURL("https://raw.githubusercontent.com/TheSevenPens/DrawTabData/master/data");import { loadAllFromDisk } from "./data-repo/lib/drawtab-all-node.js";
const ds = loadAllFromDisk("./data-repo/data");
console.log(`${ds.tablets.length} tablets`);
console.log(`${ds.pens.length} pens`);
console.log(`${ds.penCompat.length} compatibility pairs`);import { loadAllFromURL } from "./data-repo/lib/drawtab-all.js";
const ds = await loadAllFromURL("https://your-server.com/data");The ds object contains:
ds.tablets,ds.pens,ds.penCompat,ds.penFamilies,ds.tabletFamilies,ds.drivers— all entity arraysds.tabletToPens— Map: tablet ModelId to compatible Pen[]ds.penToTablets— Map: pen PenId to compatible Tablet[]ds.includedPenMap— Map: pen PenId to Tablet[] that include it
Every record has an EntityId that uniquely identifies it: BRAND.ENTITYTYPE.ID
WACOM.TABLET.PTK870WACOM.PEN.KP501EWACOM.DRIVER.6.3.45-2_WINDOWSWACOM.PENFAMILY.WacomKPGEN3WACOM.TABLETFAMILY.WacomIntuosProGen8
Fields on one entity reference IDs on another:
| Field | On entity | References |
|---|---|---|
ModelIncludedPen |
Tablet | Array of PenIds on Pen |
ModelFamily |
Tablet | FamilyId on TabletFamily |
PenFamily |
Pen | FamilyId on PenFamily |
TabletId |
PenCompat | ModelId on Tablet |
PenId |
PenCompat | PenId on Pen |
import { filterByBrand, filterByType } from "./data-repo/lib/drawtab-loader-node.js";
const wacomDisplays = filterByType(filterByBrand(ds.tablets, "WACOM"), "PENDISPLAY");const pens = ds.tabletToPens.get("PTK-870") ?? [];
for (const pen of pens) {
console.log(`${pen.PenName} (${pen.PenId})`);
}const tablets = ds.penToTablets.get("KP-501E") ?? [];
for (const tablet of tablets) {
console.log(`${tablet.ModelName} (${tablet.ModelId})`);
}import { containsText } from "./data-repo/lib/drawtab-loader-node.js";
const matches = ds.tablets.filter(t =>
containsText(t.ModelName, "16") && containsText(t.ModelName, "pro")
);import { getDiagonal, formatDimensions } from "./data-repo/lib/drawtab-loader-node.js";
import { formatValue } from "./data-repo/lib/units.js";
const largest = ds.tablets
.map(t => ({ tablet: t, diag: getDiagonal(t.DigitizerDimensions) }))
.filter(({ diag }) => diag !== null)
.sort((a, b) => b.diag! - a.diag!)
.slice(0, 10);
for (const { tablet, diag } of largest) {
const mm = diag!.toFixed(1);
const inches = formatValue(mm, "mm", "imperial");
console.log(`${tablet.ModelName} - ${formatDimensions(tablet.DigitizerDimensions)} mm (${mm} mm / ${inches} in diagonal)`);
}import { formatValue, getFieldLabel } from "./data-repo/lib/units.js";
formatValue("345.5", "mm", "imperial"); // "13.60"
formatValue("1145", "g", "imperial"); // "40.38"
getFieldLabel("Diagonal (mm)", "mm", "imperial"); // "Diagonal (in)"Supported: mm to in, g to oz, LPmm to LPI, px/mm to PPI.
| Function | Module | Description |
|---|---|---|
loadAllFromDisk(dataDir) |
drawtab-all-node |
Load everything from disk (sync) |
loadAllFromURL(baseUrl) |
drawtab-all |
Load everything from URL (async) |
filterByBrand(items, brand) |
drawtab-loader |
Case-insensitive brand filter (generic) |
filterByType(tablets, type) |
drawtab-loader |
Case-insensitive type filter |
containsText(value, search) |
drawtab-loader |
Case-insensitive substring match |
equalsText(value, search) |
drawtab-loader |
Case-insensitive equality |
getDiagonal(dimensions) |
drawtab-loader |
Compute diagonal from Width/Height |
formatDimensions(dimensions) |
drawtab-loader |
Format as "W x H" or "W x H x D" string |
formatValue(value, unit, pref) |
units |
Convert metric/imperial |
getFieldLabel(label, unit, pref) |
units |
Update label with active unit |
buildTabletToPenCompatMap(compat, pens) |
compat-helpers |
Map: tabletId to Pen[] |
buildPenToTabletCompatMap(compat, tablets) |
compat-helpers |
Map: penId to Tablet[] |
buildIncludedPenMap(tablets) |
compat-helpers |
Map: penId to Tablet[] (included) |
A live explorer UI is available at thesevenpens.github.io/DrawTabDataExplorer.
Source: github.com/TheSevenPens/DrawTabDataExplorer
data/
tablets/ HUION, WACOM, XENCELABS, XPPEN
pens/ WACOM
pen-families/ WACOM
tablet-families/ WACOM
pen-compat/ WACOM (pen -> tablet[] grouped format)
drivers/ WACOM
Files are partitioned by brand: BRAND-entitytype.json (e.g. WACOM-tablets.json).
- User Manual — detailed guide with all examples
- Architecture — project structure and library design
- Fields — tablet field definitions with formats and units
- Data Layout — JSON file organization
- Decisions — design decision log
- Futures — roadmap
ISC