@visactor/vchart
Version:
charts lib based @visactor/VGrammar
194 lines (180 loc) • 11.3 kB
JavaScript
import { STACK_FIELD_END, STACK_FIELD_START_PERCENT, STACK_FIELD_END_PERCENT, STACK_FIELD_END_OffsetSilhouette, STACK_FIELD_START_OffsetSilhouette, STACK_FIELD_TOTAL, STACK_FIELD_TOTAL_PERCENT, STACK_FIELD_TOTAL_TOP, STACK_FIELD_START, STACK_FIELD_KEY, STACK_FIELD_TOTAL_BOTTOM, MOSAIC_CAT_START_PERCENT, MOSAIC_CAT_END_PERCENT, MOSAIC_VALUE_START_PERCENT, MOSAIC_VALUE_END_PERCENT } from "../constant/data";
import { isValid, toValidNumber } from "./type";
import { max, sum } from "./math";
export function mergeFields(targetFields, mergeFields) {
for (let i = 0; i < mergeFields.length; i++) {
const element = mergeFields[i], _target = findFields(targetFields, element.key);
_target ? _target.operations = [ ...new Set(_target.operations.concat(element.operations)) ] : targetFields.push(element);
}
return targetFields;
}
function findFields(list, fieldKey) {
return list.find((i => i.key === fieldKey));
}
export function getFieldAlias(dataView, field) {
var _a;
if (!dataView) return null != field ? field : null;
const fields = dataView.getFields();
return fields && fields[field] ? null !== (_a = fields[field].alias) && void 0 !== _a ? _a : field : null != field ? field : null;
}
export function getRegionStackGroup(region, setInitialValue, filter) {
const stackSort = region.getStackSort(), stackValueGroup = {};
let stackSortCache = null;
return stackSort && (stackSortCache = {}, region.getSeries().forEach((s => {
const seriesField = s.getSeriesField();
if (seriesField) {
const fieldInfo = s.getRawDataStatisticsByField(seriesField);
fieldInfo.values && (stackSortCache[seriesField] || (stackSortCache[seriesField] = {
lastIndex: 0,
sort: {}
}), fieldInfo.values.forEach(((v, i) => {
v in stackSortCache[seriesField].sort || (stackSortCache[seriesField].sort[v] = stackSortCache[seriesField].lastIndex,
stackSortCache[seriesField].lastIndex++);
})));
}
}))), region.getSeries().forEach((s => {
var _a;
const stackData = s.getStackData(), stackValue = s.getStackValue(), stackValueField = s.getStackValueField(), filterEnable = !filter || filter(s);
stackData && stackValueField && filterEnable && (stackValueGroup[stackValue] = null !== (_a = stackValueGroup[stackValue]) && void 0 !== _a ? _a : {
groupField: stackData.groupField,
nodes: {}
}, stackGroup(s, stackData, stackValueGroup[stackValue], stackValueField, setInitialValue, stackSortCache));
})), stackSort ? sortStackValueGroup(stackValueGroup, stackSortCache) : stackValueGroup;
}
export function sortStackValueGroup(stackValueGroup, stackSortCache) {
var _a;
for (const key in stackValueGroup) (null === (_a = stackValueGroup[key].sortDatums) || void 0 === _a ? void 0 : _a.length) ? (stackValueGroup[key].sortDatums.sort(((a, b) => a.index - b.index)),
stackValueGroup[key].values = stackValueGroup[key].sortDatums.map((sd => sd.datum))) : sortStackValueGroup(stackValueGroup[key].nodes, stackSortCache);
return stackValueGroup;
}
export function stackTotal(stackData, valueField) {
if ("values" in stackData && stackData.values.length) {
const total = sum(stackData.values, valueField), percent = max(stackData.values, STACK_FIELD_END_PERCENT);
stackData.values.forEach((v => {
v[STACK_FIELD_TOTAL] = total, v[STACK_FIELD_TOTAL_PERCENT] = percent;
}));
} else for (const key in stackData.nodes) stackTotal(stackData.nodes[key], valueField);
}
export function stackMosaicTotal(stackData, valueField) {
var _a, _b;
if ("values" in stackData && stackData.values.length) isValid(null === (_a = stackData.values[0]) || void 0 === _a ? void 0 : _a[STACK_FIELD_TOTAL]) ? stackData.total = null === (_b = stackData.values[0]) || void 0 === _b ? void 0 : _b[STACK_FIELD_TOTAL] : stackData.total = sum(stackData.values, valueField); else {
for (const key in stackData.nodes) stackMosaicTotal(stackData.nodes[key], valueField);
stackData.nodes && (stackData.total = sum(Object.keys(stackData.nodes).map((key => stackData.nodes[key])), "total"));
}
}
export function stackMosaic(s, stackCache, mosaicData) {
var _a;
if (stackCache.groupField && stackCache.nodes) {
const groupValues = (null === (_a = s.getRawDataStatisticsByField(stackCache.groupField, !1)) || void 0 === _a ? void 0 : _a.values) || [], mosaicStackData = {
key: `${stackCache.groupField}`,
values: groupValues.map((group => {
var _a, _b;
const groupValues = stackCache.nodes[group];
let value;
return value = s.bandWidthField && null !== (_b = null === (_a = groupValues.values.find((v => isValid(v[s.bandWidthField])))) || void 0 === _a ? void 0 : _a[s.bandWidthField]) && void 0 !== _b ? _b : groupValues.total,
{
groupValue: group,
value: value,
end: value
};
}))
};
stack(mosaicStackData, !1, !0, !1, {
key: "groupField",
start: "start",
end: "end",
startPercent: "startPercent",
endPercent: "endPercent"
}), mosaicStackData.values.forEach((stackValue => {
stackCache.nodes[stackValue.groupValue].mosaicData = stackValue;
}));
} else if ("values" in stackCache && stackCache.values.length && mosaicData && mosaicData.length) {
const len = mosaicData.length;
let catStartPercent = 0, catEndPercent = 1, valueStartPercent = 0, valueEndPercent = 1;
for (let i = 0; i < len; i++) if (i % 2 == 0) {
const catDelta = catEndPercent - catStartPercent;
catEndPercent = catStartPercent + mosaicData[i].endPercent * catDelta, catStartPercent += mosaicData[i].startPercent * catDelta;
} else {
const valueDelta = valueEndPercent - valueStartPercent;
valueEndPercent = valueStartPercent + mosaicData[i].endPercent * valueDelta, valueStartPercent += mosaicData[i].startPercent * valueDelta;
}
len % 2 == 0 ? stackCache.values.forEach((v => {
const delta = catEndPercent - catStartPercent;
v[MOSAIC_CAT_END_PERCENT] = catStartPercent + delta * v[STACK_FIELD_END_PERCENT],
v[MOSAIC_CAT_START_PERCENT] = catStartPercent + delta * v[STACK_FIELD_START_PERCENT],
v[MOSAIC_VALUE_END_PERCENT] = valueEndPercent, v[MOSAIC_VALUE_START_PERCENT] = valueStartPercent;
})) : stackCache.values.forEach((v => {
const delta = valueEndPercent - valueStartPercent;
v[MOSAIC_VALUE_END_PERCENT] = valueStartPercent + delta * v[STACK_FIELD_END_PERCENT],
v[MOSAIC_VALUE_START_PERCENT] = valueStartPercent + delta * v[STACK_FIELD_START_PERCENT],
v[MOSAIC_CAT_END_PERCENT] = catEndPercent, v[MOSAIC_CAT_START_PERCENT] = catStartPercent;
}));
}
for (const key in stackCache.nodes) stackMosaic(s, stackCache.nodes[key], stackCache.nodes[key].mosaicData ? mosaicData ? [ ...mosaicData, stackCache.nodes[key].mosaicData ] : [ stackCache.nodes[key].mosaicData ] : null);
}
export function stackOffsetSilhouette(stackCache) {
if (!stackCache.values.length) return;
const centerValue = stackCache.values[stackCache.values.length - 1][STACK_FIELD_END] / 2;
for (let j = 0; j < stackCache.values.length; j++) stackCache.values[j][STACK_FIELD_START_OffsetSilhouette] = stackCache.values[j][STACK_FIELD_START] - centerValue,
stackCache.values[j][STACK_FIELD_END_OffsetSilhouette] = stackCache.values[j][STACK_FIELD_END] - centerValue;
}
export function stack(stackCache, stackInverse, hasPercent, hasMinMax, fields = {
key: STACK_FIELD_KEY,
start: STACK_FIELD_START,
end: STACK_FIELD_END,
startPercent: STACK_FIELD_START_PERCENT,
endPercent: STACK_FIELD_END_PERCENT,
max: STACK_FIELD_TOTAL_TOP,
min: STACK_FIELD_TOTAL_BOTTOM
}) {
const hasMinField = hasMinMax && isValid(fields.min), hasMaxField = hasMinMax && isValid(fields.max);
if (stackCache.values.length > 0) {
let positiveStart = 0, negativeStart = 0, sign = 1, value = 0, minNode = null, maxNode = null;
const maxLength = stackCache.values.length;
for (let index = 0; index < maxLength; index++) {
const v = stackCache.values[stackInverse ? maxLength - 1 - index : index];
value = v[fields.end], value >= 0 ? (v[fields.start] = positiveStart, positiveStart += v[fields.end],
v[fields.end] = positiveStart) : (v[fields.start] = negativeStart, negativeStart += v[fields.end],
v[fields.end] = negativeStart), v[fields.key] = stackCache.key, hasMaxField && (delete v[fields.max],
(!maxNode || v[fields.end] > maxNode[fields.end]) && (maxNode = v)), hasMinField && (delete v[fields.min],
(!minNode || v[fields.start] < minNode[fields.start]) && (minNode = v));
}
if (hasMaxField && maxNode && (maxNode[fields.max] = !0), hasMinField && minNode && (minNode[fields.min] = !0),
hasPercent) for (let index = 0; index < maxLength; index++) {
const v = stackCache.values[stackInverse ? maxLength - 1 - index : index];
value = v[fields.end];
const denominator = value >= 0 ? positiveStart : negativeStart;
sign = value >= 0 ? 1 : -1, v[fields.startPercent] = 0 === denominator ? 0 : Math.min(1, v[fields.start] / denominator) * sign,
v[fields.endPercent] = 0 === denominator ? 0 : Math.min(1, v[fields.end] / denominator) * sign;
}
}
for (const key in stackCache.nodes) stack(stackCache.nodes[key], stackInverse, hasPercent, hasMinMax, fields);
}
export function stackGroup(s, stackData, stackCache, valueField, setInitialValue, stackSortCache, stackKey) {
var _a;
if ("values" in stackData) if (setInitialValue && stackData.values.forEach((v => v[STACK_FIELD_END] = toValidNumber(v[valueField]))),
stackCache.series.push({
s: s,
values: stackData.values
}), stackSortCache) {
const seriesField = s.getSeriesField();
stackData.values.forEach((d => {
stackCache.sortDatums.push({
series: s,
datum: d,
index: seriesField ? stackSortCache[seriesField].sort[d[seriesField]] : 0
});
}));
} else stackCache.values.push(...stackData.values); else for (const key in stackData.nodes) {
const newStackKey = stackKey ? `${stackKey}_${key}` : key;
stackCache.nodes[key] || (stackCache.nodes[key] = {
values: [],
series: [],
nodes: {},
sortDatums: [],
key: newStackKey
}, isValid(null === (_a = stackData.nodes[key]) || void 0 === _a ? void 0 : _a.groupField) && (stackCache.nodes[key].groupField = stackData.nodes[key].groupField)),
stackGroup(s, stackData.nodes[key], stackCache.nodes[key], valueField, setInitialValue, stackSortCache, newStackKey);
}
}
//# sourceMappingURL=data.js.map