Skip to content
This repository was archived by the owner on Dec 21, 2018. It is now read-only.

Commit 663a7e3

Browse files
committed
Initial commit.
1 parent 66ab2c0 commit 663a7e3

12 files changed

+537
-0
lines changed

.eslintrc

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
parserOptions:
2+
sourceType: "module"
3+
4+
env:
5+
es6: true
6+
browser: true
7+
node: true
8+
9+
extends:
10+
"eslint:recommended"
11+
12+
rules:
13+
no-cond-assign: 0

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
*.sublime-workspace
2+
.DS_Store
3+
build/
4+
node_modules
5+
npm-debug.log

.npmignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
*.sublime-*
2+
build/*.zip
3+
test/

LICENSE

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Copyright (c) 2016, University of Washington Interactive Data Lab
2+
All rights reserved.
3+
4+
Redistribution and use in source and binary forms, with or without
5+
modification, are permitted provided that the following conditions are met:
6+
7+
1. Redistributions of source code must retain the above copyright notice, this
8+
list of conditions and the following disclaimer.
9+
10+
2. Redistributions in binary form must reproduce the above copyright notice,
11+
this list of conditions and the following disclaimer in the documentation
12+
and/or other materials provided with the distribution.
13+
14+
3. Neither the name of the copyright holder nor the names of its contributors
15+
may be used to endorse or promote products derived from this software
16+
without specific prior written permission.
17+
18+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

index.js

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export {default as scale} from './src/scales';
2+
export {default as scheme} from './src/schemes';

package.json

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"name": "vega-scale",
3+
"version": "1.0.0",
4+
"description": "Scales and color schemes for visual encoding.",
5+
"keywords": [
6+
"vega",
7+
"scales"
8+
],
9+
"license": "BSD-3-Clause",
10+
"author": {
11+
"name": "Jeffrey Heer",
12+
"url": "http://idl.cs.washington.edu"
13+
},
14+
"main": "build/vega-scale.js",
15+
"jsnext:main": "index",
16+
"repository": {
17+
"type": "git",
18+
"url": "https://github.com/uwdata/vega-scale.git"
19+
},
20+
"scripts": {
21+
"pretest": "rm -rf build && mkdir build && rollup -g d3-array:d3,d3-scale:d3,d3-scale-chromatic:d3 -f umd -n vega -o build/vega-scale.js -- index.js",
22+
"test": "tape 'test/**/*-test.js' && eslint index.js src test",
23+
"prepublish": "npm run test && uglifyjs build/vega-scale.js -c -m -o build/vega-scale.min.js",
24+
"postpublish": "VERSION=`node -e 'console.log(require(\"./package.json\").version)'`; git push && git push --tags && zip -j build/vega-scale.zip -- LICENSE README.md build/vega-scale.js build/vega-scale.min.js"
25+
},
26+
"dependencies": {
27+
"d3-array": "1",
28+
"d3-scale": "1",
29+
"d3-scale-chromatic": "1"
30+
},
31+
"devDependencies": {
32+
"eslint": "2",
33+
"rollup": "0.34",
34+
"tape": "4",
35+
"uglify-js": "2"
36+
}
37+
}

