Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Sequential Scale #188

Closed
3 tasks
pearmini opened this issue Aug 23, 2022 · 0 comments
Closed
3 tasks

Add Sequential Scale #188

pearmini opened this issue Aug 23, 2022 · 0 comments
Assignees
Labels
enhancement New feature or request

Comments

@pearmini
Copy link
Member

pearmini commented Aug 23, 2022

Sequential Scale

Sequential Scales are like linear scales, except that they use interpolator function rather than an array to describe the visual domain. And they also do not expose the invert method and interpolate options.

For every value to be scaled, there are two steps in short:

  • Normalize: Map x from [min, max] to [0, 1].
  • Interpolate: Apply interpolator to the normalized value.

Basic Usage

import { Sequential } from '@antv/scale';

function interpolator(t) {
  return 1 - t;
}

const scale = new Sequential({
  domain: [0, 10],
  interpolator: interpolator,
});

scale.map(5); // 0.5
scale.map(2); // 0.8
scale.map(8); // 0.2
scale.getOptions().range; // [1, 0]

API Design

export type SequentialOptions = Omit<LinearOptions, 'Interpolates'> & { interpolator: Interpolate };
  • scale.map(x)
  • scale.getTicks()
  • scale.update(options)
  • scale.getOptions()
  • scale.nice()
  • scale.clone()

Implement Suggestions

Note: This is just some suggestions, feel free to implement them in your own way if you have a better idea.

Use decoration instead of inheritance to enhance linear scale. Although this will cause inconsistent design patterns, it is good for future scales, such as SequentialLog, SequentialPow, SequentialSqrt, etc,.

// src/sequential.ts
import { Linear, Log } from './linear',

function Sequentialish(Scale) {
  // Modify the behavior of public method map directly.
  Scale.prototype.map = function(x) {}

  // Or modify the behavior of protected method rescale to get new output function.
  Scale.prototype.rescale = function() {
    // ...
    this.ouput = /* ... */;
  }

  Scale.prototype.invert = undefined;
}

// Define the shape of Sequential object explicitly.
interface Sequential {}
 
export const Sequential = Sequentialish(Linear);

Example In G2

image

G2.render({
  type: 'area',
  data: [],
  transform: [{ type: 'stackY', }],
  scale: {
    // Which one is better?
    // color: { type: 'linear', range: d3.interpolateCool }
    // color: { type: 'sequential', interpolator: d3.interpolateCool },
   color: {/* ... */},
  },
  encode: {
    x: 'year',
    y: 'value',
    color: () => Math.random()
  },
})

Reference

For more details, read the source code or doc of d3-scale.

Todo

  • source
  • test: coverage 100%
  • docs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
No open projects
Status: Done
Development

No branches or pull requests

2 participants