Create D3 questions with +/- button controls and emoji/visual displays. Common for ratio, mixture, and recipe problems where students adjust quantities.
Use this skill when creating questions where students:
Perfect for:
Not suitable for:
Copy these from .claude/skills/question-types/snippets/:
cards/standard-card.js → createStandardCard()cards/explanation-card.js → createExplanationCard() - For student explanationscards/video-accordion.js → createVideoAccordion() - For help videosform-inputs.js → Increment/decrement button patternStudy the working example:
cat courses/IM-8th-Grade/modules/Unit-3/assignments/117-Equivalent-Ratios/questions/01/attachments/chart.js
Customize the scenario data (emojis, names, colors, ranges)
Adjust the visualization (emoji grid or SVG)
Test locally with chart.html
Reference this codebase file:
courses/IM-8th-Grade/modules/Unit-3/assignments/117-Equivalent-Ratios/questions/01/attachments/chart.js
This example includes:
const SCENARIO = {
item1: { emoji: "🧂", name: "Salt", color: "#FFD700" },
item2: { emoji: "🥛", name: "Water", color: "#87CEEB" },
minValue: 0,
maxValue: 20,
initialValue1: 2,
initialValue2: 5
};
function createDefaultState() {
return {
item1Count: SCENARIO.initialValue1,
item2Count: SCENARIO.initialValue2,
explanation: ""
};
}
Display two mixtures side-by-side:
const layout = container.append("div")
.style("display", "grid")
.style("grid-template-columns", "1fr 1fr")
.style("gap", "20px");
Show the relationship as a fraction:
fractionDiv.append("div").text(numerator);
fractionDiv.append("hr").style("width", "50px");
fractionDiv.append("div").text(denominator);
Disable buttons at limits:
.property("disabled", interactivityLocked || count <= MIN)
.style("opacity", count <= MIN ? 0.3 : 1);
setInitialState