Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Expert skill for G2 legend development - provides comprehensive knowledge about legend rendering implementation, component architecture, layout algorithms, and interaction handling. Use when implementing, customizing, or debugging legend functionality in G2 visualizations.
.claude/skills/foryourhealth111-pixel-g2-legend-expert/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 15% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 6% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 3% | 0% |
| case-09 | ✗→✓ | ▲ Improved | -35% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 4% | 0% |
This skill provides comprehensive knowledge about legend rendering in G2, covering the complete legend rendering flow from component creation to layout calculation and interaction handling.
The legend rendering flow in G2 follows a multi-stage process that transforms legend configuration into visual components. This flow involves several key stages:
Legend components are inferred from the chart's scales and configuration during the initial setup phase. The inference process is handled by the inferComponent function in src/runtime/component.ts:
shape, size, color, and opacitylegendCategory (for discrete scales) or legendContinuous (for continuous scales)Two main legend component types are implemented:
Located in src/component/legendCategory.ts, this component handles categorical legends:
LegendCategoryLayout to handle layout positioningrender optionLocated in src/component/legendContinuous.ts, this handles continuous legends:
The layout process is managed in src/runtime/layout.ts and involves several critical steps:
The computeComponentSize function handles sizing based on component type:
The core layout logic is in the computePadding function:
typescriptconst autoSizeOf = (d) => { if (d.size) return; if (value !== 'auto') sizeOf(d); else { // Compute component size dynamically computeComponentSize( d, crossSize, crossPadding, position, theme, library, ); defaultSizeOf(d); } };
computeComponentSize to measure actual content dimensionsdefaultSize directly, bypassing content measurementThe renderComponent function in src/runtime/component.ts handles the actual rendering:
After size calculation, the placeComponents function assigns bounding boxes:
Categorical legends (LegendCategory) are used for discrete scales and support:
render optionContinuous legends (LegendContinuous) handle continuous scales:
The legend filtering interaction is implemented in src/interaction/legendFilter.ts:
Legends support multiple visual states:
Legend components integrate with G2's theming system:
When paddingTop is manually set (e.g., paddingTop: 72), the height of legendCategory changes unexpectedly (e.g., from 60px to 40px). This occurs because:
defaultSize instead of measuring actual contentLegendCategory, the default size is 40 (defined in src/component/legendCategory.ts)size property in the legend configuration to override the defaultFor more detailed information on legend layout mechanisms and related topics, see the knowledge directory:
./knowledge/legendLayout.md - Detailed analysis of padding behavior and layout calculationscomputePadding function| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-18 | pass→pass | 9,771 | 6,324 | -35% | 1 | 1 | 0% | 2,013 | 2,867 | +42% | 0 | 0 | — |
case-01 | fail→pass | 16,991 | 8,772 | -48% | 1 | 1 | 0% | 2,998 | 3,433 | +15% | 0 | 0 | — |
case-02 | fail→pass | 24,415 | 15,468 | -37% | 1 | 1 | 0% | 4,351 | 4,633 | +6% | 0 | 0 | — |
case-03 | pass→pass | 7,503 | 2,401 | -68% | 1 | 1 | 0% | 1,256 | 2,016 | +61% | 0 | 0 | — |
case-04 | pass→pass | 5,073 | 2,090 | -59% | 1 | 1 | 0% | 899 | 1,918 | +113% | 0 | 0 | — |
case-05 | pass→pass | 6,191 | 1,297 | -79% | 1 | 1 | 0% | 1,161 | 1,778 | +53% | 0 | 0 | — |
case-06 | fail→pass | 11,121 | 1,861 | -83% | 1 | 1 | 0% | 1,841 | 1,897 | +3% | 0 | 0 | — |
case-07 | pass→pass | 6,204 | 1,976 | -68% | 1 | 1 | 0% | 1,194 | 1,898 | +59% | 0 | 0 | — |
case-08 | pass→pass | 12,135 | 9,490 | -22% | 1 | 1 | 0% | 2,159 | 3,148 | +46% | 0 | 0 | — |
case-09 | fail→pass | 19,505 | 3,250 | -83% | 1 | 1 | 0% | 3,347 | 2,187 | -35% | 0 | 0 | — |
case-10 | fail→pass | 10,939 | 2,752 | -75% | 1 | 1 | 0% | 1,989 | 2,062 | +4% | 0 | 0 | — |
case-11 | fail→pass | 11,231 | 2,031 | -82% | 1 | 1 | 0% | 1,935 | 1,934 | -0% | 0 | 0 | — |
case-12 | pass→pass | 8,182 | 1,849 | -77% | 1 | 1 | 0% | 1,661 | 1,910 | +15% | 0 | 0 | — |
case-13 | pass→pass | 12,321 | 3,012 | -76% | 1 | 1 | 0% | 2,159 | 2,039 | -6% | 0 | 0 | — |
case-14 | fail→pass | 9,213 | 4,591 | -50% | 1 | 1 | 0% | 1,859 | 2,420 | +30% | 0 | 0 | — |
case-15 | pass→pass | 10,634 | 2,439 | -77% | 1 | 1 | 0% | 1,796 | 1,877 | +5% | 0 | 0 | — |
case-16 | fail→pass | 14,366 | 1,586 | -89% | 1 | 1 | 0% | 2,570 | 1,836 | -29% | 0 | 0 | — |
case-17 | pass→pass | 14,380 | 13,547 | -6% | 1 | 1 | 0% | 2,480 | 3,889 | +57% | 0 | 0 | — |
case-19 | fail→pass | 14,401 | 2,589 | -82% | 1 | 1 | 0% | 2,458 | 2,052 | -17% | 0 | 0 | — |
case-20 | fail→fail | 14,013 | 11,209 | -20% | 1 | 1 | 0% | 2,548 | 3,554 | +39% | 0 | 0 | — |
case-21 | pass→pass | 16,672 | 13,760 | -17% | 1 | 1 | 0% | 2,677 | 3,770 | +41% | 0 | 0 | — |
case-22 | pass→pass | 11,850 | 8,611 | -27% | 1 | 1 | 0% | 2,258 | 3,235 | +43% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +41 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.