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 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | 1 1 1 3 3 7 1 1 3 3 1 1 3 3 1 3 1 1 2 1 2 1 1 1 1 1 1 12 1 1 1 1 1 1 1 | 'use strict'; var util = require('../util'); module.exports = time; function time(spec, encoding, opt) { // FIXME refactor to reduce side effect #276 // jshint unused:false var timeFields = {}, timeUnits = {}; // find unique formula transformation and bin function encoding.forEach(function(field, encType) { if (field.type === T && field.timeUnit) { timeFields[encoding.field(encType)] = { field: field, encType: encType }; timeUnits[field.timeUnit] = true; } }); // add formula transform var data = spec.data[1], transform = data.transform = data.transform || []; for (var f in timeFields) { var tf = timeFields[f]; time.transform(transform, encoding, tf.encType, tf.field); } // add scales var scales = spec.scales = spec.scales || []; for (var timeUnit in timeUnits) { time.scale(scales, timeUnit, encoding); } return spec; } time.cardinality = function(field, stats, filterNull, type) { var timeUnit = field.timeUnit; switch (timeUnit) { case 'seconds': return 60; case 'minutes': return 60; case 'hours': return 24; case 'day': return 7; case 'date': return 31; case 'month': return 12; case 'year': var stat = stats[field.name], yearstat = stats['year_'+field.name]; if (!yearstat) { return null; } return yearstat.distinct - (stat.nulls > 0 && filterNull[type] ? 1 : 0); } return null; }; function fieldFn(func, field) { return 'utc' + func + '(d.data.'+ field.name +')'; } /** * @return {String} date binning formula of the given field */ time.formula = function(field) { return fieldFn(field.timeUnit, field); }; /** add formula transforms to data */ time.transform = function(transform, encoding, encType, field) { transform.push({ type: 'formula', field: encoding.field(encType), expr: time.formula(field) }); }; /** append custom time scales for axis label */ time.scale = function(scales, timeUnit, encoding) { var labelLength = encoding.config('timeScaleLabelLength'); // TODO add option for shorter scale / custom range switch (timeUnit) { case 'day': scales.push({ name: 'time-'+timeUnit, type: 'ordinal', domain: util.range(0, 7), range: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'].map( function(s) { return s.substr(0, labelLength);} ) }); break; case 'month': scales.push({ name: 'time-'+timeUnit, type: 'ordinal', domain: util.range(0, 12), range: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'].map( function(s) { return s.substr(0, labelLength);} ) }); break; } }; time.isOrdinalFn = function(timeUnit) { switch (timeUnit) { case 'seconds': case 'minutes': case 'hours': case 'day': case 'date': case 'month': return true; } return false; }; time.scale.type = function(timeUnit, name) { if (name === COLOR) { return 'linear'; // this has order } return time.isOrdinalFn(timeUnit) || name === COL || name === ROW ? 'ordinal' : 'linear'; }; time.scale.domain = function(timeUnit, name) { var isColor = name === COLOR; switch (timeUnit) { case 'seconds': case 'minutes': return isColor ? [0,59] : util.range(0, 60); case 'hours': return isColor ? [0,23] : util.range(0, 24); case 'day': return isColor ? [0,6] : util.range(0, 7); case 'date': return isColor ? [1,31] : util.range(1, 32); case 'month': return isColor ? [0,11] : util.range(0, 12); } return null; }; /** whether a particular time function has custom scale for labels implemented in time.scale */ time.hasScale = function(timeUnit) { switch (timeUnit) { case 'day': case 'month': return true; } return false; }; |