Skip to content

Commit

Permalink
feat(line): draw charts related to line geometry including parallel c…
Browse files Browse the repository at this point in the history
…oordinate. (antvis#3845)

* feat(runtime): render charts related to line geometry.

1. scale:
 - Time
 - Point
 - Not not nice by defualt
 - Infer padding
2. mark: Line
3. shape: Line
4. infer: MaybeSeries

* feat(stdlib): update stdlib and related test cases

* test(scale): add test suite for point and time

* feat(transform): update fetch and add filterBy

* feat(coordinate): add parallel

* feat(statistic): add splitPosition for position channel

* feat(infer): update and infer with inferring statistic

* feat(shape): add line and smooth, rename rect and hollowRect

* feat(geometry): add line

* feat(runtime): add parallel

* feat(stdlib): add pick transform

* refactor(runtime): plot
  • Loading branch information
pearmini authored and hustcc committed Mar 30, 2022
1 parent 162f50e commit e9d0c79
Show file tree
Hide file tree
Showing 67 changed files with 1,901 additions and 310 deletions.
6 changes: 5 additions & 1 deletion __tests__/unit/coordinate/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Cartesian, Polar, Transpose } from '../../../src/coordinate';
import { Cartesian, Polar, Transpose, Parallel } from '../../../src/coordinate';

