Back to skills
extension
Category: Development & EngineeringNo API key required

Implement Custom D3 Question

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

personAuthor: jakexiaohubgithub

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