Run3 skill 1
[COLM'26] SkillLearnBench is the first benchmark for evaluating continual learning methods that automatically generate agent skills.From the repository description
npx -y skills add cxcscmu/SkillLearnBench --skill run3_skill-1Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.
SKILL.md
12.6 KB, ~3.3k tokens by cl100k_base, as published. Nobody here has run it
[SKILL]
name: d3-stock-bubble-chart-and-table description: Use when creating a D3.js v6 single-page web app that visualizes stock data as a bubble chart (sized by market cap, colored by sector, force-clustered) alongside a data table, with interactive linking between them. Covers CSV parsing, force simulation, tooltips, and table highlighting.
D3.js Stock Bubble Chart + Data Table Visualization
Overview
Create a single-page web app with:
- A bubble chart (force-simulated, clustered by sector, sized by market cap)
- A data table (50 stocks, formatted market cap)
- Interactive linking (click bubble → highlight row, click row → highlight bubble)
- Tooltips for non-ETF stocks only
File Structure
/root/output/
├── index.html
├── js/
│ ├── d3.v6.min.js
│ └── visualization.js
├── css/
│ └── style.css
└── data/
├── stock-descriptions.csv
└── indiv-stock/
└── (copied .csv files)
Step 1: Copy Data and D3 Library
# Copy input data
cp -r /root/data/* /root/output/data/
# Download D3.js v6 min
curl -o /root/output/js/d3.v6.min.js https://d3js.org/d3.v6.min.js
# If no internet, use: cp /path/to/d3.v6.min.js /root/output/js/d3.v6.min.js
Step 2: index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Stock Visualization</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<h1>Stock Bubble Chart & Data Table</h1>
<div id="main-container">
<div id="chart-container">
<svg id="bubble-chart"></svg>
<div id="legend-container"></div>
</div>
<div id="table-container">
<table id="stock-table">
<thead>
<tr>
<th>Ticker symbol</th>
<th>Full company name</th>
<th>Sector</th>
<th>Market cap</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
<div id="tooltip" class="tooltip" style="opacity:0;"></div>
<script src="js/d3.v6.min.js"></script>
<script src="js/visualization.js"></script>
</body>
</html>
Step 3: css/style.css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
background-color: #f5f5f5;
padding: 20px;
}
h1 {
text-align: center;
margin-bottom: 20px;
color: #333;
}
#main-container {
display: flex;
flex-direction: row;
justify-content: center;
align-items: flex-start;
gap: 20px;
width: 100%;
}
#chart-container {
flex: 0 0 660px;
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
padding: 10px;
}
#bubble-chart {
display: block;
width: 640px;
height: 600px;
}
#legend-container {
display: flex;
flex-wrap: wrap;
gap: 8px;
padding: 10px;
justify-content: center;
}
.legend-item {
display: flex;
align-items: center;
gap: 4px;
font-size: 12px;
}
.legend-color {
width: 14px;
height: 14px;
border-radius: 50%;
}
#table-container {
flex: 1 1 auto;
max-height: 700px;
overflow-y: auto;
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
#stock-table {
width: 100%;
border-collapse: collapse;
font-size: 13px;
}
#stock-table thead th {
background-color: #4a90d9;
color: white;
padding: 10px 8px;
text-align: left;
position: sticky;
top: 0;
z-index: 1;
}
#stock-table tbody td {
padding: 8px;
border-bottom: 1px solid #eee;
}
#stock-table tbody tr:hover {
background-color: #f0f7ff;
}
#stock-table tbody tr.highlighted {
background-color: #ffeb3b !important;
font-weight: bold;
}
#stock-table tbody tr {
cursor: pointer;
}
.tooltip {
position: absolute;
padding: 10px 14px;
background: rgba(0, 0, 0, 0.85);
color: #fff;
border-radius: 6px;
font-size: 13px;
pointer-events: none;
line-height: 1.5;
z-index: 1000;
max-width: 300px;
}
.bubble-selected {
stroke: #ff0000;
stroke-width: 3px;
}
.bubble-label {
pointer-events: none;
text-anchor: middle;
dominant-baseline: central;
font-size: 10px;
font-weight: bold;
fill: #fff;
}
Step 4: js/visualization.js
CRITICAL: This must be the COMPLETE file — no truncation.
(function() {
const width = 640;
const height = 600;
const svg = d3.select("#bubble-chart")
.attr("width", width)
.attr("height", height);
const tooltip = d3.select("#tooltip");
d3.csv("data/stock-descriptions.csv").then(function(rawData) {
// Parse data
const data = rawData.map(function(d) {
const mcRaw = d.marketCap ? d.marketCap.trim() : "";
let marketCap = null;
if (mcRaw !== "") {
marketCap = parseFloat(mcRaw);
if (isNaN(marketCap)) marketCap = null;
}
// Determine if ETF: no marketCap value in the data
const isETF = (marketCap === null || marketCap === undefined);
return {
ticker: (d.ticker || d.Ticker || d.Symbol || "").trim(),
name: (d.name || d.Name || d.Company || "").trim(),
sector: (d.sector || d.Sector || "").trim(),
marketCap: marketCap,
country: (d.country || d.Country || "").trim(),
website: (d.website || d.Website || "").trim(),
isETF: isETF
};
});
// Get unique sectors (non-empty)
const sectors = Array.from(new Set(data.map(function(d) { return d.sector; }))).filter(function(s) { return s !== ""; }).sort();
// Color scale
const colorScale = d3.scaleOrdinal()
.domain(sectors)
.range(d3.schemeTableau10.concat(d3.schemePaired).slice(0, sectors.length));
// Radius scale based on market cap for non-ETFs
const nonETF = data.filter(function(d) { return !d.isETF && d.marketCap > 0; });
const mcExtent = d3.extent(nonETF, function(d) { return d.marketCap; });
const radiusScale = d3.scaleSqrt()
.domain([mcExtent[0] || 1, mcExtent[1] || 1])
.range([8, 50]);
const defaultETFRadius = 12;
data.forEach(function(d) {
if (d.isETF) {
d.radius = defaultETFRadius;
} else {
d.radius = radiusScale(d.marketCap);
}
});
// Sector center positions — arrange sectors in a grid-like pattern centered
const sectorCenters = {};
const cols = Math.ceil(Math.sqrt(sectors.length));
const rows = Math.ceil(sectors.length / cols);
const xSpacing = width / (cols + 1);
const ySpacing = height / (rows + 1);
sectors.forEach(function(s, i) {
const col = i % cols;
const row = Math.floor(i / cols);
sectorCenters[s] = {
x: xSpacing * (col + 1),
y: ySpacing * (row + 1)
};
});
// For items with empty sector (ETFs possibly), place them in center
sectorCenters[""] = { x: width / 2, y: height / 2 };
// Force simulation
const simulation = d3.forceSimulation(data)
.force("x", d3.forceX(function(d) {
return (sectorCenters[d.sector] || sectorCenters[""]).x;
}).strength(0.4))
.force("y", d3.forceY(function(d) {
return (sectorCenters[d.sector] || sectorCenters[""]).y;
}).strength(0.4))
.force("collide", d3.forceCollide(function(d) {
return d.radius + 2;
}).iterations(3))
.force("center", d3.forceCenter(width / 2, height / 2).strength(0.05))
.on("tick", ticked);
// Create bubble groups
const bubbleGroup = svg.selectAll(".bubble-group")
.data(data)
.enter()
.append("g")
.attr("class", "bubble-group");
const circles = bubbleGroup.append("circle")
.attr("r", function(d) { return d.radius; })
.attr("fill", function(d) { return d.sector ? colorScale(d.sector) : "#999"; })
.attr("stroke", "#fff")
.attr("stroke-width", 1)
.attr("opacity", 0.85)
.attr("data-ticker", function(d) { return d.ticker; })
.style("cursor", "pointer");
const labels = bubbleGroup.append("text")
.attr("class", "bubble-label")
.text(function(d) { return d.ticker; })
.style("font-size", function(d) {
return Math.max(7, Math.min(d.radius * 0.45, 14)) + "px";
});
// Tooltip handlers
circles.on("mouseover", function(event, d) {
// ETFs: do NOT show tooltip
if (d.isETF) {
tooltip.style("opacity", 0);
return;
}
tooltip.style("opacity", 1);
let html = "<strong>" + d.ticker + "</strong><br/>";
html += "Name: " + d.name + "<br/>";
html += "Sector: " + d.sector;
tooltip.html(html);
tooltip.style("left", (event.pageX + 15) + "px")
.style("top", (event.pageY - 10) + "px");
})
.on("mousemove", function(event, d) {
if (d.isETF) {
tooltip.style("opacity", 0);
return;
}
tooltip.style("left", (event.pageX + 15) + "px")
.style("top", (event.pageY - 10) + "px");
})
.on("mouseout", function(event, d) {
tooltip.style("opacity", 0);
tooltip.html("");
});
// Click handler for bubbles
circles.on("click", function(event, d) {
selectStock(d.ticker);
});
function ticked() {
bubbleGroup.attr("transform", function(d) {
// Constrain to SVG bounds
d.x = Math.max(d.radius, Math.min(width - d.radius, d.x));
d.y = Math.max(d.radius, Math.min(height - d.radius, d.y));
return "translate(" + d.x + "," + d.y + ")";
});
}
// Build legend
const legendContainer = d3.select("#legend-container");
sectors.forEach(function(sector) {
const item = legendContainer.append("div").attr("class", "legend-item");
item.append("div")
.attr("class", "legend-color")
.style("background-color", colorScale(sector));
item.append("span").text(sector);
});
// Build data table
function formatMarketCap(mc) {
if (mc === null || mc === undefined || isNaN(mc)) return "N/A";
if (mc >= 1e12) return (mc / 1e12).toFixed(2) + "T";
if (mc >= 1e9) return (mc / 1e9).toFixed(2) + "B";
if (mc >= 1e6) return (mc / 1e6).toFixed(2) + "M";
if (mc >= 1e3) return (mc / 1e3).toFixed(2) + "K";
return mc.toString();
}
const tbody = d3.select("#stock-table tbody");
const rows_el = tbody.selectAll("tr")
.data(data)
.enter()
.append("tr")
.attr("data-ticker", function(d) { return d.ticker; })
.on("click", function(event, d) {
selectStock(d.ticker);
});
rows_el.append("td").text(function(d) { return d.ticker; });
rows_el.append("td").text(function(d) { return d.name; });
rows_el.append("td").text(function(d) { return d.sector; });
rows_el.append("td").text(function(d) { return formatMarketCap(d.marketCap); });
// Selection / linking function
function selectStock(ticker) {
// Highlight bubble
circles.classed("bubble-selected", false)
.attr("stroke", "#fff")
.attr("stroke-width", 1);
circles.filter(function(d) { return d.ticker === ticker; })
.classed("bubble-selected", true)
.attr("stroke", "#ff0000")
.attr("stroke-width", 3);
// Highlight table row
rows_el.classed("highlighted", false);
const selectedRow = rows_el.filter(function(d) { return d.ticker === ticker; })
.classed("highlighted", true);
// Scroll table row into view
if (!selectedRow
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.