describe('coordinate', () => {
it('Cartesian() returns expected coordinate transformations', () => {
Expand Down Expand Up @@ -36,4 +36,8 @@ describe('coordinate', () => {
['polar', -Math.PI / 2, Math.PI, 0.2, 0.8],
]);
});

it('Parallel({...}) returns expected coordinate transformations', () => {
expect(Parallel()).toEqual([['parallel', 0, 1, 0, 1]]);
});
});
5 changes: 3 additions & 2 deletions __tests__/unit/geometry/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
type Options = {
index: number[];
mark: Mark;
scale: Record<string, Scale>;
scale?: Record<string, Scale>;
container: string | HTMLElement;
channel: {
x?: number[][];
Expand All @@ -35,11 +35,12 @@ type Options = {
export function plot({
index,
mark,
scale,
scale = {},
channel,
container,
theme = {
defaultColor: '#5B8FF9',
defaultSize: 1,
},
x = 0,
y = 0,
Expand Down
7 changes: 4 additions & 3 deletions __tests__/unit/geometry/interval.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Interval } from '../../../src/geometry';
import { ShapeRect } from '../../../src/shape';
import { Rect as RectShape } from '../../../src/shape';
import { Band } from '../../../src/scale';
import { createDiv, mount, unmountAll } from '../../utils/dom';
import { plot } from './helper';
Expand All @@ -23,14 +23,15 @@ describe('Interval', () => {
{ type: 'maybeTuple' },
{ type: 'maybeZeroX1' },
{ type: 'maybeZeroY2' },
{ type: 'maybeStackY' },
],
shapes: ['rect', 'hollowRect'],
});
});

it('Interval() returns a function transforming values into interval shapes', () => {
const container = document.createElement('div');
const rect = ShapeRect();
const rect = RectShape();
const shapes = plot({
mark: Interval({}),
container,
Expand Down Expand Up @@ -91,7 +92,7 @@ describe('Interval', () => {

it('Interval() returns a function handle series channel', () => {
const container = document.createElement('div');
const rect = ShapeRect();
const rect = RectShape();
const shapes = plot({
mark: Interval({}),
container,
Expand Down
218 changes: 218 additions & 0 deletions __tests__/unit/geometry/line.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
import { Parallel } from '../../../src/coordinate';
import { Line } from '../../../src/geometry';
import { Line as LineShape } from '../../../src/shape';
import { createDiv, mount, unmountAll } from '../../utils/dom';
import { plot } from './helper';

describe('Line', () => {
it('Line has expected props', () => {
expect(Line.props).toEqual({
defaultShape: 'line',
channels: [
{ name: 'x' },
{ name: 'y' },
{ name: 'size' },
{ name: 'series', scale: 'identity' },
{ name: 'color' },
{ name: 'position' },
{ name: 'shape' },
{ name: 'enterType' },
{ name: 'enterDelay' },
{ name: 'enterDuration' },
{ name: 'enterEasing' },
],
infer: [
{ type: 'maybeTuple' },
{ type: 'maybeSeries' },
{ type: 'maybeSplitPosition' },
],
shapes: ['line', 'smooth'],
});
});

it('Line should draw basic line', () => {
const container = document.createElement('div');
const line = LineShape();
const shapes = plot({
mark: Line({}),
container,
index: [0, 1, 2],
channel: {
x: [[0.2], [0.4], [0.6]],
y: [[0.5], [0.2], [0.4]],
shape: [line, line, line],
},
});
mount(createDiv(), container);

const attributes = shapes.map((d) => ({
type: d.nodeName,
stroke: d.style.stroke,
path: d.style.path,
lineWidth: d.style.lineWidth,
}));

expect(attributes).toEqual([
{
type: 'path',
stroke: '#5B8FF9',
lineWidth: 1,
path: 'M120,200L240,80L360,160',
},
]);
});

it('Line should using size channel as lineWidth', () => {
const container = document.createElement('div');
const line = LineShape();
const shapes = plot({
mark: Line({}),
container,
index: [0, 1, 2],
channel: {
x: [[0.2], [0.4], [0.6]],
y: [[0.5], [0.2], [0.4]],
shape: [line, line, line],
size: [2, 2, 2],
},
});
mount(createDiv(), container);

const attributes = shapes.map((d) => ({
type: d.nodeName,
lineWidth: d.style.lineWidth,
}));

expect(attributes).toEqual([
{
type: 'path',
lineWidth: 2,
},
]);
});

it('Line should drawing multiple lines', () => {
const container = document.createElement('div');
const line = LineShape();
const shapes = plot({
mark: Line({}),
container,
index: [0, 1, 2, 3, 4, 5],
channel: {
x: [[0.2], [0.4], [0.6], [0.5], [0.2], [0.4]],
y: [[0.5], [0.2], [0.4], [0.2], [0.4], [0.6]],
series: ['a', 'a', 'a', 'b', 'b', 'b'],
color: ['steelblue', 'a', 'b', 'orange', 'c', 'd'],
shape: [line, line, line, line, line, line],
},
});
mount(createDiv(), container);

const attributes = shapes.map((d) => ({
type: d.nodeName,
path: d.style.path,
stroke: d.style.stroke,
}));

expect(attributes).toEqual([
{
type: 'path',
stroke: 'steelblue',
path: 'M120,200L240,80L360,160',
},
{
type: 'path',
stroke: 'orange',
path: 'M300,80L120,160L240,240',
},
]);
});

it('Line should drawing parallel lines', () => {
const container = document.createElement('div');
const line = LineShape();
const shapes = plot({
mark: Line({}),
container,
index: [0, 1, 2],
channel: {
'position[0]': [0.2, 0.9, 0.3],
'position[1]': [0.3, 0.5, 0.1],
'position[2]': [0.9, 0.4, 0.7],
shape: [line, line, line],
},
transform: [Parallel()],
});
mount(createDiv(), container);

const attributes = shapes.map((d) => ({
type: d.nodeName,
path: d.style.path,
}));

expect(attributes).toEqual([
{
type: 'path',
path: 'M0,80L300,120L600,360',
},
{
type: 'path',
path: 'M0,360L300,200L600,160',
},
{
type: 'path',
path: 'M0,120L300,40L600,280',
},
]);
});

it('Line should throw error without x', () => {
const container = document.createElement('div');
const line = LineShape();
expect(() =>
plot({
mark: Line({}),
container,
index: [0, 1, 2],
channel: {
y: [[0.5], [0.2], [0.4]],
shape: [line, line, line],
size: [2, 2, 2],
},
}),
).toThrowError();
});

it('Line should throw error without y', () => {
const container = document.createElement('div');
const line = LineShape();
expect(() =>
plot({
mark: Line({}),
container,
index: [0, 1, 2],
channel: {
x: [[0.5], [0.2], [0.4]],
shape: [line, line, line],
size: [2, 2, 2],
},
}),
).toThrowError();
});

it('Line should throw error without position', () => {
const container = document.createElement('div');
const line = LineShape();
expect(() =>
plot({
mark: Line({}),
container,
index: [0, 1, 2],
channel: {
shape: [line, line, line],
},
transform: [Parallel()],
}),
).toThrowError();
});
});
Loading

0 comments on commit e9d0c79

Please sign in to comment.