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 | 1 1 1 1 2 2 2 1 2 2 2 2 2 2 1 1 2 2 1 1 2 2 2 2 1 3 1 2 4 4 2 2 2 2 1 1 4 2 | 'use strict'; require('../globals'); var util = require('../util'), setter = util.setter; module.exports = vllayout; function vllayout(encoding, stats) { var layout = box(encoding, stats); layout = offset(encoding, stats, layout); return layout; } /* HACK to set chart size NOTE: this fails for plots driven by derived values (e.g., aggregates) One solution is to update Vega to support auto-sizing In the meantime, auto-padding (mostly) does the trick */ function box(encoding, stats) { var hasRow = encoding.has(ROW), hasCol = encoding.has(COL), hasX = encoding.has(X), hasY = encoding.has(Y), marktype = encoding.marktype(); // FIXME/HACK we need to take filter into account var xCardinality = hasX && encoding.isDimension(X) ? encoding.cardinality(X, stats) : 1, yCardinality = hasY && encoding.isDimension(Y) ? encoding.cardinality(Y, stats) : 1; var useSmallBand = xCardinality > encoding.config('largeBandMaxCardinality') || yCardinality > encoding.config('largeBandMaxCardinality'); var cellWidth, cellHeight, cellPadding = encoding.config('cellPadding'); // set cellWidth Eif (hasX) { if (encoding.isOrdinalScale(X)) { // for ordinal, hasCol or not doesn't matter -- we scale based on cardinality cellWidth = (xCardinality + encoding.band(X).padding) * encoding.bandSize(X, useSmallBand); } else { cellWidth = hasCol || hasRow ? encoding.enc(COL).width : encoding.config('singleWidth'); } } else { if (marktype === TEXT) { cellWidth = encoding.config('textCellWidth'); } else { cellWidth = encoding.bandSize(X); } } // set cellHeight Eif (hasY) { if (encoding.isOrdinalScale(Y)) { // for ordinal, hasCol or not doesn't matter -- we scale based on cardinality cellHeight = (yCardinality + encoding.band(Y).padding) * encoding.bandSize(Y, useSmallBand); } else { cellHeight = hasCol || hasRow ? encoding.enc(ROW).height : encoding.config('singleHeight'); } } else { cellHeight = encoding.bandSize(Y); } // Cell bands use rangeBands(). There are n-1 padding. Outerpadding = 0 for cells var width = cellWidth, height = cellHeight; Iif (hasCol) { var colCardinality = encoding.cardinality(COL, stats); width = cellWidth * ((1 + cellPadding) * (colCardinality - 1) + 1); } Iif (hasRow) { var rowCardinality = encoding.cardinality(ROW, stats); height = cellHeight * ((1 + cellPadding) * (rowCardinality - 1) + 1); } return { // width and height of the whole cell cellWidth: cellWidth, cellHeight: cellHeight, cellPadding: cellPadding, // width and height of the chart width: width, height: height, // information about x and y, such as band size x: {useSmallBand: useSmallBand}, y: {useSmallBand: useSmallBand} }; } function getMaxLength(encoding, stats, et) { // FIXME determine constant for Q and T in a nicer way return encoding.isType(et, Q) ? 5 : encoding.isType(et, T) ? 20 : stats[encoding.fieldName(et)].max; // FIXME this must be max length, not max number } function offset(encoding, stats, layout) { [X, Y].forEach(function (x) { var maxLength; if (encoding.isDimension(x) || encoding.isType(x, T)) { maxLength = getMaxLength(encoding, stats, x); } else Iif (encoding.aggregate(x) === 'count') { //assign default value for count as it won't have stats maxLength = 5; } else Eif (encoding.isType(x, Q)) { if (x===X) { maxLength = 3; } else { // Y //assume that default formating is always shorter than 7 maxLength = Math.min(getMaxLength(encoding, stats, x), 7); } } setter(layout,[x, 'axisTitleOffset'], encoding.config('characterWidth') * maxLength + 20); }); return layout; } |