返回 Skill 列表
extension
分类: 开发与工程无需 API Key

Implement Drag Match Question

创建带有拖放匹配互动的D3问题。学生将项目(表格、图表、方程式)拖动到相应的类别中。

person作者: jakexiaohubgithub

Implement Drag Match Question

Use this skill when creating questions where students:

  • Drag items to match them with categories or labels
  • Categorize or sort visual elements
  • Match representations (tables, graphs, equations)

When to Use This Pattern

Perfect for:

  • "Match each table to the equation it represents"
  • "Drag graphs to the descriptions that match"
  • "Match scenarios to proportional relationships"
  • Any "match X with Y" interaction
  • Categorization tasks with 2+ categories

Not suitable for:

Components Required

Copy these from .claude/skills/question-types/snippets/:

Required

  • drag-match.js → Full createDragMatcher() system (sophisticated!)
  • cards/standard-card.jscreateStandardCard()

Optional

  • cards/explanation-card.jscreateExplanationCard() - For student explanations
  • cards/video-accordion.jscreateVideoAccordion() - For help videos
  • tables.js → If rendering tables inside draggable items

Quick Start

  1. Review the pattern guide: PATTERN.md
  2. Study the working example:
    cat courses/IM-8th-Grade/modules/Unit-3/assignments/510-Proportion-Equations/questions/06/attachments/chart.js
    

Key Implementation Decisions

  1. Define items - What can be dragged? (tables, graphs, equations, text)
  2. Define categories - Where can items be dropped? (2+ categories)
  3. Render function - How to display each item (table, graph, simple text)
  4. State structure - One array per category storing matched item IDs

Data Structure

const ITEMS = [
  { id: "item1", /* your item data */ },
  { id: "item2", /* your item data */ },
  { id: "item3", /* your item data */ },
];

const CATEGORIES = [
  { id: "cat1", text: "Category 1 description" },
  { id: "cat2", text: "Category 2 description" },
];

State Shape

function createDefaultState() {
  return {
    cat1Matches: [],  // Array of matched item IDs
    cat2Matches: [],
    explanation: ""
  };
}

Core Pattern

dragMatcher = createDragMatcher(d3, content, {
  items: ITEMS.map(item => ({
    id: item.id,
    content: (container) => renderItem(container, item),  // Custom render function
  })),
  categories: CATEGORIES.map(cat => ({
    id: cat.id,
    label: cat.text,
  })),
  state: {
    cat1: chartState.cat1Matches,
    cat2: chartState.cat2Matches,
  },
  onStateChange: (newState) => {
    chartState.cat1Matches = newState.cat1 || [];
    chartState.cat2Matches = newState.cat2 || [];
    sendChartState();
  },
  locked: interactivityLocked,
});

Working Examples

In codebase:

In this skill:

Common Variations

Simple Text Items

For text-only items (not tables/graphs):

items: ITEMS.map(item => ({
  id: item.id,
  content: item.text,  // String instead of render function
}))

3+ Categories

function createDefaultState() {
  return {
    cat1Matches: [],
    cat2Matches: [],
    cat3Matches: [],
    explanation: ""
  };
}

dragMatcher = createDragMatcher(d3, content, {
  // ...
  state: {
    cat1: chartState.cat1Matches,
    cat2: chartState.cat2Matches,
    cat3: chartState.cat3Matches,
  },
});

Custom Item Rendering (Tables, Graphs, Images)

function renderTableItem(container, tableData) {
  // Use D3 to render a table
  const table = container.append("table")
    .style("width", "100%")
    .style("border-collapse", "collapse");

  // Add headers, rows, etc.
  // See working example for full implementation
}

items: ITEMS.map(item => ({
  id: item.id,
  content: (container) => renderTableItem(container, item.data),
}))

Implementation Checklist

  • [ ] Defined ITEMS array with unique IDs
  • [ ] Defined CATEGORIES array
  • [ ] Created render function for items (if complex)
  • [ ] Created createDefaultState() with one array per category
  • [ ] Implemented createDragMatcher() with onStateChange callback
  • [ ] Added explanation card (if needed)
  • [ ] Implemented setInteractivity() to call dragMatcher.setLocked()
  • [ ] Implemented applyInitialState() to restore matches
  • [ ] Tested dragging items between categories
  • [ ] Tested removing items from categories
  • [ ] Tested locking/unlocking
  • [ ] Verified state restoration

Tips

  1. Keep item rendering simple - Complex DOM structures can slow down dragging
  2. Use clear category labels - Students should know where to drag items
  3. Provide context - Use intro cards to explain the matching task
  4. Test on mobile - Drag-and-drop works on touch devices but test carefully
  5. Add visual feedback - The component provides this, but ensure it's visible

The createDragMatcher API

The createDragMatcher component is a complete drag-and-drop system. Key features:

  • Automatic drag handling - No manual event listeners needed
  • Touch support - Works on mobile devices
  • Visual feedback - Highlights drop zones, shows drag state
  • Remove buttons - Students can unmatch items
  • Lock support - Disable dragging after submission via .setLocked(true)

Important methods:

  • dragMatcher.setLocked(boolean) - Enable/disable dragging
  • dragMatcher.getState() - Get current match state
  • dragMatcher.setState(newState) - Update matches programmatically

Related Skills

Additional Resources