Skip to content

Commit 2268867

Browse files
authored
Merge branch 'master' into fix/poptip-render
2 parents 2ecbd68 + bace973 commit 2268867

File tree

17 files changed

+382
-42
lines changed

17 files changed

+382
-42
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@
118118
},
119119
{
120120
"path": "dist/component.min.js",
121-
"limit": "250 Kb"
121+
"limit": "260 Kb"
122122
}
123123
],
124124
"author": {

src/ui/legend/category.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ export class Category extends Component<CategoryStyleProps> {
2323
private items!: Selection<CategoryItems>;
2424

2525
private renderTitle(container: Selection, width: number, height: number) {
26-
const { showTitle, titleText } = this.attributes;
26+
const { showTitle, titleText, classNamePrefix } = this.attributes;
2727
const style = subStyleProps<TitleStyleProps>(this.attributes, 'title');
2828
const [titleStyle, groupStyle] = splitStyle(style);
2929

3030
this.titleGroup = container.maybeAppendByClassName<Group>(CLASS_NAMES.titleGroup, 'g').styles(groupStyle);
3131

32-
const finalTitleStyle = { width, height, ...titleStyle, text: showTitle ? titleText : '' };
32+
const finalTitleStyle = { width, height, ...titleStyle, text: showTitle ? titleText : '', classNamePrefix };
3333
this.title = this.titleGroup
3434
.maybeAppendByClassName(CLASS_NAMES.title, () => new Title({ style: finalTitleStyle as TitleStyleProps }))
3535
.update(finalTitleStyle) as Selection<Title>;

src/ui/legend/category/item.ts

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import {
3030
import { Poptip } from '../../poptip';
3131
import type { PoptipStyleProps } from '../../poptip/types';
3232
import type { PoptipRender } from './items';
33+
import { getLegendClassName } from '../utils/classname';
34+
import { CLASSNAME_SUFFIX_MAP } from '../constant';
3335

3436
type ItemMarkerStyle = { size?: number } & PathStyleProps;
3537
type ItemTextStyle = Omit<TextStyleProps, 'text'>;
@@ -53,6 +55,7 @@ export type CategoryItemStyleProps = GroupStyleProps &
5355
poptip?: PoptipStyleProps & PoptipRender;
5456
focus?: boolean;
5557
focusMarkerSize?: number;
58+
classNamePrefix?: string;
5659
};
5760

5861
export type CategoryItemOptions = ComponentOptions<CategoryItemStyleProps>;
@@ -227,19 +230,26 @@ export class CategoryItem extends Component<CategoryItemStyleProps> {
227230
}
228231

229232
private renderMarker(container: Selection) {
230-
const { marker } = this.attributes;
233+
const { marker, classNamePrefix } = this.attributes;
231234
const style = subStyleProps(this.attributes, 'marker');
232235
this.markerGroup = container.maybeAppendByClassName(CLASS_NAMES.markerGroup, 'g').style('zIndex', 0);
233236
ifShow(!!marker, this.markerGroup, () => {
234237
const parent = this.markerGroup.node();
235238
const oldMarker = parent.childNodes?.[0] as DisplayObject | undefined;
239+
const markerClassName = getLegendClassName(CLASS_NAMES.marker.name, CLASSNAME_SUFFIX_MAP.marker, classNamePrefix);
236240
const newMarker =
237-
typeof marker === 'string'
238-
? new Marker({ style: { symbol: marker }, className: CLASS_NAMES.marker.name })
239-
: marker();
241+
typeof marker === 'string' ? new Marker({ style: { symbol: marker }, className: markerClassName }) : marker();
240242

241243
if (!oldMarker) {
242-
if (!(newMarker instanceof Marker)) select(newMarker).attr('className', CLASS_NAMES.marker.name).styles(style);
244+
if (!(newMarker instanceof Marker)) {
245+
const markerClassName = getLegendClassName(
246+
CLASS_NAMES.marker.name,
247+
CLASSNAME_SUFFIX_MAP.marker,
248+
classNamePrefix
249+
);
250+
(newMarker as any).className = markerClassName;
251+
select(newMarker).styles(style);
252+
}
243253
parent.appendChild(newMarker);
244254
} else if (newMarker.nodeName === oldMarker.nodeName) {
245255
if (oldMarker instanceof Marker) oldMarker.update({ ...style, symbol: marker });
@@ -249,7 +259,15 @@ export class CategoryItem extends Component<CategoryItemStyleProps> {
249259
}
250260
} else {
251261
oldMarker.remove();
252-
select(newMarker).attr('className', CLASS_NAMES.marker.name).styles(style);
262+
if (!(newMarker instanceof Marker)) {
263+
const markerClassName = getLegendClassName(
264+
CLASS_NAMES.marker.name,
265+
CLASSNAME_SUFFIX_MAP.marker,
266+
classNamePrefix
267+
);
268+
(newMarker as any).className = markerClassName;
269+
}
270+
select(newMarker).styles(style);
253271
parent.appendChild(newMarker);
254272
}
255273

@@ -262,15 +280,23 @@ export class CategoryItem extends Component<CategoryItemStyleProps> {
262280

263281
private renderLabel(container: Selection) {
264282
const { text: label, ...style } = subStyleProps(this.attributes, 'label');
283+
const { classNamePrefix } = this.attributes;
265284
this.labelGroup = container.maybeAppendByClassName<Group>(CLASS_NAMES.labelGroup, 'g').style('zIndex', 0);
266-
this.labelGroup.maybeAppendByClassName(CLASS_NAMES.label, () => renderExtDo(label)).styles(style);
285+
const labelClassName = getLegendClassName(CLASS_NAMES.label.name, CLASSNAME_SUFFIX_MAP.label, classNamePrefix);
286+
const labelElement = this.labelGroup.maybeAppendByClassName(CLASS_NAMES.label, () => renderExtDo(label));
287+
labelElement.node().setAttribute('class', labelClassName);
288+
labelElement.styles(style);
267289
}
268290

269291
private renderValue(container: Selection) {
270292
const { text: value, ...style } = subStyleProps(this.attributes, 'value');
293+
const { classNamePrefix } = this.attributes;
271294
this.valueGroup = container.maybeAppendByClassName(CLASS_NAMES.valueGroup, 'g').style('zIndex', 0);
272295
ifShow(this.showValue, this.valueGroup, () => {
273-
this.valueGroup.maybeAppendByClassName(CLASS_NAMES.value, () => renderExtDo(value)).styles(style);
296+
const valueClassName = getLegendClassName(CLASS_NAMES.value.name, CLASSNAME_SUFFIX_MAP.value, classNamePrefix);
297+
const valueElement = this.valueGroup.maybeAppendByClassName(CLASS_NAMES.value, () => renderExtDo(value));
298+
valueElement.node().setAttribute('class', valueClassName);
299+
valueElement.styles(style);
274300
});
275301
}
276302

@@ -305,7 +331,7 @@ export class CategoryItem extends Component<CategoryItemStyleProps> {
305331
}
306332

307333
private renderFocus(ctn: Selection) {
308-
const { focus, focusMarkerSize } = this.attributes;
334+
const { focus, focusMarkerSize, classNamePrefix } = this.attributes;
309335
const defaultOptions = {
310336
x: 0,
311337
y: 0,
@@ -320,11 +346,17 @@ export class CategoryItem extends Component<CategoryItemStyleProps> {
320346

321347
this.focusGroup = ctn.maybeAppendByClassName<Group>(CLASS_NAMES.focusGroup, 'g').style('zIndex', 0);
322348
ifShow(focus, this.focusGroup, () => {
349+
const focusClassName = getLegendClassName(
350+
CLASS_NAMES.focus.name,
351+
CLASSNAME_SUFFIX_MAP.focusIcon,
352+
classNamePrefix
353+
);
323354
const marker = new Marker({
324355
style: {
325356
...defaultOptions,
326357
symbol: 'focus',
327358
},
359+
className: focusClassName,
328360
});
329361
const interactiveCircle = new Circle({
330362
style: {
@@ -363,7 +395,18 @@ export class CategoryItem extends Component<CategoryItemStyleProps> {
363395
const { width, height } = this.shape;
364396
const style = subStyleProps(this.attributes, 'background');
365397
this.background = container.maybeAppendByClassName(CLASS_NAMES.backgroundGroup, 'g').style('zIndex', -1);
366-
this.background.maybeAppendByClassName(CLASS_NAMES.background, 'rect').styles({ width, height, ...style });
398+
const backgroundElement = this.background.maybeAppendByClassName(CLASS_NAMES.background, 'rect');
399+
backgroundElement.styles({ width, height, ...style });
400+
401+
const { classNamePrefix = '' } = this.attributes;
402+
if (classNamePrefix) {
403+
const backgroundClassName = getLegendClassName(
404+
CLASS_NAMES.background.name,
405+
CLASSNAME_SUFFIX_MAP.background,
406+
classNamePrefix
407+
);
408+
backgroundElement.node().setAttribute('class', backgroundClassName);
409+
}
367410
}
368411

369412
private adjustLayout() {

src/ui/legend/category/items.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import { ifHorizontal } from '../utils';
2121
import type { CategoryItemStyleProps } from './item';
2222
import { CategoryItem } from './item';
2323
import type { PoptipStyleProps } from '../../poptip/types';
24+
import { getLegendClassName } from '../utils/classname';
25+
import { CLASSNAME_SUFFIX_MAP } from '../constant';
2426

2527
interface CategoryItemsDatum {
2628
[keys: string]: any;
@@ -62,6 +64,7 @@ export type CategoryItemsStyleProps = GroupStyleProps &
6264
poptip?: PoptipStyleProps & PoptipRender;
6365
focus?: boolean;
6466
focusMarkerSize?: number;
67+
classNamePrefix?: string;
6568
};
6669

6770
export type CategoryItemsOptions = ComponentOptions<CategoryItemsStyleProps>;
@@ -136,7 +139,7 @@ export class CategoryItems extends Component<CategoryItemsStyleProps> {
136139
}
137140

138141
private get renderData() {
139-
const { data, layout, poptip, focus, focusMarkerSize } = this.attributes;
142+
const { data, layout, poptip, focus, focusMarkerSize, classNamePrefix } = this.attributes;
140143
const style = subStyleProps<CategoryItemStyleProps>(this.attributes, 'item');
141144

142145
const d = data.map((datum, index) => {
@@ -151,6 +154,7 @@ export class CategoryItems extends Component<CategoryItemsStyleProps> {
151154
poptip,
152155
focus,
153156
focusMarkerSize,
157+
classNamePrefix,
154158
...Object.fromEntries(
155159
Object.entries(style).map(([key, val]) => [key, getCallbackValue(val, [datum, index, data])])
156160
),
@@ -255,17 +259,18 @@ export class CategoryItems extends Component<CategoryItemsStyleProps> {
255259
}
256260

257261
private renderItems(container: Group) {
258-
const { click, mouseenter, mouseleave } = this.attributes;
262+
const { click, mouseenter, mouseleave, classNamePrefix } = this.attributes;
259263
this.flattenPage(container);
260264
const dispatchCustomEvent = this.dispatchCustomEvent.bind(this);
265+
const itemClassName = getLegendClassName(CLASS_NAMES.item.name, CLASSNAME_SUFFIX_MAP.item, classNamePrefix);
261266
select(container)
262267
.selectAll(CLASS_NAMES.item.class)
263268
.data(this.renderData, (d) => d.id)
264269
.join(
265270
(enter) =>
266271
enter
267272
.append(({ style, ...rest }) => new CategoryItem({ style }, rest))
268-
.attr('className', CLASS_NAMES.item.name)
273+
.attr('className', itemClassName)
269274
.on('click', function () {
270275
click?.(this);
271276
dispatchCustomEvent('itemClick', { item: this });
@@ -316,9 +321,9 @@ export class CategoryItems extends Component<CategoryItemsStyleProps> {
316321
}
317322

318323
private renderNavigator(container: Selection) {
319-
const { orientation } = this.attributes;
324+
const { orientation, classNamePrefix } = this.attributes;
320325
const navStyle = subStyleProps(this.attributes, 'nav');
321-
const style = deepAssign({ orientation }, navStyle);
326+
const style = deepAssign({ orientation, classNamePrefix }, navStyle);
322327
const that = this;
323328
container
324329
.selectAll(CLASS_NAMES.navigator.class)

src/ui/legend/classname-map.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* className suffix mapping for legend elements
3+
* Used to generate prefixed classNames, e.g., classNamePrefix='g2-' generates 'g2-legend-{suffix}'
4+
*
5+
* @example
6+
* import { CLASSNAME_SUFFIX_MAP, getLegendClassName } from './utils';
7+
*
8+
* const titleClassName = getLegendClassName(
9+
* CLASS_NAMES.text.name,
10+
* CLASSNAME_SUFFIX_MAP.title,
11+
* 'g2-'
12+
* );
13+
* // Returns: 'title-text g2-legend-title'
14+
*/
15+
export const CLASSNAME_SUFFIX_MAP = {
16+
// Common elements
17+
title: 'title',
18+
19+
// Category legend elements
20+
item: 'item',
21+
marker: 'marker',
22+
label: 'label',
23+
value: 'value',
24+
focusIcon: 'focus-icon',
25+
background: 'background',
26+
27+
// Continuous legend elements
28+
ribbon: 'ribbon',
29+
track: 'track',
30+
selection: 'selection',
31+
handle: 'handle',
32+
handleMarker: 'handle-marker',
33+
handleLabel: 'handle-label',
34+
indicator: 'indicator',
35+
36+
// Navigator elements (reserved)
37+
prevBtn: 'prev-btn',
38+
nextBtn: 'next-btn',
39+
pageInfo: 'page-info',
40+
} as const;
41+
42+
/**
43+
* className suffix type
44+
*/
45+
export type ClassNameSuffix = keyof typeof CLASSNAME_SUFFIX_MAP;

src/ui/legend/constant.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { classNames, deepAssign, superStyleProps } from '../../util';
22
import { DEFAULT_HANDLE_CFG } from './continuous/handle';
33
import type { LegendBaseStyleProps } from './types';
44

5+
export { CLASSNAME_SUFFIX_MAP, type ClassNameSuffix } from './classname-map';
6+
57
export const LEGEND_BASE_DEFAULT_OPTIONS: Partial<LegendBaseStyleProps> = {
68
showTitle: true,
79
padding: 0,

0 commit comments

Comments
 (0)