Implement Static Graph Question
by asmith7013
Create D3 questions with static line graphs and coordinating table inputs. Students read graphs and fill in corresponding values.
Skill Details
Repository Files
2 files in this skill directory
name: Implement Static Graph Question description: Create D3 questions with static line graphs and coordinating table inputs. Students read graphs and fill in corresponding values.
Implement Static Graph Question
Use this skill when creating questions where students:
- Read a static line graph showing a relationship
- Fill in table values based on the graph
- Explain patterns or relationships shown in the graph
When to Use This Pattern
Perfect for:
- "Use the graph to complete the table"
- "Read the graph and fill in missing values"
- Proportional relationship questions with visual representation
- Rate/slope questions with coordinate visualization
Not suitable for:
- Interactive graph manipulation (use dynamic graph component when available)
- Simple tables without graphs → use implement-table-question
- Drag-and-drop matching → use implement-drag-match-question
Components Required
Copy these from .claude/skills/question-types/snippets/:
Required
static-graph.js→renderStaticGraph()- NEW! Static graph componentcards/standard-card.js→createStandardCard()
Optional
cards/explanation-card.js→createExplanationCard()- For student explanationscards/video-accordion.js→createVideoAccordion()- For help videostables.js→ For custom table rendering (or use HTML tables)
Quick Start
-
Study the working example:
cat courses/IM-8th-Grade/modules/Unit-3/assignments/Ramp-Up-01/questions/02/attachments/chart.js -
Copy the static-graph component from snippets/static-graph.js
-
Use the pattern below to render graph + table
Key Implementation Decisions
- Graph configuration - X/Y domains, labels, grid spacing
- Line data - What relationship does the graph show?
- Table structure - Which values are editable?
- State fields - One field per editable table cell
State Shape
function createDefaultState() {
return {
// One field per editable table cell
cell1: "",
cell2: "",
cell3: "",
cell4: "",
explanation: ""
};
}
Core Pattern
1. Define Graph Configuration
// Graph data
const RATE = 20; // $20 per day
const MAX_DAYS = 10;
const MAX_MONEY = 200;
const graphConfig = {
width: 600,
height: 400,
padding: { top: 40, right: 40, bottom: 60, left: 70 },
xDomain: [0, MAX_DAYS],
yDomain: [0, MAX_MONEY],
xLabel: "Days",
yLabel: "Money Earned ($)",
xVariable: "d", // Variable label (optional)
yVariable: "m", // Variable label (optional)
lineData: [
{ x: 0, y: 0 },
{ x: MAX_DAYS, y: MAX_DAYS * RATE }
],
xGridStep: 1,
yGridStep: 20,
showArrow: true
};
2. Render Graph
function buildLayout(d3, containerSelector) {
const container = d3.select(containerSelector);
container.html("").style("padding", "20px").style("overflow", "auto");
// Intro card
const introCard = createStandardCard(d3, container, {
size: "large",
title: "Read the Graph"
});
introCard.append("p").text("Use the graph to complete the table below.");
// Graph card
const graphCard = createStandardCard(d3, container, {
size: "graph",
title: "Sarah's Earnings"
});
const svg = graphCard.append("svg");
renderStaticGraph(d3, svg, graphConfig);
// Table and explanation below...
renderTable(d3, container);
renderExplanation(d3, container);
}
3. Render Table with Inputs
function renderTable(d3, container) {
const tableCard = createStandardCard(d3, container, {
size: "medium",
title: "Complete the Table"
});
// HTML table approach (simpler)
const tableHtml = `
<table style="width: 100%; border-collapse: collapse;">
<thead>
<tr>
<th style="border: 1px solid #e5e7eb; padding: 12px;">Days</th>
<th style="border: 1px solid #e5e7eb; padding: 12px;">Money ($)</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #e5e7eb; padding: 12px;">1</td>
<td style="border: 1px solid #e5e7eb; padding: 12px;">
<input type="text" id="day1" inputmode="numeric"
style="width: 100%; padding: 8px; border: 1px solid #cbd5e1; border-radius: 4px;">
</td>
</tr>
<tr>
<td style="border: 1px solid #e5e7eb; padding: 12px;">3</td>
<td style="border: 1px solid #e5e7eb; padding: 12px;">
<input type="text" id="day3" inputmode="numeric"
style="width: 100%; padding: 8px; border: 1px solid #cbd5e1; border-radius: 4px;">
</td>
</tr>
</tbody>
</table>
`;
tableCard.html(tableCard.html() + tableHtml);
// Bind input events
input1 = tableCard.select("#day1")
.property("value", chartState.day1)
.on("input", function() {
chartState.day1 = this.value;
sendChartState();
});
input3 = tableCard.select("#day3")
.property("value", chartState.day3)
.on("input", function() {
chartState.day3 = this.value;
sendChartState();
});
}
4. Message Protocol
function sendChartState() {
sendMessage("response_updated", {
tableValues: {
day1: chartState.day1,
day3: chartState.day3,
// ... other table values
},
explanation: {
text: chartState.explanation
}
});
}
Working Examples
In codebase:
- IM-8th-Grade Ramp-Up-01 Q02 - Complete example with graph + table
Key features shown:
- Static line graph with grid
- Arrowhead at end of line
- Variable labels (d, m)
- Table with 4 editable cells
- Explanation card
- Video accordion for help
Common Variations
Two-Column Layout (Graph + Table Side-by-Side)
const layout = container.append("div")
.style("display", "grid")
.style("grid-template-columns", "1fr 1fr")
.style("gap", "20px");
const leftColumn = layout.append("div");
const rightColumn = layout.append("div");
// Graph in left column
const svg = leftColumn.append("svg");
renderStaticGraph(d3, svg, graphConfig);
// Table in right column
renderTable(d3, rightColumn);
Different Graph Types
Horizontal line (constant value):
lineData: [
{ x: 0, y: 50 },
{ x: 10, y: 50 }
]
Non-linear relationship:
lineData: Array.from({length: 11}, (_, i) => ({
x: i,
y: i * i // Quadratic
}))
D3 Table Instead of HTML
See snippets/tables.js for D3 table patterns with custom styling.
Static Graph Component API
The renderStaticGraph() function accepts these options:
renderStaticGraph(d3, svg, {
// Size
width: 600, // SVG width
height: 400, // SVG height
padding: { top: 40, right: 40, bottom: 60, left: 70 },
// Domains
xDomain: [0, 10], // X-axis min/max
yDomain: [0, 200], // Y-axis min/max
// Labels
xLabel: "Days", // X-axis label
yLabel: "Money ($)", // Y-axis label
xVariable: "d", // X variable (optional, italic)
yVariable: "m", // Y variable (optional, italic)
// Line data
lineData: [ // Array of {x, y} points
{ x: 0, y: 0 },
{ x: 10, y: 200 }
],
// Grid
xGridStep: 1, // Vertical grid line spacing
yGridStep: 20, // Horizontal grid line spacing
// Axes
xTicks: 10, // Number of X-axis ticks (optional)
yTicks: 10, // Number of Y-axis ticks
// Line styling
showArrow: true, // Show arrowhead at end
lineColor: "#3b82f6", // Line color
lineWidth: 2.5 // Line stroke width
});
Implementation Checklist
- Copied
renderStaticGraph()from snippets/static-graph.js - Defined graph configuration (domains, labels, line data)
- Created SVG and called
renderStaticGraph() - Created table with editable cells (HTML or D3)
- Created
createDefaultState()with one field per editable cell - Bound input events to update state
- Implemented
sendChartState()with tableValues - Added explanation card (if needed)
- Implemented
setInteractivity()to disable inputs when locked - Implemented
applyInitialState()to restore table values - Tested state restoration
- Tested locking/unlocking
- Verified graph renders correctly at different screen sizes
Tips
- Match table to graph - Table values should correspond to visible points on the graph
- Use grid lines - Help students read values accurately
- Label clearly - Both axis labels and variable labels aid comprehension
- Provide context - Intro card should explain the scenario
- Consider layout - Side-by-side works well on desktop, stacked better on mobile
- Test readability - Ensure graph is readable at different sizes (viewBox helps!)
Graph Design Best Practices
- Choose appropriate domains - Don't make graph too cramped or too sparse
- Use consistent grid spacing - Makes values easier to read
- Add arrowheads - Shows the line continues beyond the visible domain
- Include units - Label axes with units (e.g., "Days", "Money ($)")
- Variable labels optional - Use when teaching function notation (e.g., m = f(d))
Related Skills
- implement-table-question - For tables without graphs
- implement-slider-question - For interactive parameter exploration
- create-d3-question - Parent workflow skill
Additional Resources
- snippets/static-graph.js - Static graph component
- snippets/tables.js - D3 table patterns
- snippets/cards/ - Card components
Related Skills
Attack Tree Construction
Build comprehensive attack trees to visualize threat paths. Use when mapping attack scenarios, identifying defense gaps, or communicating security risks to stakeholders.
Grafana Dashboards
Create and manage production Grafana dashboards for real-time visualization of system and application metrics. Use when building monitoring dashboards, visualizing metrics, or creating operational observability interfaces.
Matplotlib
Foundational plotting library. Create line plots, scatter, bar, histograms, heatmaps, 3D, subplots, export PNG/PDF/SVG, for scientific visualization and publication figures.
Scientific Visualization
Create publication figures with matplotlib/seaborn/plotly. Multi-panel layouts, error bars, significance markers, colorblind-safe, export PDF/EPS/TIFF, for journal-ready scientific plots.
Seaborn
Statistical visualization. Scatter, box, violin, heatmaps, pair plots, regression, correlation matrices, KDE, faceted plots, for exploratory analysis and publication figures.
Shap
Model interpretability and explainability using SHAP (SHapley Additive exPlanations). Use this skill when explaining machine learning model predictions, computing feature importance, generating SHAP plots (waterfall, beeswarm, bar, scatter, force, heatmap), debugging models, analyzing model bias or fairness, comparing models, or implementing explainable AI. Works with tree-based models (XGBoost, LightGBM, Random Forest), deep learning (TensorFlow, PyTorch), linear models, and any black-box model
Pydeseq2
Differential gene expression analysis (Python DESeq2). Identify DE genes from bulk RNA-seq counts, Wald tests, FDR correction, volcano/MA plots, for RNA-seq analysis.
Query Writing
For writing and executing SQL queries - from simple single-table queries to complex multi-table JOINs and aggregations
Pydeseq2
Differential gene expression analysis (Python DESeq2). Identify DE genes from bulk RNA-seq counts, Wald tests, FDR correction, volcano/MA plots, for RNA-seq analysis.
Scientific Visualization
Meta-skill for publication-ready figures. Use when creating journal submission figures requiring multi-panel layouts, significance annotations, error bars, colorblind-safe palettes, and specific journal formatting (Nature, Science, Cell). Orchestrates matplotlib/seaborn/plotly with publication styles. For quick exploration use seaborn or plotly directly.
