-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
1,802 additions
and
1 deletion.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import { | ||
interval, line, area, text, link, cell, rect, point, path, | ||
} from '../geometry'; | ||
import { | ||
createBand, | ||
createIdentity, | ||
createLinear, | ||
createLog, | ||
createOrdinal, | ||
createPoint, | ||
createQuantile, | ||
createQuantize, | ||
createThreshold, | ||
createTime, | ||
} from '../scale'; | ||
import { | ||
axisX, axisY, legendRamp, legendSwatches, | ||
} from '../guide'; | ||
import { cartesian, transpose, polar } from '../coordinate'; | ||
import { | ||
createBinX, createNormalizeY, createSymmetryY, createStackY, | ||
} from '../statistic'; | ||
|
||
export function create(options) { | ||
if (typeof options === 'function') return options; | ||
const { type, ...rest } = options; | ||
|
||
// geometries | ||
if (type === 'interval') return interval; | ||
if (type === 'line') return line; | ||
if (type === 'area') return area; | ||
if (type === 'text') return text; | ||
if (type === 'link') return link; | ||
if (type === 'cell') return cell; | ||
if (type === 'rect') return rect; | ||
if (type === 'point') return point; | ||
if (type === 'path') return path; | ||
|
||
// facet | ||
if (type === 'facet') { | ||
const facet = () => {}; | ||
facet.channels = () => ({ | ||
x: { name: 'x', optional: true }, | ||
y: { name: 'y', optional: true }, | ||
}); | ||
return facet; | ||
} | ||
|
||
// statistics | ||
if (type === 'stackY') return createStackY(rest); | ||
if (type === 'normalizeY') return createNormalizeY(rest); | ||
if (type === 'symmetryY') return createSymmetryY(rest); | ||
if (type === 'binX') return createBinX(rest); | ||
|
||
// coordinates | ||
if (type === 'cartesian') return cartesian(rest); | ||
if (type === 'transpose') return transpose(rest); | ||
if (type === 'polar') return polar(rest); | ||
|
||
// scales | ||
if (type === 'band') return createBand(rest); | ||
if (type === 'linear') return createScaleQ(createLinear, rest); | ||
if (type === 'time') return createScaleQ(createTime, rest); | ||
if (type === 'log') return createScaleQ(createLog, rest); | ||
if (type === 'identity') return createIdentity(rest); | ||
if (type === 'ordinal') return createOrdinal(rest); | ||
if (type === 'dot') return createPoint(rest); | ||
if (type === 'quantile') return createQuantile(rest); | ||
if (type === 'quantize') return createQuantize(rest); | ||
if (type === 'threshold') return createThreshold(rest); | ||
|
||
// guides | ||
if (type === 'axisX') return createGuide(axisX, rest); | ||
if (type === 'axisY') return createGuide(axisY, rest); | ||
if (type === 'legendSwatches') return createGuide(legendSwatches, rest); | ||
if (type === 'legendRamp') return createGuide(legendRamp, rest); | ||
|
||
throw new Error(`Unknown node type: ${options.type}`); | ||
} | ||
|
||
function createGuide(guide, options) { | ||
return (renderer, scale, coordinate) => guide(renderer, scale, coordinate, options); | ||
} | ||
|
||
function createScaleQ(ctor, options) { | ||
const { nice = true, tickCount = 10 } = options; | ||
const scale = ctor(options); | ||
if (nice) scale.nice(tickCount); | ||
return scale; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import { firstOf, map } from '../utils'; | ||
import { categoricalColors } from './theme'; | ||
|
||
export function inferEncodings(type, data, encodings) { | ||
const typedEncodings = map(encodings, (encoding, key) => ({ | ||
type: inferType(data, encoding, key), | ||
value: encoding, | ||
})); | ||
|
||
switch (type) { | ||
case 'interval': | ||
return maybeFill(maybeZeroX(maybeZeroY1(typedEncodings))); | ||
case 'line': | ||
return maybeStroke(maybeGroup(typedEncodings)); | ||
case 'area': | ||
return maybeFill(maybeIdentityX(maybeZeroY1(maybeGroup(typedEncodings)))); | ||
case 'link': | ||
return maybeStroke(maybeIdentityX(typedEncodings)); | ||
case 'point': | ||
return maybeZeroY(maybeStroke(typedEncodings)); | ||
case 'rect': | ||
return maybeFill(maybeZeroX1(maybeZeroY1(typedEncodings))); | ||
case 'cell': | ||
return maybeFill(typedEncodings); | ||
default: | ||
break; | ||
} | ||
|
||
return typedEncodings; | ||
} | ||
|
||
export function valueOf(data, { type, value }) { | ||
if (type === 'transform') return data.map(value); | ||
if (type === 'value') return data.map(() => value); | ||
return data.map((d) => d[value]); | ||
} | ||
|
||
function inferType(data, encoding, name) { | ||
if (typeof encoding === 'function') return 'transform'; | ||
if (typeof encoding === 'string') { | ||
if (data.length && firstOf(data)[encoding] !== undefined) return 'field'; | ||
if (isStyle(name)) return 'constant'; | ||
} | ||
return 'value'; | ||
} | ||
|
||
function isStyle(type) { | ||
return type === 'fill' || type === 'stroke'; | ||
} | ||
|
||
function maybeFill({ fill = color(), ...rest }) { | ||
return { fill, ...rest }; | ||
} | ||
|
||
function maybeStroke({ stroke = color(), ...rest }) { | ||
return { stroke, ...rest }; | ||
} | ||
|
||
function maybeZeroY1({ y1 = zero(), ...rest }) { | ||
return { y1, ...rest }; | ||
} | ||
|
||
function maybeZeroX1({ x1 = zero(), ...rest }) { | ||
return { x1, ...rest }; | ||
} | ||
|
||
function maybeZeroY({ y = zero(), ...rest }) { | ||
return { y, ...rest }; | ||
} | ||
|
||
function maybeZeroX({ x = zero(), ...rest }) { | ||
return { x, ...rest }; | ||
} | ||
|
||
function maybeIdentityX({ x, x1 = x, ...rest }) { | ||
return { x, x1, ...rest }; | ||
} | ||
|
||
function maybeGroup({ | ||
fill, stroke, z, ...rest | ||
}) { | ||
if (z === undefined) z = maybeField(fill); | ||
if (z === undefined) z = maybeField(stroke); | ||
return { | ||
fill, stroke, z, ...rest, | ||
}; | ||
} | ||
|
||
function maybeField(encoding) { | ||
if (encoding === undefined || encoding.type !== 'field') return undefined; | ||
return encoding; | ||
} | ||
|
||
function zero() { | ||
return { type: 'value', value: 0 }; | ||
} | ||
|
||
function color() { | ||
return { type: 'constant', value: categoricalColors[0] }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { compose, indexOf } from '../utils'; | ||
import { inferEncodings, valueOf } from './encoding'; | ||
import { create } from './create'; | ||
|
||
export function initialize({ | ||
data, | ||
type, | ||
encodings: E = {}, | ||
statistics: statisticsOptions = [], | ||
transforms: transformsOptions = [], | ||
styles, | ||
}) { | ||
// apply transform | ||
const transform = compose(...transformsOptions.map(create)); | ||
const transformedData = transform(data); | ||
const index = indexOf(transformedData); | ||
|
||
// apply valueOf | ||
const encodings = inferEncodings(type, transformedData, E); | ||
const constants = {}; | ||
const values = {}; | ||
for (const [key, e] of Object.entries(encodings)) { | ||
if (e) { | ||
const { type, value } = e; | ||
if (type === 'constant') constants[key] = value; | ||
else values[key] = valueOf(transformedData, e); | ||
} | ||
} | ||
|
||
// apply statistics | ||
const statistic = compose(...statisticsOptions.map(create)); | ||
const { values: transformedValues, index: I } = statistic({ index, values }); | ||
|
||
// create channels | ||
const geometry = create({ type }); | ||
const channels = {}; | ||
for (const [key, channel] of Object.entries(geometry.channels())) { | ||
const values = transformedValues[key]; | ||
const { optional } = channel; | ||
if (values) { | ||
channels[key] = createChannel(channel, values, encodings[key]); | ||
} else if (!optional) { | ||
throw new Error(`Missing values for channel: ${key}`); | ||
} | ||
} | ||
|
||
return { | ||
index: I, geometry, channels, styles: { ...styles, ...constants }, | ||
}; | ||
} | ||
|
||
function createChannel(channel, values, encoding = {}) { | ||
const { type, value } = encoding; | ||
return { | ||
...channel, | ||
...(type === 'field' && { field: value }), | ||
values, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
export function inferGuides(scales, dimensions, options) { | ||
const { x: xScale, y: yScale, color: colorScale } = scales; | ||
const { x = {}, y = {}, color = {} } = options; | ||
const { display: dx = true } = x; | ||
const { display: dy = true } = y; | ||
const { display: dc = true } = color; | ||
|
||
return { | ||
...(dx && xScale && { x: { ...merge(x, xScale), type: 'axisX' } }), | ||
...(dy && yScale && { y: { ...merge(y, yScale), type: 'axisY' } }), | ||
...(dc && colorScale && { | ||
color: { | ||
...merge(color, colorScale), | ||
...inferPosition(dimensions), | ||
type: inferLegendType(colorScale), | ||
}, | ||
}), | ||
}; | ||
} | ||
|
||
function merge(options, { domain, label }) { | ||
return { ...options, domain, label }; | ||
} | ||
|
||
function inferLegendType({ type }) { | ||
switch (type) { | ||
case 'linear': case 'log': case 'time': | ||
case 'threshold': case 'quantile': case 'quantize': | ||
return 'legendRamp'; | ||
default: | ||
return 'legendSwatches'; | ||
} | ||
} | ||
|
||
function inferPosition({ x, y, paddingLeft }) { | ||
return { x: x + paddingLeft, y }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { plot } from './plot'; |
Oops, something went wrong.