src/band.js

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import {range as sequence, bisectRight} from 'd3-array';
2+
import {scaleOrdinal as ordinal} from 'd3-scale';
3+
4+
export default function band() {
5+
var scale = ordinal().unknown(undefined),
6+
domain = scale.domain,
7+
ordinalRange = scale.range,
8+
range = [0, 1],
9+
step,
10+
bandwidth,
11+
round = false,
12+
paddingInner = 0,
13+
paddingOuter = 0,
14+
align = 0.5;
15+
16+
delete scale.unknown;
17+
18+
function rescale() {
19+
var n = domain().length,
20+
reverse = range[1] < range[0],
21+
start = range[reverse - 0],
22+
stop = range[1 - reverse];
23+
step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2);
24+
if (round) step = Math.floor(step);
25+
start += (stop - start - step * (n - paddingInner)) * align;
26+
bandwidth = step * (1 - paddingInner);
27+
if (round) start = Math.round(start), bandwidth = Math.round(bandwidth);
28+
var values = sequence(n).map(function(i) { return start + step * i; });
29+
return ordinalRange(reverse ? values.reverse() : values);
30+
}
31+
32+
scale.domain = function(_) {
33+
return arguments.length ? (domain(_), rescale()) : domain();
34+
};
35+
36+
scale.range = function(_) {
37+
return arguments.length ? (range = [+_[0], +_[1]], rescale()) : range.slice();
38+
};
39+
40+
scale.rangeRound = function(_) {
41+
return range = [+_[0], +_[1]], round = true, rescale();
42+
};
43+
44+
scale.bandwidth = function() {
45+
return bandwidth;
46+
};
47+
48+
scale.step = function() {
49+
return step;
50+
};
51+
52+
scale.round = function(_) {
53+
return arguments.length ? (round = !!_, rescale()) : round;
54+
};
55+
56+
scale.padding = function(_) {
57+
return arguments.length ? (paddingInner = paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
58+
};
59+
60+
scale.paddingInner = function(_) {
61+
return arguments.length ? (paddingInner = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
62+
};
63+
64+
scale.paddingOuter = function(_) {
65+
return arguments.length ? (paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingOuter;
66+
};
67+
68+
scale.align = function(_) {
69+
return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align;
70+
};
71+
72+
scale.invertExtent = function(r0, r1) {
73+
var lo = +r0,
74+
hi = arguments.length > 1 ? +r1 : lo,
75+
reverse = range[1] < range[0],
76+
values = reverse ? ordinalRange().reverse() : ordinalRange(),
77+
n = values.length - 1, a, b, t;
78+
79+
// order range inputs, bail if outside of scale range
80+
if (hi < lo) t = lo, lo = hi, hi = t;
81+
if (hi < values[0] || lo > range[1-reverse]) return undefined;
82+
83+
// binary search to index into scale range
84+
a = Math.max(0, bisectRight(values, lo) - 1);
85+
b = lo===hi ? a : bisectRight(values, hi) - 1;
86+
87+
// increment index a if lo is within padding gap
88+
if (lo - values[a] > bandwidth + 1e-10) ++a;
89+
90+
if (reverse) t = a, a = n - b, b = n - t; // map + swap
91+
return (a > b) ? undefined : domain().slice(a, b+1);
92+
};
93+
94+
scale.copy = function() {
95+
return band()
96+
.domain(domain())
97+
.range(range)
98+
.round(round)
99+
.paddingInner(paddingInner)
100+
.paddingOuter(paddingOuter)
101+
.align(align);
102+
};
103+
104+
return rescale();
105+
}
106+
107+
function pointish(scale) {
108+
var copy = scale.copy;
109+
110+
scale.padding = scale.paddingOuter;
111+
delete scale.paddingInner;
112+
delete scale.paddingOuter;
113+
114+
scale.copy = function() {
115+
return pointish(copy());
116+
};
117+
118+
return scale;
119+
}
120+
121+
export function point() {
122+
return pointish(band().paddingInner(1));
123+
}

src/index.js

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import {scaleLinear, scaleSequential} from 'd3-scale';
2+
3+
export default function index(scheme) {
4+
var domain = [],
5+
length = 0,
6+
lookup = {},
7+
interp = scheme ? scaleSequential(scheme) : scaleLinear();
8+
9+
function scale(_) {
10+
if (lookup.hasOwnProperty(_)) return interp(lookup[_]);
11+
}
12+
13+
scale.domain = function(_) {
14+
if (!arguments.length) return domain.slice();
15+
domain = _.slice();
16+
length = domain.length;
17+
lookup = {};
18+
for (var i=0; i<length;) lookup[domain[i]] = i++;
19+
interp.domain([0, length - 1]);
20+
return scale;
21+
};
22+
23+
if (!scheme) {
24+
// sequential scales do not export an invert method
25+
26+
scale.invert = function(_) {
27+
return domain[interp.invert(_)];
28+
};
29+
30+
scale.invertExtent = function(r0, r1) {
31+
if (arguments.length < 2) {
32+
return (t = scale.invert(r0)) !== undefined ? [t] : [];
33+
}
34+
35+
var lo = interp.invert(r0),
36+
hi = interp.invert(r1),
37+
t;
38+
39+
if (lo > hi) t = lo, lo = hi, hi = t;
40+
41+
return (hi < 0 || lo >= length) ? [] : domain.slice(
42+
Math.max(0, Math.ceil(lo)),
43+
Math.min(length, Math.floor(hi) + 1)
44+
);
45+
};
46+
}
47+
48+
(scheme
49+
? ['interpolator']
50+
: ['interpolate', 'range', 'rangeRound'])
51+
.forEach(function(method) {
52+
scale[method] = function() {
53+
var r = interp[method].apply(null, arguments);
54+
return arguments.length ? scale : r;
55+
};
56+
});
57+
58+
scale.copy = function() {
59+
return (scheme
60+
? index(scheme).interpolator(interp.interpolator())
61+
: index().interpolate(interp.interpolate()).range(interp.range())
62+
).domain(domain);
63+
};
64+
65+
return scale;
66+
}

src/scales.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import * as $ from 'd3-scale';
2+
import {default as scaleBand, point as scalePoint} from './band';
3+
import scaleIndex from './index';
4+
5+
var scales = {
6+
// extended scale types
7+
band: scaleBand,
8+
point: scalePoint,
9+
index: scaleIndex,
10+
11+
// base scale types
12+
identity: $.scaleIdentity,
13+
linear: $.scaleLinear,
14+
log: $.scaleLog,
15+
ordinal: $.scaleOrdinal,
16+
pow: $.scalePow,
17+
sqrt: $.scaleSqrt,
18+
quantile: $.scaleQuantile,
19+
quantize: $.scaleQuantize,
20+
threshold: $.scaleThreshold,
21+
time: $.scaleTime,
22+
utc: $.scaleUtc,
23+
sequential: $.scaleSequential
24+
};
25+
26+
export default function(name, scale) {
27+
return arguments.length > 1 ? (scales[name] = scale, this)
28+
: scales.hasOwnProperty(name) ? scales[name] : null;
29+
}

src/schemes.js

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import * as $ from 'd3-scale';
2+
import * as _ from 'd3-scale-chromatic';
3+
4+
var schemes = {
5+
// d3 built-in categorical palettes
6+
category10: $.schemeCategory10,
7+
category20: $.schemeCategory20,
8+
category20b: $.schemeCategory20b,
9+
category20c: $.schemeCategory20c,
10+
11+
// extended categorical palettes
12+
accent: _.schemeAccent,
13+
dark2: _.schemeDark2,
14+
paired: _.schemePaired,
15+
pastel1: _.schemePastel1,
16+
pastel2: _.schemePastel2,
17+
set1: _.schemeSet1,
18+
set2: _.schemeSet2,
19+
set3: _.schemeSet3,
20+
21+
// d3 built-in interpolators
22+
cubehelix: $.interpolateCubehelixDefault,
23+
rainbow: $.interpolateRainbow,
24+
warm: $.interpolateWarm,
25+
cool: $.interpolateCool,
26+
viridis: $.interpolateViridis,
27+
magma: $.interpolateMagma,
28+
inferno: $.interpolateInferno,
29+
plasma: $.interpolatePlasma,
30+
31+
// diverging
32+
brbg: _.interpolateBrBG,
33+
prgn: _.interpolatePRGn,
34+
piyg: _.interpolatePiYG,
35+
puor: _.interpolatePuOr,
36+
rdbu: _.interpolateRdBu,
37+
rdgy: _.interpolateRdGy,
38+
rdylbu: _.interpolateRdYlBu,
39+
rdylgn: _.interpolateRdYlGn,
40+
spectral: _.interpolateSpectral,
41+
42+
// sequential multi-hue
43+
bugn: _.interpolateBuGn,
44+
bupu: _.interpolateBuPu,
45+
gnbu: _.interpolateGnBu,
46+
orrd: _.interpolateOrRd,
47+
pubugn: _.interpolatePuBuGn,
48+
pubu: _.interpolatePuBu,
49+
purd: _.interpolatePuRd,
50+
rdpu: _.interpolateRdPu,
51+
ylgnbu: _.interpolateYlGnBu,
52+
ylgn: _.interpolateYlGn,
53+
ylorbr: _.interpolateYlOrBr,
54+
ylorrd: _.interpolateYlOrRd,
55+
56+
// sequential single-hue
57+
blues: _.interpolateBlues,
58+
greens: _.interpolateGreens,
59+
greys: _.interpolateGreys,
60+
purples: _.interpolatePurples,
61+
reds: _.interpolateReds,
62+
oranges: _.interpolateOranges
63+
};
64+
65+
export default function scheme(name, scheme) {
66+
return arguments.length > 1 ? (schemes[name] = scheme, this)
67+
: schemes.hasOwnProperty(name) ? schemes[name] : null;
68+
}

0 commit comments

Comments
 (0)