Claude-skill-registry Implement Custom D3 Question

Create D3 questions with unique, non-standard interactions. Fallback skill for questions not fitting standard patterns.

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/implement-custom-d3-question" ~/.claude/skills/majiayu000-claude-skill-registry-implement-custom-d3-question && rm -rf "$T"
manifest: skills/data/implement-custom-d3-question/SKILL.md
source content

Implement Custom D3 Question

Use this skill when creating questions that don't fit standard patterns. For unique visualizations or complex custom interactions.

When to Use This Pattern

Use when:

  • Question requires truly unique interactions
  • None of the standard patterns fit
  • Complex custom visualization needed
  • Multiple interaction types combined in novel ways

Try standard patterns first:

Components Available

All components in

.claude/skills/question-types/snippets/
can be mixed and matched:

  • cards/
    - Standard cards, video players, explanation cards
  • form-inputs.js
    - Buttons, inputs, textareas
  • tables.js
    - D3 tables
  • drag-match.js
    - Drag-and-drop system
  • svg-basics.js
    - SVG shapes and diagrams

Core Architecture Requirements

All D3 questions MUST implement these patterns:

1. State Management

function createDefaultState() {
  return {
    // All student response data
  };
}

let chartState = createDefaultState();

2. Message Protocol

function sendChartState() {
  sendMessage("response_updated", {
    // Send complete state
  });
}

// Call after EVERY state change

3. Interactivity Locking

let interactivityLocked = false;

function setInteractivity(enabled) {
  interactivityLocked = !enabled;
  // Update all interactive elements
}

4. State Restoration

function applyInitialState(payload) {
  if (!payload) return;
  // Restore state from payload
  chartState = { ...createDefaultState(), ...payload };
}

5. Message Handlers

window.addEventListener("message", (event) => {
  const { data } = event;
  if (!data || typeof data !== "object") return;

  if (data.type === "setInitialState") {
    applyInitialState(data.payload);
    renderFromState(d3);
  }

  if (data.type === "set_lock") {
    setInteractivity(data.payload === false);
  }

  if (data.type === "check_answer") {
    sendChartState();
  }
});

Implementation Guide

See PATTERN.md for detailed custom implementation guide.

Reference Example

Study existing questions for patterns:

# Find all D3 questions
find courses/ -name "chart.js" -type f

# Look for unique patterns
grep -r "createChart" courses/ | head -5

Checklist

  • Defined
    createDefaultState()
  • Implemented
    sendChartState()
    with complete payload
  • Called
    sendChartState()
    after every state change
  • Implemented
    setInteractivity(enabled)
  • Implemented
    applyInitialState(payload)
  • Set up message event listeners
  • Implemented
    window.clearChart()
  • Implemented
    window.getSvg()
    (if using SVG)
  • Tested state restoration
  • Tested interactivity locking
  • Verified message protocol

Tips

  1. Start simple - Build incrementally
  2. Borrow liberally - Copy patterns from existing questions
  3. Test frequently - Use chart.html for local testing
  4. Document state - Comment what each state field represents
  5. Inline components - All components must be inlined in chart.js

Related Skills

  • create-d3-question - Parent workflow skill
  • All other question-type skills for standard patterns

Additional Resources