vega-lite
Advanced tools
Comparing version 0.7.11 to 0.7.12
{ | ||
"name": "vega-lite", | ||
"main": "vega-lite.js", | ||
"version": "0.7.11", | ||
"version": "0.7.12", | ||
"homepage": "https://github.com/uwdata/vega-lite", | ||
@@ -6,0 +6,0 @@ "authors": [ |
@@ -69,3 +69,3 @@ 'use strict'; | ||
row: {type: 'O',name: 'site'}, | ||
color: {type: 'O',name: 'year'} | ||
color: {type: 'N',name: 'year'} | ||
} | ||
@@ -110,2 +110,14 @@ } | ||
} | ||
},{ | ||
title: 'Text Heatmap', | ||
spec: { | ||
'marktype': 'text', | ||
'encoding': { | ||
'row': {'name': 'Origin','type': 'O'}, | ||
'col': {'axis': {'maxLabelLength': 25},'name': 'Cylinders','type': 'O'}, | ||
'color': {'name': 'Horsepower','type': 'Q','aggregate': 'avg'}, | ||
'text': {'name': '*','type': 'Q','aggregate': 'count'} | ||
}, | ||
'data': {'url': 'data/cars.json'} | ||
} | ||
} | ||
@@ -112,0 +124,0 @@ ]; |
{ | ||
"name": "vega-lite", | ||
"author": "Jeffrey Heer, Dominik Moritz, Kanit \"Ham\" Wongsuphasawat", | ||
"version": "0.7.11", | ||
"version": "0.7.12", | ||
"collaborators": [ | ||
@@ -6,0 +6,0 @@ "Kanit Wongsuphasawat <kanitw@gmail.com> (http://kanitw.yellowpigz.com)", |
@@ -12,17 +12,2 @@ 'use strict'; | ||
axis.names = function(props) { | ||
return util.keys(util.keys(props).reduce(function(a, x) { | ||
var s = props[x].scale; | ||
if (s === X || s === Y) a[props[x].scale] = 1; | ||
return a; | ||
}, {})); | ||
}; | ||
axis.defs = function(names, encoding, layout, stats, opt) { | ||
return names.reduce(function(a, name) { | ||
a.push(axis.def(name, encoding, layout, stats, opt)); | ||
return a; | ||
}, []); | ||
}; | ||
axis.def = function(name, encoding, layout, stats, opt) { | ||
@@ -29,0 +14,0 @@ var isCol = name == COL, |
@@ -61,5 +61,4 @@ 'use strict'; | ||
group = spec.marks[0], | ||
mark = marks[encoding.marktype()], | ||
mdefs = marks.def(mark, encoding, layout, style, stats), | ||
mdef = mdefs[0]; // TODO: remove this dirty hack by refactoring the whole flow | ||
mdefs = marks.def(encoding, layout, style, stats), | ||
mdef = mdefs[mdefs.length - 1]; // TODO: remove this dirty hack by refactoring the whole flow | ||
@@ -92,10 +91,19 @@ for (var i = 0; i < mdefs.length; i++) { | ||
// get a flattened list of all scale names that are used in the vl spec | ||
var singleScaleNames = [].concat.apply([], mdefs.map(function(markProps) { | ||
return scale.names(markProps.properties.update); | ||
})); | ||
// Small Multiples | ||
if (encoding.has(ROW) || encoding.has(COL)) { | ||
spec = compiler.facet(group, encoding, layout, style, sorting, spec, mdef, stack, stats); | ||
spec.legends = legend.defs(encoding); | ||
spec = compiler.facet(group, encoding, layout, style, sorting, spec, singleScaleNames, stack, stats); | ||
spec.legends = legend.defs(encoding, style); | ||
} else { | ||
group.scales = scale.defs(scale.names(mdef.properties.update), encoding, layout, stats, style, sorting, {stack: stack}); | ||
group.axes = axis.defs(axis.names(mdef.properties.update), encoding, layout, stats); | ||
group.legends = legend.defs(encoding); | ||
group.scales = scale.defs(singleScaleNames, encoding, layout, stats, style, sorting, {stack: stack}); | ||
group.axes = []; | ||
if (encoding.has(X)) group.axes.push(axis.def(X, encoding, layout, stats)); | ||
if (encoding.has(Y)) group.axes.push(axis.def(Y, encoding, layout, stats)); | ||
group.legends = legend.defs(encoding, style); | ||
} | ||
@@ -102,0 +110,0 @@ |
@@ -13,3 +13,3 @@ 'use strict'; | ||
function faceting(group, encoding, layout, style, sorting, spec, mdef, stack, stats) { | ||
function faceting(group, encoding, layout, style, sorting, spec, singleScaleNames, stack, stats) { | ||
var enter = group.properties.enter; | ||
@@ -51,3 +51,3 @@ var facetKeys = [], cellAxes = [], from, axesGrp; | ||
axesGrp = groupdef('x-axes', { | ||
axes: encoding.has(X) ? axis.defs(['x'], encoding, layout, stats) : undefined, | ||
axes: encoding.has(X) ? [axis.def(X, encoding, layout, stats)] : undefined, | ||
x: hasCol ? {scale: COL, field: 'keys.0'} : {value: 0}, | ||
@@ -60,7 +60,7 @@ width: hasCol && {'value': layout.cellWidth}, //HACK? | ||
(spec.axes = spec.axes || []); | ||
spec.axes.push.apply(spec.axes, axis.defs(['row'], encoding, layout, stats)); | ||
spec.axes.push(axis.def(ROW, encoding, layout, stats)); | ||
} else { // doesn't have row | ||
if (encoding.has(X)) { | ||
//keep x axis in the cell | ||
cellAxes.push.apply(cellAxes, axis.defs(['x'], encoding, layout, stats)); | ||
cellAxes.push(axis.def(X, encoding, layout, stats)); | ||
} | ||
@@ -85,3 +85,3 @@ } | ||
axesGrp = groupdef('y-axes', { | ||
axes: encoding.has(Y) ? axis.defs(['y'], encoding, layout, stats) : undefined, | ||
axes: encoding.has(Y) ? [axis.def(Y, encoding, layout, stats)] : undefined, | ||
y: hasRow && {scale: ROW, field: 'keys.0'}, | ||
@@ -95,6 +95,6 @@ x: hasRow && {value: 0}, | ||
(spec.axes = spec.axes || []); | ||
spec.axes.push.apply(spec.axes, axis.defs(['col'], encoding, layout, stats)); | ||
spec.axes.push(axis.def(COL, encoding, layout, stats)); | ||
} else { // doesn't have col | ||
if (encoding.has(Y)) { | ||
cellAxes.push.apply(cellAxes, axis.defs(['y'], encoding, layout, stats)); | ||
cellAxes.push(axis.def(Y, encoding, layout, stats)); | ||
} | ||
@@ -106,3 +106,3 @@ } | ||
spec.scales = (spec.scales || []).concat(scale.defs( | ||
scale.names(enter).concat(scale.names(mdef.properties.update)), | ||
scale.names(enter).concat(singleScaleNames), | ||
encoding, | ||
@@ -109,0 +109,0 @@ layout, |
@@ -5,9 +5,11 @@ 'use strict'; | ||
var time = require('./time'); | ||
var time = require('./time'), | ||
util = require('../util'), | ||
setter = util.setter, | ||
getter = util.getter; | ||
var legend = module.exports = {}; | ||
legend.defs = function(encoding) { | ||
legend.defs = function(encoding, style) { | ||
var defs = []; | ||
// TODO: support alpha | ||
@@ -18,3 +20,3 @@ if (encoding.has(COLOR) && encoding.field(COLOR).legend) { | ||
orient: 'right' | ||
})); | ||
}, style)); | ||
} | ||
@@ -26,3 +28,3 @@ | ||
orient: defs.length === 1 ? 'left' : 'right' | ||
})); | ||
}, style)); | ||
} | ||
@@ -32,5 +34,3 @@ | ||
if (defs.length === 2) { | ||
// TODO: fix this | ||
console.error('Vega-lite currently only supports two legends'); | ||
return defs; | ||
} | ||
@@ -40,13 +40,12 @@ defs.push(legend.def(SHAPE, encoding, { | ||
orient: defs.length === 1 ? 'left' : 'right' | ||
})); | ||
}, style)); | ||
} | ||
return defs; | ||
}; | ||
legend.def = function(name, encoding, props) { | ||
var def = props, | ||
timeUnit = encoding.field(name).timeUnit; | ||
legend.def = function(name, encoding, def, style) { | ||
var timeUnit = encoding.field(name).timeUnit; | ||
def.title = encoding.fieldTitle(name); | ||
def = legend.style(name, encoding, def, style); | ||
@@ -57,10 +56,55 @@ if (encoding.isType(name, T) && | ||
) { | ||
var properties = def.properties = def.properties || {}, | ||
labels = properties.labels = properties.labels || {}, | ||
text = labels.text = labels.text || {}; | ||
setter(def, ['properties', 'labels', 'text', 'scale'], 'time-'+ timeUnit); | ||
} | ||
text.scale = 'time-'+ timeUnit; | ||
return def; | ||
}; | ||
legend.style = function(name, e, def, style) { | ||
var symbols = getter(def, ['properties', 'symbols']), | ||
marktype = e.marktype(); | ||
switch (marktype) { | ||
case 'bar': | ||
case 'tick': | ||
case 'text': | ||
symbols.stroke = {value: 'transparent'}; | ||
symbols.shape = {value: 'square'}; | ||
break; | ||
case 'circle': | ||
case 'square': | ||
symbols.shape = {value: marktype}; | ||
/* fall through */ | ||
case 'point': | ||
// fill or stroke | ||
if (e.field(SHAPE).filled) { | ||
if (e.has(COLOR) && name === COLOR) { | ||
symbols.fill = {scale: COLOR, field: 'data'}; | ||
} else { | ||
symbols.fill = {value: e.value(COLOR)}; | ||
} | ||
symbols.stroke = {value: 'transparent'}; | ||
} else { | ||
if (e.has(COLOR) && name === COLOR) { | ||
symbols.stroke = {scale: COLOR, field: 'data'}; | ||
} else { | ||
symbols.stroke = {value: e.value(COLOR)}; | ||
} | ||
symbols.fill = {value: 'transparent'}; | ||
symbols.strokeWidth = {value: e.config('strokeWidth')}; | ||
} | ||
break; | ||
case 'line': | ||
case 'area': | ||
// TODO use shape here after implementing #508 | ||
break; | ||
} | ||
var opacity = e.field(COLOR).opacity || style.opacity; | ||
if (opacity) { | ||
symbols.opacity = {value: opacity}; | ||
} | ||
return def; | ||
}; | ||
}; |
@@ -7,5 +7,7 @@ 'use strict'; | ||
marks.def = function(mark, encoding, layout, style, stats) { | ||
var defs = []; | ||
marks.def = function(encoding, layout, style, stats) { | ||
var defs = [], | ||
mark = marks[encoding.marktype()]; | ||
// to add a background to text, we need to add it before the text | ||
@@ -194,3 +196,3 @@ if (encoding.marktype() === TEXT && encoding.has(COLOR)) { | ||
// stroke | ||
// fill or stroke | ||
if (e.field(SHAPE).filled) { | ||
@@ -212,3 +214,3 @@ if (e.has(COLOR)) { | ||
// opacity | ||
var opacity = e.field(COLOR).opacity || style.opacity; | ||
var opacity = e.field(COLOR).opacity || style.opacity; | ||
if (opacity) p.opacity = {value: opacity}; | ||
@@ -415,3 +417,3 @@ | ||
// color should be set to background | ||
p.fill = {value: field.text.color}; | ||
p.fill = {value: field.color}; | ||
@@ -424,3 +426,3 @@ var opacity = e.field(COLOR).opacity || style.opacity; | ||
if (e.isType(TEXT, Q)) { | ||
var fieldStats = stats[e.fieldName(name)], | ||
var fieldStats = stats[e.fieldName(TEXT)], | ||
numberFormat = field.format || e.numberFormat(fieldStats); | ||
@@ -427,0 +429,0 @@ |
@@ -6,3 +6,3 @@ 'use strict'; | ||
colorbrewer = require('colorbrewer'), | ||
interpolateLab = require('d3-color').interpolateLab, | ||
interpolate = require('d3-color').interpolateHsl, | ||
schema = require('../schema/schema'); | ||
@@ -188,2 +188,3 @@ | ||
s.range = scale.color(s, encoding, stats); | ||
if (s.type !== 'ordinal') s.zero = false; | ||
break; | ||
@@ -194,2 +195,3 @@ default: | ||
// FIXME(kanitw): Jul 29, 2015 - consolidate this with above | ||
switch (s.name) { | ||
@@ -217,3 +219,5 @@ case ROW: | ||
if (range === undefined) { | ||
var ordinalPalette = colorScale.ordinalPalette; | ||
var ordinalPalette = colorScale.ordinalPalette, | ||
quantitativeRange = colorScale.quantitativeRange; | ||
if (s.type === 'ordinal') { | ||
@@ -227,19 +231,17 @@ if (type === N) { | ||
} | ||
return scale.color.palette(range, cardinality, type); | ||
} else { | ||
if (cardinality <= 2) { | ||
range = [colorbrewer[ordinalPalette][3][0], colorbrewer[ordinalPalette][3][2]]; | ||
} else { | ||
range = ordinalPalette; | ||
if (ordinalPalette) { | ||
return scale.color.palette(ordinalPalette, cardinality, type); | ||
} | ||
return scale.color.interpolate(quantitativeRange[0], quantitativeRange[1], cardinality); | ||
} | ||
} else { //time or quantitative | ||
var palette = colorbrewer[ordinalPalette][9]; | ||
range = [palette[0], palette[8]]; | ||
s.zero = false; | ||
return [quantitativeRange[0], quantitativeRange[1]]; | ||
} | ||
} | ||
return scale.color.palette(range, cardinality, type); | ||
}; | ||
scale.color.palette = function(range, cardinality, type) { | ||
// FIXME(kanitw): Jul 29, 2015 - check range is string | ||
switch (range) { | ||
@@ -265,5 +267,6 @@ case 'category10k': | ||
// TODO add our own set of custom ordinal color palette | ||
if (range in colorbrewer) { | ||
var palette = colorbrewer[range], | ||
ps = 5; | ||
var palette = colorbrewer[range]; | ||
@@ -279,3 +282,7 @@ // if cardinality pre-defined, use it. | ||
// otherwise, interpolate | ||
return scale.color.interpolate(palette[ps][0], palette[ps][ps-1], cardinality); | ||
var ps = cardinality < 3 ? 3 : Math.max.apply(null, util.keys(palette)), | ||
from = 0 , to = ps - 1; | ||
// FIXME add config for from / to | ||
return scale.color.interpolate(palette[ps][from], palette[ps][to], cardinality); | ||
} | ||
@@ -287,4 +294,5 @@ | ||
scale.color.interpolate = function (start, end, cardinality) { | ||
var interpolator = interpolateLab(start, end); | ||
var interpolator = interpolate(start, end); | ||
return util.range(cardinality).map(function(i) { return interpolator(i*1.0/(cardinality-1)); }); | ||
}; |
@@ -13,2 +13,3 @@ 'use strict'; | ||
// TODO(kanitw): Jul 22, 2015 - split this file into data and template | ||
var data = {name: RAW, format: {}}, | ||
@@ -15,0 +16,0 @@ table = {name: TABLE, source: RAW}, |
@@ -148,3 +148,4 @@ 'use strict'; | ||
if (fn) { | ||
return fn.toUpperCase() + '(' + this._enc[et].name + ')'; | ||
var uppercase = fn === 'avg' ? 'MEAN' :fn.toUpperCase(); | ||
return uppercase + '(' + this._enc[et].name + ')'; | ||
} else { | ||
@@ -151,0 +152,0 @@ return this._enc[et].name; |
@@ -363,2 +363,3 @@ // Package of defining Vega-lite Specification's json schema | ||
'to pick one from c10palette, c20palette, or ordinalPalette' | ||
//FIXME | ||
}, | ||
@@ -382,4 +383,13 @@ c10palette: { | ||
type: 'string', | ||
default: 'BuGn', | ||
default: undefined, | ||
enum: util.keys(colorbrewer) | ||
}, | ||
quantitativeRange: { | ||
type: 'array', | ||
default: ['#AFC6A3', '#09622A'], // tableau greens | ||
// default: ['#ccece6', '#00441b'], // BuGn.9 [2-8] | ||
items: { | ||
type: 'string', | ||
role: 'color' | ||
} | ||
} | ||
@@ -386,0 +396,0 @@ } |
@@ -20,3 +20,4 @@ 'use strict'; | ||
vl.toShorthand = vl.Encoding.shorthand; | ||
vl.format = require('d3-format').format; | ||
module.exports = vl; |
@@ -220,5 +220,5 @@ 'use strict'; | ||
var cardinality = 20, | ||
ps = 5, | ||
p = colorbrewer[palette], | ||
interpolator = d3.interpolateLab(p[ps][0], p[ps][ps - 1]); | ||
ps = Math.max.apply(null, util.keys(p)), | ||
interpolator = d3.interpolateHsl(p[ps][0], p[ps][ps - 1]); | ||
expect(vlscale.color.palette(palette, cardinality, 'O')).to.eql( | ||
@@ -234,4 +234,4 @@ util.range(cardinality).map(function(i) { | ||
describe('color.interpolate', function() { | ||
it('should interpolate color along the lab space', function() { | ||
var interpolator = d3.interpolateLab('#ffffff', '#000000'), | ||
it('should interpolate color along the hsl space', function() { | ||
var interpolator = d3.interpolateHsl('#ffffff', '#000000'), | ||
cardinality = 8; | ||
@@ -238,0 +238,0 @@ |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
7517889
120020