|
| 1 | +--- |
| 2 | +name: G2 Legend Expert |
| 3 | +description: 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. |
| 4 | +--- |
| 5 | + |
| 6 | +# G2 Legend Expert Skill |
| 7 | + |
| 8 | +## Overview |
| 9 | + |
| 10 | +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. |
| 11 | + |
| 12 | +## Legend Rendering Flow in G2 |
| 13 | + |
| 14 | +The legend rendering flow in G2 follows a multi-stage process that transforms legend configuration into visual components. This flow involves several key stages: |
| 15 | + |
| 16 | +### 1. Legend Component Inference |
| 17 | + |
| 18 | +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`: |
| 19 | + |
| 20 | +- **Scale Analysis**: The system analyzes all scales in the chart, looking for channels like `shape`, `size`, `color`, and `opacity` |
| 21 | +- **Legend Type Detection**: Based on the scale types, the system determines whether to create `legendCategory` (for discrete scales) or `legendContinuous` (for continuous scales) |
| 22 | +- **Position Inference**: Default positions and orientations are inferred based on the chart type and coordinate system |
| 23 | + |
| 24 | +### 2. Legend Component Creation |
| 25 | + |
| 26 | +Two main legend component types are implemented: |
| 27 | + |
| 28 | +#### LegendCategory |
| 29 | + |
| 30 | +Located in `src/component/legendCategory.ts`, this component handles categorical legends: |
| 31 | + |
| 32 | +- **Data Processing**: Processes domain values from scales to create legend items |
| 33 | +- **Marker Inference**: Automatically infers appropriate markers based on the chart's shapes and scales |
| 34 | +- **Layout Wrapper**: Uses `LegendCategoryLayout` to handle layout positioning |
| 35 | +- **Rendering Options**: Supports both standard GUI rendering and custom HTML rendering via the `render` option |
| 36 | + |
| 37 | +#### LegendContinuous |
| 38 | + |
| 39 | +Located in `src/component/legendContinuous.ts`, this handles continuous legends: |
| 40 | + |
| 41 | +- **Scale Type Handling**: Supports various continuous scale types including linear, log, time, quantize, quantile, and threshold |
| 42 | +- **Configuration Inference**: Generates appropriate configuration based on scale properties |
| 43 | +- **Ribbon Generation**: Creates color ribbons for continuous scales |
| 44 | +- **Label Formatting**: Handles proper formatting of continuous scale labels |
| 45 | + |
| 46 | +### 3. Layout and Sizing Calculation |
| 47 | + |
| 48 | +The layout process is managed in `src/runtime/layout.ts` and involves several critical steps: |
| 49 | + |
| 50 | +#### Component Size Computation |
| 51 | + |
| 52 | +The `computeComponentSize` function handles sizing based on component type: |
| 53 | + |
| 54 | +- **Auto vs Manual Padding**: When padding is set to 'auto', the system dynamically calculates component size based on content. When manually set, it uses default sizes. |
| 55 | +- **Size Calculation**: Different calculation strategies for different component types (axis, legend, title, etc.) |
| 56 | +- **Cross-size Considerations**: Takes into account cross-size dimensions for proper layout |
| 57 | + |
| 58 | +#### Padding Calculation Logic |
| 59 | + |
| 60 | +The core layout logic is in the `computePadding` function: |
| 61 | + |
| 62 | +```typescript |
| 63 | +const autoSizeOf = (d) => { |
| 64 | + if (d.size) return; |
| 65 | + if (value !== 'auto') sizeOf(d); |
| 66 | + else { |
| 67 | + // Compute component size dynamically |
| 68 | + computeComponentSize( |
| 69 | + d, |
| 70 | + crossSize, |
| 71 | + crossPadding, |
| 72 | + position, |
| 73 | + theme, |
| 74 | + library, |
| 75 | + ); |
| 76 | + defaultSizeOf(d); |
| 77 | + } |
| 78 | +}; |
| 79 | +``` |
| 80 | + |
| 81 | +- **Auto Padding ('auto')**: Calls `computeComponentSize` to measure actual content dimensions |
| 82 | +- **Manual Padding**: Uses `defaultSize` directly, bypassing content measurement |
| 83 | + |
| 84 | +### 4. Component Rendering |
| 85 | + |
| 86 | +The `renderComponent` function in `src/runtime/component.ts` handles the actual rendering: |
| 87 | + |
| 88 | +- **Component Instantiation**: Creates the appropriate component based on type |
| 89 | +- **Context Injection**: Provides scale instances, theme, and other context information |
| 90 | +- **Display Object Creation**: Returns a DisplayObject that can be added to the chart |
| 91 | + |
| 92 | +### 5. Legend Positioning and BBox Assignment |
| 93 | + |
| 94 | +After size calculation, the `placeComponents` function assigns bounding boxes: |
| 95 | + |
| 96 | +- **Position-based Grouping**: Components are grouped by position (top, bottom, left, right, center) |
| 97 | +- **Area Calculation**: Each position gets a specific area in the chart layout |
| 98 | +- **Dimension Assignment**: Components receive their final x, y, width, and height values |
| 99 | + |
| 100 | +## Legend Types and Configuration |
| 101 | + |
| 102 | +### Categorical Legends |
| 103 | + |
| 104 | +Categorical legends (LegendCategory) are used for discrete scales and support: |
| 105 | + |
| 106 | +- **Item Markers**: Automatic marker generation based on chart types |
| 107 | +- **Flexible Layouts**: Supports both flex and grid layouts |
| 108 | +- **Custom Rendering**: HTML-based custom rendering via the `render` option |
| 109 | +- **Interaction Features**: Support for filtering and focus modes |
| 110 | + |
| 111 | +### Continuous Legends |
| 112 | + |
| 113 | +Continuous legends (LegendContinuous) handle continuous scales: |
| 114 | + |
| 115 | +- **Color Ranges**: Support for various color interpolation methods |
| 116 | +- **Scale Types**: Handles linear, log, time, and quantile scales |
| 117 | +- **Threshold Handling**: Special support for threshold scales with custom boundaries |
| 118 | +- **Size Control**: Configurable ribbon sizes and label spacing |
| 119 | + |
| 120 | +## Interaction Handling |
| 121 | + |
| 122 | +### Legend Filtering |
| 123 | + |
| 124 | +The legend filtering interaction is implemented in `src/interaction/legendFilter.ts`: |
| 125 | + |
| 126 | +- **Event Delegation**: Handles click, pointerenter, and pointerout events |
| 127 | +- **State Management**: Maintains selection states and visual feedback |
| 128 | +- **Filter Propagation**: Updates chart data based on legend selections |
| 129 | +- **Cross-chart Coordination**: Supports filtering across multiple chart views |
| 130 | + |
| 131 | +### Visual States |
| 132 | + |
| 133 | +Legends support multiple visual states: |
| 134 | + |
| 135 | +- **Selected/Unselected**: Visual distinction between selected and unselected items |
| 136 | +- **Hover States**: Pointer interaction feedback |
| 137 | +- **Focus Mode**: Special highlighting for focused items |
| 138 | + |
| 139 | +## Customization and Theming |
| 140 | + |
| 141 | +### Theme Integration |
| 142 | + |
| 143 | +Legend components integrate with G2's theming system: |
| 144 | + |
| 145 | +- **Theme Properties**: Respects theme settings for colors, fonts, and spacing |
| 146 | +- **Component-specific Themes**: Separate theme settings for different legend types |
| 147 | +- **Style Override**: Allows specific style overrides via component options |
| 148 | + |
| 149 | +### Layout Customization |
| 150 | + |
| 151 | +- **Position Control**: Configurable positions (top, bottom, left, right, center) |
| 152 | +- **Size Control**: Manual or automatic size calculation |
| 153 | +- **Padding Control**: Configurable padding and spacing |
| 154 | +- **Orientation Control**: Horizontal or vertical orientation options |
| 155 | + |
| 156 | +## Best Practices |
| 157 | + |
| 158 | +### Performance Considerations |
| 159 | + |
| 160 | +- **Efficient Data Processing**: Minimize legend data processing for large datasets |
| 161 | +- **Optimized Rendering**: Use appropriate rendering strategies for different legend types |
| 162 | +- **Event Handling**: Properly manage and clean up event listeners |
| 163 | + |
| 164 | +### Accessibility |
| 165 | + |
| 166 | +- **Label Clarity**: Ensure legend labels are clear and descriptive |
| 167 | +- **Color Contrast**: Maintain sufficient contrast for color accessibility |
| 168 | +- **Interaction Feedback**: Provide clear visual feedback for interactions |
| 169 | + |
| 170 | +## Troubleshooting Common Issues |
| 171 | + |
| 172 | +### Layout Issues |
| 173 | + |
| 174 | +When `paddingTop` is manually set (e.g., `paddingTop: 72`), the height of `legendCategory` changes unexpectedly (e.g., from 60px to 40px). This occurs because: |
| 175 | + |
| 176 | +1. When padding is manually set, the layout engine uses the component's `defaultSize` instead of measuring actual content |
| 177 | +2. For `LegendCategory`, the default size is 40 (defined in `src/component/legendCategory.ts`) |
| 178 | +3. To fix this, explicitly set the `size` property in the legend configuration to override the default |
| 179 | + |
| 180 | +### Interaction Issues |
| 181 | + |
| 182 | +- **Event Bubbling**: Ensure proper event handling to prevent unwanted interactions |
| 183 | +- **State Synchronization**: Keep legend states synchronized across different chart views |
| 184 | +- **Performance**: Use throttling for filter events to prevent excessive updates |
| 185 | + |
| 186 | +## References |
| 187 | + |
| 188 | +For more detailed information on legend layout mechanisms and related topics, see the knowledge directory: |
| 189 | + |
| 190 | +- **Legend Layout Mechanisms**: `./knowledge/legendLayout.md` - Detailed analysis of padding behavior and layout calculations |
| 191 | + - Manual Padding Effects: How manually set padding values affect legend sizing |
| 192 | + - Default Size Fallback: Behavior when padding is set manually vs. 'auto' |
| 193 | + - Layout Calculation Logic: The core algorithm in `computePadding` function |
0 commit comments