High-performance YASGUI plugin for rendering SPARQL SELECT results in an interactive table with advanced features.
- π Virtual Scrolling - Efficiently handles 10,000+ rows
- π Search & Filter - Real-time search with highlighting
- π Interactive Columns - Sort and resize columns
- π¨ Dynamic Theme Support - Automatically adapts to YASGUI light/dark theme changes
- π Selection & Copy - Select cells/rows and copy to clipboard
- πΎ Copy - Copy to clipboard as Markdown, CSV, or TSV (tab-delimited) formats
- π₯ YASR Integration - Integrated with YASR's download interface for CSV export
- π¬ Tooltips - Hover over any cell to view full content
- π Notifications - Visual feedback for copy operations
- βΏ Accessible - WCAG AA compliant with keyboard navigation
- π― SPARQL-Aware - Proper rendering of URIs, literals, datatypes, and blank nodes with prefix support from YASR
- π§ Smart Formatters - Auto-format cells by XSD datatype (e.g.
xsd:booleanβ β/β) and variable name suffix conventions (e.g.*stars,*percent,*image,*color,*description) - Decimal Places - Configure a fixed number of fraction digits for
xsd:float,xsd:double, andxsd:decimalliterals via the Display dropdown ordisplayConfig.decimalPlaces(leave unset for raw values) - π§ DESCRIBE Resource - Ctrl+click (or Cmd+click) any URI, or right-click it and choose Describe resource, to run a background
DESCRIBE <uri>query and view the resulting triples in a modal; optionally open the DESCRIBE as a new main query - π URI Link Prefix - Toolbar control to set a custom URL prefix for all URI links (e.g. point to a faceted browser); overrides
uriHrefAdapterwhen set by the user - β Quick Reference - Toolbar help icon opens an in-place quick reference card listing all features and keyboard shortcuts
npm install @matdata/yasgui-table-plugin<script src="https://unpkg.com/@matdata/yasgui-table-plugin/dist/yasgui-table-plugin.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/@matdata/yasgui-table-plugin/dist/yasgui-table-plugin.css">import Yasgui from '@yasgui/yasgui';
import TablePlugin from '@matdata/yasgui-table-plugin';
import '@yasgui/yasgui/build/yasgui.min.css';
import '@matdata/yasgui-table-plugin/dist/yasgui-table-plugin.css';
// Register the plugin
Yasgui.Yasr.plugins.table = TablePlugin;
// Create YASGUI instance
const yasgui = new Yasgui(document.getElementById('yasgui'), {
requestConfig: { endpoint: 'https://dbpedia.org/sparql' },
yasqe: { value: 'SELECT * WHERE { ?s ?p ?o } LIMIT 100' }
});const yasgui = new Yasgui(document.getElementById('yasgui'), {
yasr: {
pluginsOptions: {
table: {
displayConfig: {
uriDisplayMode: 'abbreviated', // 'full' or 'abbreviated'
showDatatypes: true, // Show datatype annotations
ellipsisMode: true, // Truncate long cell content (default: on)
smartFormatters: true, // Apply suffix-based formatters (default: on)
decimalPlaces: 2 // Fixed fraction digits for xsd:float/double/decimal (omit for raw values)
},
persistenceEnabled: true, // Save user preferences
// Developer adapter: transform a URI into a custom href (overridden by user-set uriLinkPrefix)
uriHrefAdapter: (uri) => `https://browser.example.org/?uri=${encodeURIComponent(uri)}`,
// Developer adapter: transform an entire binding set before rendering
bindingSetAdapter: (bindingSet) => bindingSet,
}
}
}
});The plugin emits events that can be used to integrate with your application:
const tablePlugin = yasgui.getTab().yasr.plugins.table;
// Listen for search events
tablePlugin.on('search', (data) => {
console.log(`Filtered to ${data.filteredCount} of ${data.totalCount} rows`);
});
// Listen for column sort
tablePlugin.on('columnSort', (data) => {
console.log(`Sorted by ${data.column} ${data.dir}`);
});
// Listen for selection changes
tablePlugin.on('selectionChange', (data) => {
console.log('Selection:', data.range);
});
// Listen for copy events
tablePlugin.on('copy', (data) => {
console.log(`Copied as ${data.format}`);
});
// Listen for URI link prefix changes
tablePlugin.on('linkPrefixChange', (data) => {
console.log(`Link prefix set to: ${data.prefix}`);
});
// Listen for DESCRIBE query results
tablePlugin.on('describeQuery', (data) => {
console.log(`DESCRIBE ${data.uri}: ${data.success ? data.triples + ' triples' : 'failed'}`);
});
// Available events:
// - ready, search, columnSort, columnResize, cellDoubleClick
// - selectionChange, selectionCleared, clipboardCopy
// - copy, layoutChange, linkPrefixChange, describeQuery, error, destroy// Get current selection
const selection = tablePlugin.getSelection();
// Clear selection
tablePlugin.clearSelection();
// Get download info
const downloadInfo = tablePlugin.getDownloadInfo();
// Update configuration
tablePlugin.updateConfig({ displayConfig: { ellipsisMode: true } });
// Event listeners
tablePlugin.on('eventName', handler);
tablePlugin.off('eventName', handler);
tablePlugin.once('eventName', handler);- Chrome (latest 2 versions)
- Firefox (latest 2 versions)
- Safari (latest 2 versions)
- Edge (latest 2 versions)
For detailed documentation, see the specification and quickstart guide.
# Install dependencies
npm install
# Start development server with Vite (http://localhost:3000)
npm run dev
# Build for production with esbuild
npm run build
# Run tests
npm run test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverageThe npm run dev command starts a Vite development server at http://localhost:3000 with:
- Hot module replacement (HMR) for instant updates
- Source maps for debugging TypeScript
- Serves the demo page from
demo/index.html - Plugin source loaded directly from
src/(no build needed)
The demo automatically loads the plugin from source during development for live reload.
The project uses esbuild for production builds with:
- CJS, ESM, and minified UMD module formats
- PostCSS for CSS processing
- TypeScript type declarations
Build outputs are generated in dist/ with .cjs.js, .esm.js, and .min.js formats.
Apache-2.0
Contributions are welcome! Please read the specification documents in ./specs/001-advanced-table/ before submitting changes.