1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | 1 1 1 1 1 | 'use strict'; require('../globals'); var util = require('../util'); var axis = require('./axis'), groupdef = require('./group').def, scale = require('./scale'); module.exports = faceting; function faceting(group, encoding, layout, style, sorting, spec, mdef, stack, stats) { var enter = group.properties.enter; var facetKeys = [], cellAxes = [], from, axesGrp; var hasRow = encoding.has(ROW), hasCol = encoding.has(COL); enter.fill = {value: encoding.config('cellBackgroundColor')}; //move "from" to cell level and add facet transform group.from = {data: group.marks[0].from.data}; // Hack, this needs to be refactored for (var i = 0; i < group.marks.length; i++) { var mark = group.marks[i]; if (mark.from.transform) { delete mark.from.data; //need to keep transform for subfacetting case } else { delete mark.from; } } if (hasRow) { if (!encoding.isDimension(ROW)) { util.error('Row encoding should be ordinal.'); } enter.y = {scale: ROW, field: 'keys.' + facetKeys.length}; enter.height = {'value': layout.cellHeight}; // HACK facetKeys.push(encoding.field(ROW)); if (hasCol) { from = util.duplicate(group.from); from.transform = from.transform || []; from.transform.unshift({type: 'facet', keys: [encoding.field(COL)]}); } axesGrp = groupdef('x-axes', { axes: encoding.has(X) ? axis.defs(['x'], encoding, layout, stats) : undefined, x: hasCol ? {scale: COL, field: 'keys.0'} : {value: 0}, width: hasCol && {'value': layout.cellWidth}, //HACK? from: from }); spec.marks.unshift(axesGrp); // need to prepend so it appears under the plots (spec.axes = spec.axes || []); spec.axes.push.apply(spec.axes, axis.defs(['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)); } } if (hasCol) { if (!encoding.isDimension(COL)) { util.error('Col encoding should be ordinal.'); } enter.x = {scale: COL, field: 'keys.' + facetKeys.length}; enter.width = {'value': layout.cellWidth}; // HACK facetKeys.push(encoding.field(COL)); if (hasRow) { from = util.duplicate(group.from); from.transform = from.transform || []; from.transform.unshift({type: 'facet', keys: [encoding.field(ROW)]}); } axesGrp = groupdef('y-axes', { axes: encoding.has(Y) ? axis.defs(['y'], encoding, layout, stats) : undefined, y: hasRow && {scale: ROW, field: 'keys.0'}, x: hasRow && {value: 0}, height: hasRow && {'value': layout.cellHeight}, //HACK? from: from }); spec.marks.unshift(axesGrp); // need to prepend so it appears under the plots (spec.axes = spec.axes || []); spec.axes.push.apply(spec.axes, axis.defs(['col'], encoding, layout, stats)); } else { // doesn't have col if (encoding.has(Y)) { cellAxes.push.apply(cellAxes, axis.defs(['y'], encoding, layout, stats)); } } // assuming equal cellWidth here // TODO: support heterogenous cellWidth (maybe by using multiple scales?) spec.scales = (spec.scales || []).concat(scale.defs( scale.names(enter).concat(scale.names(mdef.properties.update)), encoding, layout, stats, style, sorting, {stack: stack, facet: true} )); // row/col scales + cell scales if (cellAxes.length > 0) { group.axes = cellAxes; } // add facet transform var trans = (group.from.transform || (group.from.transform = [])); trans.unshift({type: 'facet', keys: facetKeys}); return spec; } |