The Problem

Data analysts need a fast, interactive way to see patterns in tabular data without writing custom visual‑code. Existing BI tools are heavyweight, and ad‑hoc scripts often lack the animated transitions that keep context when users slice and dice rows.

What This Does

SandDance ships a set of reusable JavaScript components that map each row to a visual mark and animate between unit visualizations (scatter, bar, treemap, etc.). The core canvas lives in packages/sanddance/ while the specification of Vega specs is in packages/sanddance-specs/. A ready‑made UI is provided by packages/sanddance-explorer/, which bundles controls, data loading, and the animation engine.

Key files:

  • packages/sanddance-explorer/src/base.ts – the hub module imported by 43 other modules (high fan‑in).
  • packages/sanddance-explorer/src/explorer.tsx – the 1,493‑line entry component that renders the UI and drives the animation loop.
  • packages/sanddance-specs/src/interfaces.ts – defines the TypeScript contracts used across the stack.

The repository also contains pre‑built bundles for Power BI, VS Code, Azure Data Studio and a plain iframe embed (packages/sanddance-embed/).

How It Is Wired

Execution starts with the static HTML page docs/app/index.html. The page loads docs/assets/js/main.js, which imports the bundled explorer script docs/dist/sanddance-explorer/v4/sanddance-explorer.js. That bundle re‑exports the React component defined in packages/sanddance-explorer/src/explorer.tsx.

When the component mounts, it calls initializeExplorer() (found in src/base.ts). This function pulls in the spec builder from packages/sanddance-specs/src/specBuilder.ts and the Vega‑morphcharts interfaces from packages/vega-morphcharts/src/interfaces.ts. The spec builder reads the user‑supplied data (CSV/TSV) and produces a Vega spec that sanddance renders on a canvas element.

The most‑connected module, src/base.ts, is imported by 43 modules and only imports 12 others, giving it an instability of 0.22. Its central role means any change ripples widely. Conversely, src/explorer.tsx has a high instability (0.71) because it imports many others (32) but is only imported by 13 modules, making it a prime target for refactoring.

Circular imports involve 24 files, e.g. packages/sanddance-explorer/src/base.ts ↔ packages/sanddance-specs/src/types.ts ↔ packages/sanddance-specs/src/layouts/layout.ts. These cycles increase build‑time complexity and can cause runtime “undefined” bugs if the order of evaluation changes.

The oversized explorer.tsx file hosts UI layout, event handling, and data‑pipeline orchestration in a single 1,493‑line block, making local reasoning difficult. Deeply nested functions (max depth 16) appear in src/explorer.tsx, src/controls/iconButton.tsx, and src/specBuilder.ts, further raising cognitive load.

How To Use It

# 1. Clone the repo
git clone https://github.com/moses-y/SandDance.git
cd SandDance

# 2. Install npm packages (lockfile present)
npm ci

# 3. Build the explorer bundle (uses webpack config in extensions/azdata-sanddance)
npm run build   # defined in package.json scripts

# 4. Run the Jekyll‑based docs site (Dockerfile + compose present)
docker-compose -f docker-jekyll-local/docker-compose.yml up -d

# 5. Open the UI
open http://localhost:4000/docs/app/index.html

No environment variables are required for the core UI; data files are loaded from the docs/sample-data/ folder (e.g., titanicmaster.tsv). For embedding, import the pre‑built script docs/dist/sanddance-embed/v4/sanddance-embed.js and instantiate SandDanceEmbed as documented in packages/sanddance-embed/README.md.

Real‑World Use

A data‑science pipeline can drop a CSV into docs/sample-data/, start the Docker container, and let analysts explore the file through the browser UI. The same bundle can be imported into a React app:

import { SandDanceExplorer } from '@msrvida/sanddance-explorer';
<SandDanceExplorer dataUrl="/data/myfile.csv" />

The component handles parsing, spec generation, and animated transitions with zero additional code.

Code Health & Issues

  • MEDIUM – No Dependabot/Renovate configured (24 manifest files).
  • MEDIUM – Docker base image jekyll/jekyll:4.2.2 is not pinned by digest.
  • MEDIUM – No dependency‑vulnerability scan in CI (.github/workflows).
  • MEDIUM – Large binary docs/tests/v3/es6/js/sanddance-app.js (6.4 MiB) should be moved to Git LFS.
  • MEDIUM – Container runs as root; add a non‑root USER.
  • MEDIUM – postinstall script in package.json executes external code; consider disabling scripts in CI.
  • MEDIUM – Test coverage low: 13 test files vs. 358 source files (≈3 %).
  • LOW – Workflow jobs lack timeout-minutes.
  • LOW – Missing convention files (.editorconfig, formatter config).

Additional hygiene: tests, Azure Pipelines CI, LICENSE, and lockfiles are present; no secrets were detected.

The Bottom Line

SandDance provides a mature, modular visualization stack with ready‑made UI and embed options, but the codebase suffers from import cycles, an oversized core component, and limited test coverage. It is suitable for teams that need a plug‑and‑play visual explorer and are comfortable refactoring the explorer component to improve maintainability.