Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"comment": "perf: move `enableSegments` to spec\n\n",
"type": "none",
"packageName": "@visactor/vgrammar-core"
}
],
"packageName": "@visactor/vgrammar-core",
"email": "dingling112@gmail.com"
}
11 changes: 1 addition & 10 deletions docs/dev-demos/src/specs/area-mark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ export const spec = {
padding: 5,

signals: [
{
id: 'enableSegments',
value: true
},
{
id: 'defined',
value: true
Expand Down Expand Up @@ -119,12 +115,12 @@ export const spec = {
// ease: "linear"
}
},
enableSegments: true,
encode: {
enter: {
// stroke: '#652c90'
},
update: {
enableSegments: { signal: 'enableSegments' },
x: { scale: 'xscale', field: 'u' },
y1: { scale: 'yscale', value: 0 },
y: { scale: 'yscale', field: 'v' },
Expand Down Expand Up @@ -164,11 +160,6 @@ export const spec = {
};

export const binds = [
{
id: 'enableSegments',
value: true,
bind: { input: 'checkbox' }
},
{
id: 'defined',
value: true,
Expand Down
2 changes: 1 addition & 1 deletion docs/dev-demos/src/specs/line-chart-segments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export const spec = {
{
type: 'line',
id: 'line',
enableSegments: true,
// animationState: 'appear',
animation: {
enter: {
Expand Down Expand Up @@ -108,7 +109,6 @@ export const spec = {
return [];
},
lineWidth: 2,
enableSegments: true
},
update: {
// interpolate: { signal: 'interpolate' },
Expand Down
12 changes: 1 addition & 11 deletions docs/dev-demos/src/specs/line-mark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@ export const spec = {
padding: 5,

signals: [
{
id: 'enableSegments',
value: true,
bind: { input: 'checkbox' }
},
{
id: 'defined',
value: true,
Expand Down Expand Up @@ -149,12 +144,12 @@ export const spec = {
// ease: "linear"
}
},
enableSegments: true,
encode: {
enter: {
stroke: '#652c90'
},
update: {
enableSegments: { signal: 'enableSegments' },
x: { scale: 'xscale', field: 'u' },
y: { scale: 'yscale', field: 'v' },
defined: {
Expand Down Expand Up @@ -187,11 +182,6 @@ export const spec = {
};

export const binds = [
{
id: 'enableSegments',
value: true,
bind: { input: 'checkbox' }
},
{
id: 'defined',
value: true,
Expand Down
2 changes: 1 addition & 1 deletion docs/dev-demos/src/specs/simple-area-chart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ export const spec = {
type: 'area',
id: 'area',
from: { data: 'table' },
enableSegments: true,
encode: {
update: {
enableSegments: true,
x: { scale: 'xscale', field: 'u' },
y: { scale: 'yscale', value: 0 },
y1: { scale: 'yscale', field: 'v' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ cover: /vgrammar/preview/basic-mark-line-segmental-line_0.7.6.png

## Key Configuration

- `enableSegments`: When the visual channel `enableSegments` of the line is set to `true`, VGrammar will calculate the visual channel encoding of each point. If there are differences, it will automatically create a segmented style curve.
- `enableSegments`: When the spec `enableSegments` of the line is set to `true`, VGrammar will calculate the visual channel encoding of each point. If there are differences, it will automatically create a segmented style curve.

## Code Demonstration

Expand Down Expand Up @@ -140,14 +140,14 @@ const spec = {
{
type: 'line',
from: { data: 'table' },
enableSegments: true,
encode: {
enter: {
lineWidth: 2
},
update: {
x: { scale: 'xscale', field: 'time' },
y: { scale: 'yscale', field: 'value' },
enableSegments: true,
stroke: (datum, element, params) => {
return datum.value > 0 ? '#6690F2' : '#FF8F62';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ cover: /vgrammar/preview/basic-mark-line-segmental-line_0.7.6.png

## 关键配置

- `enableSegments` 当线的视觉通道`enableSegments`设置为`true`,VGrammar 会计算各个点的视觉通道编码,如果有差异,自动创建分段样式的曲线
- `enableSegments` 当线的`enableSegments`设置为`true`,VGrammar 会计算各个点的视觉通道编码,如果有差异,自动创建分段样式的曲线

## 代码演示

Expand Down Expand Up @@ -140,14 +140,14 @@ const spec = {
{
type: 'line',
from: { data: 'table' },
enableSegments: true,
encode: {
enter: {
lineWidth: 2
},
update: {
x: { scale: 'xscale', field: 'time' },
y: { scale: 'yscale', field: 'value' },
enableSegments: true,
stroke: (datum, element, params) => {
return datum.value > 0 ? '#6690F2' : '#FF8F62';
}
Expand Down
3 changes: 0 additions & 3 deletions packages/vgrammar-core/__tests__/mark/group-encode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ test('group encode of collection mark', () => {
const mark = new (Mark as any)(mockView, 'line') as IMark;

mark.encodeState('group', {
enableSegments: true,
fill: (datum: any) => (datum.group === '0' ? 'red' : 'green'),
stroke: 'black'
});
Expand All @@ -67,7 +66,6 @@ test('group encode of collection mark', () => {
expect(mark.elements[0].getGraphicAttribute('stroke')).toEqual('black');
expect(mark.elements[0].getGraphicAttribute('points')).toEqual([
{
enableSegments: true,
context: 1,
x: 1,
y: 10
Expand All @@ -82,7 +80,6 @@ test('group encode of collection mark', () => {
expect(mark.elements[1].getGraphicAttribute('stroke')).toEqual('black');
expect(mark.elements[1].getGraphicAttribute('points')).toEqual([
{
enableSegments: true,
context: 1,
x: 1,
y: 20
Expand Down
90 changes: 90 additions & 0 deletions packages/vgrammar-core/__tests__/mark/line.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,93 @@ test('addState to line', function () {
});
expect(element.getGraphicAttribute('fillOpacity')).toBe(0.5);
});

test('enableSegments is false of line', function () {
const encode = {
update: {
fill: (datum: any) => (datum.key <= 1 ? 'red' : 'green'),
x: (datum: any) => datum.key,
y: 10
}
};
const element = createSimpleElement('line', {
markSpec: {
encode,
enableSegments: false
}
});

element.updateData('key', [{ key: 0 }, { key: 1 }, { key: 2 }, { key: 3 }], 'key', {} as any);
element.initGraphicItem();

// encode enter
expect(element.getGraphicAttribute('points')).toEqual(undefined);
element.encodeItems(element.items, encode, false, {});
element.encodeGraphic();
expect(element.getGraphicAttribute('points')).toEqual([
{ x: 0, y: 10, context: 0, fill: 'red' },
{ x: 1, y: 10, context: 1 },
{ x: 2, y: 10, context: 2 },
{ x: 3, y: 10, context: 3 }
]);
expect(element.getGraphicItem().attribute).toEqual({
fill: 'red',
points: [
{ x: 0, y: 10, context: 0, fill: 'red' },
{ x: 1, y: 10, context: 1 },
{ x: 2, y: 10, context: 2 },
{ x: 3, y: 10, context: 3 }
],
segments: null
});
});

test('enableSegments is true', function () {
const encode = {
update: {
stroke: (datum: any) => (datum.key <= 1 ? 'red' : 'green'),
x: (datum: any) => datum.key,
y: 10
}
};
const element = createSimpleElement('line', {
markSpec: {
encode,
enableSegments: true
}
});

element.updateData('key', [{ key: 0 }, { key: 1 }, { key: 2 }, { key: 3 }], 'key', {} as any);
element.initGraphicItem();

// encode enter
expect(element.getGraphicAttribute('points')).toEqual(undefined);
element.encodeItems(element.items, encode, false, {});
element.encodeGraphic();
expect(element.getGraphicItem().attribute).toEqual({
points: null,
segments: [
{
context: 0,
points: [
{ x: 0, y: 10, context: 0, stroke: 'red' },
{ x: 1, y: 10, context: 1, stroke: 'red' }
],
stroke: 'red',
x: 0,
y: 0
},
{
context: 2,
points: [
{ x: 2, y: 10, context: 2, stroke: 'green' },
{ x: 3, y: 10, context: 3, stroke: 'green' }
],
stroke: 'green',
x: 0,
y: 0
}
],
stroke: 'red'
});
});
2 changes: 1 addition & 1 deletion packages/vgrammar-core/src/graph/attributes/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const transformsByType: Record<string, AttributeTransform[]> = {
],
[GrammarMarkType.line]: [
{
channels: ['x', 'y', 'defined', 'enableSegments'],
channels: ['x', 'y', 'defined'],
transform: (graphicAttributes: any, nextAttrs: any, storedAttrs: any) => {
graphicAttributes.x = 0;
graphicAttributes.y = 0;
Expand Down
8 changes: 2 additions & 6 deletions packages/vgrammar-core/src/graph/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,6 @@ export class Element implements IElement {
encodeGraphic(attrs?: any) {
this.coordinateTransformEncode(this.items);

if (!isNil(attrs?.enableSegments) && this.items?.[0]?.nextAttrs) {
this.items[0].nextAttrs.enableSegments = attrs.enableSegments;
}

const graphicAttributes = this.transformElementItems(this.items, this.mark.markType);

if (attrs) {
Expand Down Expand Up @@ -269,7 +265,7 @@ export class Element implements IElement {
const updateEncoder = encoders[BuiltInEncodeNames.update];
const enterEncoder = encoders[BuiltInEncodeNames.enter];
const exitEncoder = encoders[BuiltInEncodeNames.exit];
const onlyFullEncodeFirst = this.mark.isLargeMode();
const onlyFullEncodeFirst = this.mark.isLargeMode() || (isCollectionMark && !this.mark.getSpec().enableSegments);

if (this.diffState === DiffState.enter) {
if (enterEncoder) {
Expand Down Expand Up @@ -470,7 +466,7 @@ export class Element implements IElement {
) {
const lastPoints = this.getGraphicAttribute('points', false);
const lastSegments = this.getGraphicAttribute('segments', false);
const enableSegments = item.nextAttrs.enableSegments ?? this.getGraphicAttribute('enableSegments', false);
const enableSegments = this.mark.getSpec().enableSegments;
const itemNextAttrs = items.map(item => item.nextAttrs);
const isProgressive = this.mark.isProgressive();
nextAttrs = Object.assign({}, nextAttrs);
Expand Down
3 changes: 1 addition & 2 deletions packages/vgrammar-core/src/graph/glyph-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,10 +254,9 @@ export class GlyphElement extends Element implements IGlyphElement {
}

private _generateGlyphItems(markType: MarkType, items: MarkElementItem[], additionalAttributes: any) {
const nextAttrs = items[0]?.nextAttrs;
const glyphItems = items.map(item => Object.assign({}, item, { nextAttrs: additionalAttributes }));

if ((CollectionMarkType as string[]).includes(markType) && nextAttrs.enableSegments) {
if ((CollectionMarkType as string[]).includes(markType) && this.mark.getSpec().enableSegments) {
// segment mark require all items to apply additional attributes
glyphItems.forEach((glyphItem, index) => {
glyphItem.nextAttrs = Object.assign({}, items[index].nextAttrs, additionalAttributes);
Expand Down
5 changes: 5 additions & 0 deletions packages/vgrammar-core/src/types/mark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,11 @@ export interface IMarkConfig {
morphElementKey?: string;
/** transforms of attributes */
attributeTransforms?: AttributeTransform[];
/**
* only used in line/area mark
* TODO
*/
enableSegments?: boolean;
}

/**
Expand Down
3 changes: 2 additions & 1 deletion packages/vgrammar-core/src/view/mark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,8 @@ export class Mark extends GrammarBase implements IMark {
'morphKey',
'morphElementKey',
'attributeTransforms',
'skipTheme'
'skipTheme',
'enableSegments'
];
if (config === null) {
keys.forEach(key => {
Expand Down