victory-chart
Version:
Chart Component for Victory
203 lines (182 loc) • 8.14 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _flatten = require("lodash/flatten");
var _flatten2 = _interopRequireDefault(_flatten);
var _includes = require("lodash/includes");
var _includes2 = _interopRequireDefault(_includes);
var _data = require("./data");
var _data2 = _interopRequireDefault(_data);
var _axis = require("./axis");
var _axis2 = _interopRequireDefault(_axis);
var _victoryCore = require("victory-core");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
exports.default = {
getDomain: function getDomain(props, axis) {
var propsDomain = this.getDomainFromProps(props, axis);
if (propsDomain) {
return propsDomain;
}
var dataset = _data2.default.getData(props);
return this.getDomainFromData(dataset, axis);
},
getDomainWithZero: function getDomainWithZero(props, axis) {
var propsDomain = this.getDomainFromProps(props, axis);
if (propsDomain) {
return propsDomain;
}
var ensureZero = function ensureZero(domain) {
return axis === "y" ? [Math.min.apply(Math, _toConsumableArray(domain).concat([0])), Math.max.apply(Math, _toConsumableArray(domain).concat([0]))] : domain;
};
var categoryDomain = this.getDomainFromCategories(props, axis);
if (categoryDomain) {
return ensureZero(categoryDomain);
}
var dataset = _data2.default.getData(props);
return ensureZero(this.getDomainFromData(dataset, axis));
},
getDomainFromProps: function getDomainFromProps(props, axis) {
if (props.domain && props.domain[axis]) {
return props.domain[axis];
} else if (props.domain && Array.isArray(props.domain)) {
return props.domain;
}
},
getDomainFromData: function getDomainFromData(dataset, axis) {
var allData = (0, _flatten2.default)(dataset).map(function (datum) {
return datum[axis];
});
var min = Math.min.apply(Math, _toConsumableArray(allData));
var max = Math.max.apply(Math, _toConsumableArray(allData));
// TODO: is this the correct behavior, or should we just error. How do we
// handle charts with just one data point?
if (min === max) {
var adjustedMax = max === 0 ? 1 : max;
return [0, adjustedMax];
}
return [min, max];
},
getDomainFromTickValues: function getDomainFromTickValues(props) {
var domain = void 0;
if (_axis2.default.stringTicks(props)) {
domain = [1, props.tickValues.length];
} else {
// coerce ticks to numbers
var ticks = props.tickValues.map(function (value) {
return +value;
});
domain = [Math.min.apply(Math, _toConsumableArray(ticks)), Math.max.apply(Math, _toConsumableArray(ticks))];
}
if (_axis2.default.isVertical(props)) {
domain.reverse();
}
return domain;
},
getDomainFromCategories: function getDomainFromCategories(props, axis) {
var categories = _data2.default.getCategories(props, axis);
if (!categories) {
return undefined;
}
var stringArray = _victoryCore.Collection.containsStrings(categories) ? _data2.default.getStringsFromCategories(props, axis) : [];
var stringMap = stringArray.length === 0 ? null : stringArray.reduce(function (memo, string, index) {
memo[string] = index + 1;
return memo;
}, {});
var categoryValues = stringMap ? categories.map(function (value) {
return stringMap[value];
}) : categories;
return [Math.min.apply(Math, _toConsumableArray(categoryValues)), Math.max.apply(Math, _toConsumableArray(categoryValues))];
},
getDomainFromGroupedData: function getDomainFromGroupedData(props, axis, datasets) {
if (axis === "x" && props.categories) {
return this.getDomainFromCategories(props, axis);
}
var globalDomain = this.getDomainFromData(datasets, axis);
// find the cumulative max for stacked chart types
var cumulativeData = axis === "y" ? this.getCumulativeData(datasets, axis) : [];
var cumulativeMaxArray = cumulativeData.map(function (dataset) {
return dataset.reduce(function (memo, val) {
return val > 0 ? memo + val : memo;
}, 0);
});
var cumulativeMinArray = cumulativeData.map(function (dataset) {
return dataset.reduce(function (memo, val) {
return val < 0 ? memo + val : memo;
}, 0);
});
var cumulativeMin = Math.min.apply(Math, _toConsumableArray(cumulativeMinArray));
// use greatest min / max
var domainMin = cumulativeMin < 0 ? cumulativeMin : Math.min.apply(Math, _toConsumableArray(globalDomain));
var domainMax = Math.max.apply(Math, _toConsumableArray(globalDomain).concat(_toConsumableArray(cumulativeMaxArray)));
// TODO: is this the correct behavior, or should we just error. How do we
// handle charts with just one data point?
if (domainMin === domainMax) {
var adjustedMax = domainMax === 0 ? 1 : domainMax;
return [0, adjustedMax];
}
return [domainMin, domainMax];
},
getCumulativeData: function getCumulativeData(datasets, axis) {
var categories = [];
var axisValues = [];
datasets.forEach(function (dataset) {
dataset.forEach(function (data) {
if (data.category !== undefined && !(0, _includes2.default)(categories, data.category)) {
categories.push(data.category);
} else if (!(0, _includes2.default)(axisValues, data[axis])) {
axisValues.push(data[axis]);
}
});
});
var _dataByCategory = function _dataByCategory() {
return categories.map(function (value) {
return datasets.reduce(function (prev, data) {
return data.category === value ? prev.concat(data[axis]) : prev;
}, []);
});
};
var _dataByIndex = function _dataByIndex() {
return axisValues.map(function (value, index) {
return datasets.map(function (data) {
return data[index] && data[index][axis];
});
});
};
return categories.length === 0 ? _dataByIndex() : _dataByCategory();
},
padDomain: function padDomain(domain, props, axis) {
if (!props.domainPadding) {
return domain;
}
var domainPadding = typeof props.domainPadding === "number" ? props.domainPadding : props.domainPadding[axis];
if (!domainPadding) {
return domain;
}
var domainMin = Math.min.apply(Math, _toConsumableArray(domain));
var domainMax = Math.max.apply(Math, _toConsumableArray(domain));
var range = _victoryCore.Helpers.getRange(props, axis);
var rangeExtent = Math.abs(Math.max.apply(Math, _toConsumableArray(range)) - Math.min.apply(Math, _toConsumableArray(range)));
var padding = Math.abs(domainMax - domainMin) * domainPadding / rangeExtent;
// don't make the axes cross if they aren't already
var adjustedMin = domainMin >= 0 && domainMin - padding <= 0 ? 0 : domainMin.valueOf() - padding;
var adjustedMax = domainMax <= 0 && domainMax + padding >= 0 ? 0 : domainMax.valueOf() + padding;
return domainMin instanceof Date || domainMax instanceof Date ? [new Date(adjustedMin), new Date(adjustedMax)] : [adjustedMin, adjustedMax];
},
orientDomain: function orientDomain(domain, orientations, axis) {
// If the other axis is in a reversed orientation, the domain of this axis
// needs to be reversed
var otherAxis = axis === "x" ? "y" : "x";
var defaultOrientation = function defaultOrientation(ax) {
return ax === "x" ? "bottom" : "left";
};
var flippedAxis = orientations.x === "left" || orientations.x === "right";
var standardOrientation = flippedAxis ? orientations[otherAxis] === defaultOrientation(axis) : orientations[otherAxis] === defaultOrientation(otherAxis);
if (flippedAxis) {
return standardOrientation ? domain.concat().reverse() : domain;
} else {
return standardOrientation ? domain : domain.concat().reverse();
}
}
};