@visactor/vtable 0.12.0-alpha.1 → 0.12.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/PivotChart.d.ts +1 -1
- package/cjs/PivotChart.js +3 -3
- package/cjs/PivotChart.js.map +1 -1
- package/cjs/PivotTable.js +3 -3
- package/cjs/PivotTable.js.map +1 -1
- package/cjs/components/axis/axis.js +2 -2
- package/cjs/components/axis/axis.js.map +1 -1
- package/cjs/core/BaseTable.js +2 -2
- package/cjs/core/BaseTable.js.map +1 -1
- package/cjs/dataset/flatDataToObject.js +1 -2
- package/cjs/event/sparkline-event.js +2 -1
- package/cjs/index.d.ts +1 -1
- package/cjs/index.js +1 -1
- package/cjs/index.js.map +1 -1
- package/cjs/layout/chart-helper/get-axis-domain.js +4 -4
- package/cjs/layout/chart-helper/get-axis-domain.js.map +1 -1
- package/cjs/scenegraph/hover-state.js +1 -1
- package/cjs/scenegraph/scenegraph.js +3 -3
- package/cjs/scenegraph/scenegraph.js.map +1 -1
- package/cjs/state/state.js +1 -1
- package/cjs/themes/ARCO.js +1 -1
- package/cjs/themes/BRIGHT.js +2 -1
- package/cjs/themes/DARK.js +1 -1
- package/cjs/themes/DEFAULT.js +1 -1
- package/cjs/themes/SIMPLIFY.js +1 -1
- package/cjs/themes/theme.js +1 -1
- package/cjs/tools/calc.js +1 -1
- package/cjs/tools/debounce.js +1 -2
- package/cjs/tools/diff-cell.js +2 -2
- package/cjs/tools/dom.js +1 -1
- package/cjs/tools/env.js +1 -1
- package/cjs/tools/get-data-path/index.js +4 -3
- package/cjs/tools/get-data-path/index.js.map +1 -1
- package/cjs/tools/global.js +1 -1
- package/cjs/tools/helper.js +1 -1
- package/cjs/tools/icons.js +1 -1
- package/cjs/tools/isx.js +1 -1
- package/dist/vtable.js +31080 -5488
- package/dist/vtable.min.js +2 -2
- package/es/PivotChart.d.ts +1 -1
- package/es/PivotChart.js +3 -3
- package/es/PivotChart.js.map +1 -1
- package/es/PivotTable.js +3 -3
- package/es/PivotTable.js.map +1 -1
- package/es/components/axis/axis.js +1 -1
- package/es/components/axis/axis.js.map +1 -1
- package/es/core/BaseTable.js +2 -2
- package/es/core/BaseTable.js.map +1 -1
- package/es/dataset/flatDataToObject.js +1 -2
- package/es/event/sparkline-event.js +2 -1
- package/es/index.d.ts +1 -1
- package/es/index.js +1 -1
- package/es/index.js.map +1 -1
- package/es/layout/chart-helper/get-axis-domain.js +5 -5
- package/es/layout/chart-helper/get-axis-domain.js.map +1 -1
- package/es/scenegraph/hover-state.js +1 -1
- package/es/scenegraph/scenegraph.js +3 -4
- package/es/scenegraph/scenegraph.js.map +1 -1
- package/es/state/state.js +1 -1
- package/es/themes/ARCO.js +1 -1
- package/es/themes/BRIGHT.js +2 -1
- package/es/themes/DARK.js +1 -1
- package/es/themes/DEFAULT.js +1 -1
- package/es/themes/SIMPLIFY.js +1 -1
- package/es/themes/theme.js +1 -1
- package/es/tools/calc.js +1 -1
- package/es/tools/debounce.js +1 -2
- package/es/tools/diff-cell.js +1 -1
- package/es/tools/dom.js +1 -1
- package/es/tools/env.js +1 -1
- package/es/tools/get-data-path/index.js +4 -3
- package/es/tools/get-data-path/index.js.map +1 -1
- package/es/tools/global.js +1 -1
- package/es/tools/helper.js +1 -1
- package/es/tools/icons.js +1 -1
- package/es/tools/isx.js +2 -1
- package/package.json +5 -4
- package/cjs/components/util/tick-data/config.d.ts +0 -1
- package/cjs/components/util/tick-data/config.js +0 -6
- package/cjs/components/util/tick-data/config.js.map +0 -1
- package/cjs/components/util/tick-data/continuous.d.ts +0 -2
- package/cjs/components/util/tick-data/continuous.js +0 -44
- package/cjs/components/util/tick-data/continuous.js.map +0 -1
- package/cjs/components/util/tick-data/discrete/linear.d.ts +0 -2
- package/cjs/components/util/tick-data/discrete/linear.js +0 -90
- package/cjs/components/util/tick-data/discrete/linear.js.map +0 -1
- package/cjs/components/util/tick-data/discrete/polar-angle.d.ts +0 -2
- package/cjs/components/util/tick-data/discrete/polar-angle.js +0 -46
- package/cjs/components/util/tick-data/discrete/polar-angle.js.map +0 -1
- package/cjs/components/util/tick-data/index.d.ts +0 -2
- package/cjs/components/util/tick-data/index.js +0 -17
- package/cjs/components/util/tick-data/index.js.map +0 -1
- package/cjs/components/util/tick-data/util.d.ts +0 -21
- package/cjs/components/util/tick-data/util.js +0 -114
- package/cjs/components/util/tick-data/util.js.map +0 -1
- package/es/components/util/tick-data/config.d.ts +0 -1
- package/es/components/util/tick-data/config.js +0 -2
- package/es/components/util/tick-data/config.js.map +0 -1
- package/es/components/util/tick-data/continuous.d.ts +0 -2
- package/es/components/util/tick-data/continuous.js +0 -43
- package/es/components/util/tick-data/continuous.js.map +0 -1
- package/es/components/util/tick-data/discrete/linear.d.ts +0 -2
- package/es/components/util/tick-data/discrete/linear.js +0 -81
- package/es/components/util/tick-data/discrete/linear.js.map +0 -1
- package/es/components/util/tick-data/discrete/polar-angle.d.ts +0 -2
- package/es/components/util/tick-data/discrete/polar-angle.js +0 -39
- package/es/components/util/tick-data/discrete/polar-angle.js.map +0 -1
- package/es/components/util/tick-data/index.d.ts +0 -2
- package/es/components/util/tick-data/index.js +0 -19
- package/es/components/util/tick-data/index.js.map +0 -1
- package/es/components/util/tick-data/util.d.ts +0 -21
- package/es/components/util/tick-data/util.js +0 -103
- package/es/components/util/tick-data/util.js.map +0 -1
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { isContinuous } from "@visactor/vscale";
|
|
2
|
-
|
|
3
|
-
import { isValid, last as peek } from "@visactor/vutils";
|
|
4
|
-
|
|
5
|
-
import { DEFAULT_CONTINUOUS_TICK_COUNT } from "./config";
|
|
6
|
-
|
|
7
|
-
import { convertDomainToTickData, getCartesianLabelBounds, hasOverlap, intersect } from "./util";
|
|
8
|
-
|
|
9
|
-
export const continuousTicks = (scale, op) => {
|
|
10
|
-
if (!isContinuous(scale.type)) return convertDomainToTickData(scale.domain(), op);
|
|
11
|
-
const range = scale.range();
|
|
12
|
-
if (Math.abs(range[range.length - 1] - range[0]) < 2) return convertDomainToTickData([ scale.domain()[0] ], op);
|
|
13
|
-
const {tickCount: tickCount, forceTickCount: forceTickCount, tickStep: tickStep, noDecimals: noDecimals = !1} = op;
|
|
14
|
-
let scaleTicks;
|
|
15
|
-
if (delete scale._niceType, scaleTicks = isValid(tickStep) ? scale.stepTicks(tickStep) : isValid(forceTickCount) ? scale.forceTicks(forceTickCount) : "d3" === op.tickMode ? scale.d3Ticks(null != tickCount ? tickCount : DEFAULT_CONTINUOUS_TICK_COUNT, {
|
|
16
|
-
noDecimals: noDecimals
|
|
17
|
-
}) : scale.ticks(null != tickCount ? tickCount : DEFAULT_CONTINUOUS_TICK_COUNT, {
|
|
18
|
-
noDecimals: noDecimals
|
|
19
|
-
}), op.sampling && ("cartesian" === op.coordinateType || "polar" === op.coordinateType && "radius" === op.axisOrientType)) {
|
|
20
|
-
const {labelGap: labelGap = 4, labelFlush: labelFlush} = op;
|
|
21
|
-
let items = getCartesianLabelBounds(scale, scaleTicks, op).map(((bounds, i) => ({
|
|
22
|
-
AABBBounds: bounds,
|
|
23
|
-
value: scaleTicks[i]
|
|
24
|
-
})));
|
|
25
|
-
for (;items.length >= 3 && hasOverlap(items, labelGap); ) items = methods.parity(items);
|
|
26
|
-
const ticks = items.map((item => item.value));
|
|
27
|
-
ticks.length < 3 && labelFlush && (ticks.length > 1 && ticks.pop(), peek(ticks) !== peek(scaleTicks) && ticks.push(peek(scaleTicks))),
|
|
28
|
-
scaleTicks = ticks;
|
|
29
|
-
}
|
|
30
|
-
return convertDomainToTickData(scaleTicks, op);
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const methods = {
|
|
34
|
-
parity: function(items) {
|
|
35
|
-
return items.filter(((item, i) => i % 2 == 0));
|
|
36
|
-
},
|
|
37
|
-
greedy: function(items, sep) {
|
|
38
|
-
let a;
|
|
39
|
-
return items.filter(((b, i) => (!i || !intersect(a.AABBBounds, b.AABBBounds, sep)) && (a = b,
|
|
40
|
-
!0)));
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
//# sourceMappingURL=continuous.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["components/util/tick-data/continuous.ts"],"names":[],"mappings":"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","file":"continuous.js","sourcesContent":["import type { LinearScale, ContinuousScale } from '@visactor/vscale';\n// eslint-disable-next-line no-duplicate-imports\nimport { isContinuous } from '@visactor/vscale';\nimport { isValid, last as peek } from '@visactor/vutils';\nimport { DEFAULT_CONTINUOUS_TICK_COUNT } from './config';\nimport type { ILabelItem } from './util';\n// eslint-disable-next-line no-duplicate-imports\nimport { convertDomainToTickData, getCartesianLabelBounds, hasOverlap, intersect } from './util';\n\n/**\n * 对于连续轴:\n * - 如果spec配了tickCount、forceTickCount、tickStep,则直接输出LinearScale的ticks()、forceTicks()、stepTicks()结果;\n * - 默认输出tickCount为10的ticks()结果。\n *\n * @param scale\n * @param op\n * @returns\n */\nexport const continuousTicks = (scale: ContinuousScale, op: any): any[] => {\n if (!isContinuous(scale.type)) {\n return convertDomainToTickData(scale.domain(), op);\n }\n // if range is so small\n const range = scale.range();\n const rangeSize = Math.abs(range[range.length - 1] - range[0]);\n if (rangeSize < 2) {\n return convertDomainToTickData([scale.domain()[0]], op);\n }\n\n const { tickCount, forceTickCount, tickStep, noDecimals = false } = op;\n\n delete (scale as any)._niceType; // ensure scaleTicks consistent in `measurement`, `component label` and `chart`\n let scaleTicks: number[];\n if (isValid(tickStep)) {\n scaleTicks = (scale as LinearScale).stepTicks(tickStep);\n } else if (isValid(forceTickCount)) {\n scaleTicks = (scale as LinearScale).forceTicks(forceTickCount);\n } else if (op.tickMode === 'd3') {\n scaleTicks = (scale as LinearScale).d3Ticks(tickCount ?? DEFAULT_CONTINUOUS_TICK_COUNT, { noDecimals });\n } else {\n scaleTicks = (scale as LinearScale).ticks(tickCount ?? DEFAULT_CONTINUOUS_TICK_COUNT, { noDecimals });\n }\n\n if (op.sampling) {\n // 判断重叠\n if (op.coordinateType === 'cartesian' || (op.coordinateType === 'polar' && op.axisOrientType === 'radius')) {\n const { labelGap = 4, labelFlush } = op as any;\n let items = getCartesianLabelBounds(scale, scaleTicks, op as any).map(\n (bounds, i) =>\n ({\n AABBBounds: bounds,\n value: scaleTicks[i]\n } as ILabelItem<number>)\n );\n while (items.length >= 3 && hasOverlap(items, labelGap)) {\n items = methods.parity(items);\n }\n const ticks = items.map(item => item.value);\n\n if (ticks.length < 3 && labelFlush) {\n if (ticks.length > 1) {\n ticks.pop();\n }\n if (peek(ticks) !== peek(scaleTicks)) {\n ticks.push(peek(scaleTicks));\n }\n }\n\n scaleTicks = ticks;\n }\n }\n\n return convertDomainToTickData(scaleTicks, op);\n};\n\nconst methods = {\n parity: function <T>(items: ILabelItem<T>[]) {\n return items.filter((item, i) => i % 2 === 0);\n },\n greedy: function <T>(items: ILabelItem<T>[], sep: number) {\n let a: ILabelItem<T>;\n return items.filter((b, i) => {\n if (!i || !intersect(a.AABBBounds, b.AABBBounds, sep)) {\n a = b;\n return true;\n }\n return false;\n });\n }\n};\n"]}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { isValid } from "@visactor/vutils";
|
|
2
|
-
|
|
3
|
-
import { convertDomainToTickData, getCartesianLabelBounds, labelDistance, labelOverlap } from "../util";
|
|
4
|
-
|
|
5
|
-
export const linearDiscreteTicks = (scale, op) => {
|
|
6
|
-
var _a;
|
|
7
|
-
const domain = scale.domain();
|
|
8
|
-
if (!domain.length) return [];
|
|
9
|
-
const {tickCount: tickCount, forceTickCount: forceTickCount, tickStep: tickStep, labelGap: labelGap = 4, axisOrientType: axisOrientType} = op, isHorizontal = [ "bottom", "top" ].includes(axisOrientType), range = scale.range(), rangeSize = Math.abs(range[range.length - 1] - range[0]);
|
|
10
|
-
if (rangeSize < 2) return op.labelLastVisible ? convertDomainToTickData([ domain[domain.length - 1] ], op) : convertDomainToTickData([ domain[0] ], op);
|
|
11
|
-
let scaleTicks;
|
|
12
|
-
if (isValid(tickStep)) scaleTicks = scale.stepTicks(tickStep); else if (isValid(forceTickCount)) scaleTicks = scale.forceTicks(forceTickCount); else if (isValid(tickCount)) scaleTicks = scale.ticks(tickCount); else if (op.sampling) {
|
|
13
|
-
let labelBoundsList;
|
|
14
|
-
const fontSize = (null !== (_a = op.labelStyle.fontSize) && void 0 !== _a ? _a : 12) + 2;
|
|
15
|
-
if (domain.length <= rangeSize / fontSize) labelBoundsList = getCartesianLabelBounds(scale, domain, op); else {
|
|
16
|
-
const tempDomain = [ domain[0], domain[Math.floor(domain.length / 2)], domain[domain.length - 1] ], tempList = getCartesianLabelBounds(scale, tempDomain, op);
|
|
17
|
-
let maxBounds = null, maxBoundsIndex = 0;
|
|
18
|
-
tempList.forEach(((current, index) => {
|
|
19
|
-
if (!maxBounds) return maxBounds = current, void (maxBoundsIndex = index);
|
|
20
|
-
isHorizontal ? maxBounds.width() < current.width() && (maxBounds = current, maxBoundsIndex = index) : maxBounds.height() < current.height() && (maxBounds = current,
|
|
21
|
-
maxBoundsIndex = index);
|
|
22
|
-
}));
|
|
23
|
-
const maxBoundsDomainIndex = 0 === maxBoundsIndex ? 0 : 2 === maxBoundsIndex ? domain.length - 1 : Math.floor(domain.length / 2), maxBoundsPos = scale.scale(domain[maxBoundsDomainIndex]);
|
|
24
|
-
labelBoundsList = new Array(domain.length);
|
|
25
|
-
for (let i = 0; i < labelBoundsList.length; i++) {
|
|
26
|
-
labelBoundsList[i] = maxBounds.clone();
|
|
27
|
-
const currentPos = scale.scale(domain[i]);
|
|
28
|
-
isHorizontal ? labelBoundsList[i].translate(currentPos - maxBoundsPos, 0) : labelBoundsList[i].translate(0, currentPos - maxBoundsPos);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
const domainLengthList = labelBoundsList.map((b => isHorizontal ? b.width() : b.height())), rangeStart = Math.min(...range), incrementUnit = (Math.max(...range) - rangeStart) / domain.length, result = getStep(domain, labelBoundsList, labelGap, op.labelLastVisible, isHorizontal, Math.floor(Math.min(...domainLengthList) / incrementUnit));
|
|
32
|
-
scaleTicks = scale.stepTicks(result.step), op.labelLastVisible && (scaleTicks = scaleTicks.slice(0, scaleTicks.length - result.delCount),
|
|
33
|
-
scaleTicks.push(domain[domain.length - 1]));
|
|
34
|
-
} else scaleTicks = scale.domain();
|
|
35
|
-
return convertDomainToTickData(scaleTicks, op);
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
const getStep = (domain, labelBoundsList, labelGap, labelLastVisible, isHorizontal, defaultStep) => {
|
|
39
|
-
let step = defaultStep, delCount = 0, resultDelCount = 0, resultStep = 0, resultTickCount = -1, minDiff = Number.MAX_VALUE;
|
|
40
|
-
do {
|
|
41
|
-
let success = !0;
|
|
42
|
-
step++;
|
|
43
|
-
let ptr = 0;
|
|
44
|
-
do {
|
|
45
|
-
ptr + step < domain.length && labelOverlap(labelBoundsList[ptr], labelBoundsList[ptr + step], labelGap) && (success = !1),
|
|
46
|
-
ptr += step;
|
|
47
|
-
} while (success && ptr < domain.length);
|
|
48
|
-
if (success) {
|
|
49
|
-
if (!labelLastVisible) {
|
|
50
|
-
resultStep = step;
|
|
51
|
-
break;
|
|
52
|
-
}
|
|
53
|
-
{
|
|
54
|
-
const lastIndex = domain.length - 1;
|
|
55
|
-
delCount = 0;
|
|
56
|
-
do {
|
|
57
|
-
if (ptr -= step, ptr !== lastIndex && !labelOverlap(labelBoundsList[ptr], labelBoundsList[lastIndex], labelGap)) break;
|
|
58
|
-
delCount++;
|
|
59
|
-
} while (ptr > 0);
|
|
60
|
-
if (ptr === lastIndex) {
|
|
61
|
-
resultStep = step, resultDelCount = delCount;
|
|
62
|
-
break;
|
|
63
|
-
}
|
|
64
|
-
{
|
|
65
|
-
const tickCount = Math.floor(domain.length / step) - delCount + 1;
|
|
66
|
-
if (tickCount < resultTickCount) break;
|
|
67
|
-
{
|
|
68
|
-
resultTickCount = tickCount;
|
|
69
|
-
const distanceIndex = isHorizontal ? 0 : 1, distance1 = labelDistance(labelBoundsList[ptr], labelBoundsList[lastIndex])[distanceIndex], distance2 = ptr - step >= 0 ? labelDistance(labelBoundsList[ptr - step], labelBoundsList[ptr])[distanceIndex] : distance1, diff = Math.abs(distance1 - distance2);
|
|
70
|
-
diff < minDiff && (minDiff = diff, resultStep = step, resultDelCount = delCount);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
} while (step <= domain.length);
|
|
76
|
-
return {
|
|
77
|
-
step: resultStep,
|
|
78
|
-
delCount: resultDelCount
|
|
79
|
-
};
|
|
80
|
-
};
|
|
81
|
-
//# sourceMappingURL=linear.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["components/util/tick-data/discrete/linear.ts"],"names":[],"mappings":"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","file":"linear.js","sourcesContent":["import type { BandScale } from '@visactor/vscale';\nimport { isValid } from '@visactor/vutils';\nimport { convertDomainToTickData, getCartesianLabelBounds, labelDistance, labelOverlap } from '../util';\nimport type { AABBBounds } from '@visactor/vutils';\n\n/**\n * 对于离散轴:\n * - 如果spec配了tickCount、forceTickCount、tickStep,则直接输出BandScale的ticks()、forceTicks()、stepTicks()结果;\n * - 估算所有轴label的宽度(或高度,在竖轴的情况下)并存为数组domainLengthList;\n * - 通过循环来寻找最小的step,使:如果在这个step下采样,轴标签互不遮挡(此处用到domainLengthList和scale.range());\n * - 如果用户配置了spec.label.lastVisible,则处理右边界:强制采样最后一个tick数据,并删掉这个tick的label所覆盖的那些tick数据。\n *\n * @param scale\n * @param op\n * @returns\n */\nexport const linearDiscreteTicks = (scale: BandScale, op: any): any[] => {\n const domain = scale.domain();\n if (!domain.length) {\n return [];\n }\n const { tickCount, forceTickCount, tickStep, labelGap = 4, axisOrientType } = op;\n const isHorizontal = ['bottom', 'top'].includes(axisOrientType);\n const range = scale.range();\n\n // if range is so small\n const rangeSize = Math.abs(range[range.length - 1] - range[0]);\n if (rangeSize < 2) {\n if (op.labelLastVisible) {\n return convertDomainToTickData([domain[domain.length - 1]], op);\n }\n return convertDomainToTickData([domain[0]], op);\n }\n\n let scaleTicks;\n if (isValid(tickStep)) {\n scaleTicks = scale.stepTicks(tickStep);\n } else if (isValid(forceTickCount)) {\n scaleTicks = scale.forceTicks(forceTickCount);\n } else if (isValid(tickCount)) {\n scaleTicks = scale.ticks(tickCount);\n } else if (op.sampling) {\n let labelBoundsList: AABBBounds[];\n const fontSize = (op.labelStyle.fontSize ?? 12) + 2;\n if (domain.length <= rangeSize / fontSize) {\n labelBoundsList = getCartesianLabelBounds(scale, domain, op);\n } else {\n // only check first middle last, use the max size to sampling\n const tempDomain = [domain[0], domain[Math.floor(domain.length / 2)], domain[domain.length - 1]];\n const tempList = getCartesianLabelBounds(scale, tempDomain, op);\n let maxBounds: AABBBounds = null;\n let maxBoundsIndex = 0;\n tempList.forEach((current, index) => {\n if (!maxBounds) {\n maxBounds = current;\n maxBoundsIndex = index;\n return;\n }\n if (isHorizontal) {\n if (maxBounds.width() < current.width()) {\n maxBounds = current;\n maxBoundsIndex = index;\n }\n } else if (maxBounds.height() < current.height()) {\n maxBounds = current;\n maxBoundsIndex = index;\n }\n });\n const maxBoundsDomainIndex =\n maxBoundsIndex === 0 ? 0 : maxBoundsIndex === 2 ? domain.length - 1 : Math.floor(domain.length / 2);\n const maxBoundsPos = scale.scale(domain[maxBoundsDomainIndex]);\n labelBoundsList = new Array(domain.length);\n // set bounds to each pos\n for (let i = 0; i < labelBoundsList.length; i++) {\n labelBoundsList[i] = maxBounds.clone();\n const currentPos = scale.scale(domain[i]);\n if (isHorizontal) {\n labelBoundsList[i].translate(currentPos - maxBoundsPos, 0);\n } else {\n labelBoundsList[i].translate(0, currentPos - maxBoundsPos);\n }\n }\n }\n\n const domainLengthList = labelBoundsList.map(b => {\n return isHorizontal ? b.width() : b.height();\n });\n\n const rangeStart = Math.min(...range);\n const rangeEnd = Math.max(...range);\n const incrementUnit = (rangeEnd - rangeStart) / domain.length;\n const result = getStep(\n domain,\n labelBoundsList,\n labelGap,\n op.labelLastVisible,\n isHorizontal,\n Math.floor(Math.min(...domainLengthList) / incrementUnit) // 给step赋上合适的初值,有效改善外层循环次数\n );\n\n scaleTicks = (scale as BandScale).stepTicks(result.step);\n if (op.labelLastVisible) {\n scaleTicks = scaleTicks.slice(0, scaleTicks.length - result.delCount);\n scaleTicks.push(domain[domain.length - 1]);\n }\n } else {\n scaleTicks = scale.domain();\n }\n\n return convertDomainToTickData(scaleTicks, op);\n};\n\n/** 计算合适的step */\nconst getStep = (\n domain: any[],\n labelBoundsList: AABBBounds[],\n labelGap: number,\n labelLastVisible: boolean,\n isHorizontal: boolean,\n defaultStep: number\n) => {\n let step = defaultStep;\n let delCount = 0;\n let resultDelCount = 0;\n let resultStep = 0;\n let resultTickCount = -1;\n let minDiff = Number.MAX_VALUE;\n // 通过循环来寻找最小的step,使:如果在这个step下采样,轴标签互不遮挡\n do {\n let success = true;\n step++;\n let ptr = 0;\n do {\n if (ptr + step < domain.length && labelOverlap(labelBoundsList[ptr], labelBoundsList[ptr + step], labelGap)) {\n success = false;\n }\n ptr += step;\n } while (success && ptr < domain.length);\n\n if (success) {\n if (labelLastVisible) {\n const lastIndex = domain.length - 1;\n delCount = 0;\n do {\n ptr -= step; // 获取最后一个label位置\n if (ptr === lastIndex || labelOverlap(labelBoundsList[ptr], labelBoundsList[lastIndex], labelGap)) {\n delCount++;\n } else {\n break;\n }\n } while (ptr > 0);\n if (ptr === lastIndex) {\n // 采到的最后的一个 label 刚好是最后一项,直接退出\n resultStep = step;\n resultDelCount = delCount;\n break;\n } else {\n // 尝试获取最均匀的结果,防止倒数第二项和最后一项有大的空档\n const tickCount = Math.floor(domain.length / step) - delCount + 1;\n if (tickCount < resultTickCount) {\n break;\n } else {\n resultTickCount = tickCount;\n const distanceIndex = isHorizontal ? 0 : 1;\n const distance1 = labelDistance(labelBoundsList[ptr], labelBoundsList[lastIndex])[distanceIndex]; // 倒数第2项和最后一项的距离\n const distance2 =\n ptr - step >= 0\n ? labelDistance(labelBoundsList[ptr - step], labelBoundsList[ptr])[distanceIndex]\n : distance1; // 倒数第3项和倒数第2项的距离\n const diff = Math.abs(distance1 - distance2);\n if (diff < minDiff) {\n minDiff = diff;\n resultStep = step; // 记录最均匀的 step\n resultDelCount = delCount;\n }\n }\n }\n } else {\n resultStep = step;\n break;\n }\n }\n } while (step <= domain.length);\n\n return {\n step: resultStep,\n delCount: resultDelCount\n };\n};\n"]}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { isValid } from "@visactor/vutils";
|
|
2
|
-
|
|
3
|
-
import { convertDomainToTickData, getAxisLabelOffset, getPolarAngleLabelBounds, labelOverlap } from "../util";
|
|
4
|
-
|
|
5
|
-
export const polarAngleAxisDiscreteTicks = (scale, op) => {
|
|
6
|
-
const {tickCount: tickCount, forceTickCount: forceTickCount, tickStep: tickStep, getRadius: getRadius, axisSpec: axisSpec, labelGap: labelGap = 0} = op, radius = null == getRadius ? void 0 : getRadius();
|
|
7
|
-
if (!radius) return convertDomainToTickData(scale.domain(), op);
|
|
8
|
-
let scaleTicks;
|
|
9
|
-
if (isValid(tickStep)) scaleTicks = scale.stepTicks(tickStep); else if (isValid(forceTickCount)) scaleTicks = scale.forceTicks(forceTickCount); else if (isValid(tickCount)) scaleTicks = scale.ticks(tickCount); else if (op.sampling) {
|
|
10
|
-
const domain = scale.domain(), range = scale.range(), labelOffset = getAxisLabelOffset(axisSpec), labelBoundsList = getPolarAngleLabelBounds(scale, domain, op), rangeStart = Math.min(...range), rangeEnd = Math.max(...range), incrementUnit = Math.abs(rangeEnd - rangeStart) * (radius + labelOffset) / domain.length, {step: step, delCount: delCount} = getStep(domain, labelBoundsList, labelGap, Math.floor(labelBoundsList.reduce(((min, curBounds) => Math.min(min, curBounds.width(), curBounds.height())), Number.MAX_VALUE) / incrementUnit));
|
|
11
|
-
scaleTicks = scale.stepTicks(step), scaleTicks = scaleTicks.slice(0, scaleTicks.length - delCount);
|
|
12
|
-
} else scaleTicks = scale.domain();
|
|
13
|
-
return convertDomainToTickData(scaleTicks, op);
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const getStep = (domain, labelBoundsList, labelGap, defaultStep) => {
|
|
17
|
-
let step = defaultStep;
|
|
18
|
-
do {
|
|
19
|
-
let success = !0;
|
|
20
|
-
step++;
|
|
21
|
-
let ptr = 0;
|
|
22
|
-
do {
|
|
23
|
-
ptr + step < domain.length && labelOverlap(labelBoundsList[ptr], labelBoundsList[ptr + step], labelGap) && (success = !1),
|
|
24
|
-
ptr += step;
|
|
25
|
-
} while (success && ptr < domain.length);
|
|
26
|
-
if (success) break;
|
|
27
|
-
} while (step <= domain.length);
|
|
28
|
-
let delCount = 0;
|
|
29
|
-
if (domain.length > 2) {
|
|
30
|
-
let ptr = domain.length - domain.length % step;
|
|
31
|
-
for (ptr >= domain.length && (ptr -= step); ptr > 0 && labelOverlap(labelBoundsList[0], labelBoundsList[ptr]); ) delCount++,
|
|
32
|
-
ptr -= step;
|
|
33
|
-
}
|
|
34
|
-
return {
|
|
35
|
-
step: step,
|
|
36
|
-
delCount: delCount
|
|
37
|
-
};
|
|
38
|
-
};
|
|
39
|
-
//# sourceMappingURL=polar-angle.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["components/util/tick-data/discrete/polar-angle.ts"],"names":[],"mappings":"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","file":"polar-angle.js","sourcesContent":["import type { BandScale } from '@visactor/vscale';\nimport { isValid } from '@visactor/vutils';\nimport { convertDomainToTickData, getAxisLabelOffset, getPolarAngleLabelBounds, labelOverlap } from '../util';\nimport type { AABBBounds } from '@visactor/vutils';\n\n/**\n * 对于离散轴:\n * - 如果spec配了tickCount、forceTickCount、tickStep,则直接输出BandScale的ticks()、forceTicks()、stepTicks()结果;\n * - 估算所有轴label的宽高并存为数组labelBoundsList;\n * - 通过循环来寻找最小的step,使:如果在这个step下采样,轴标签互不遮挡(此处用到labelBoundsList和scale.range());\n *\n * @param scale\n * @param op\n * @returns\n */\nexport const polarAngleAxisDiscreteTicks = (scale: BandScale, op: any): any[] => {\n const { tickCount, forceTickCount, tickStep, getRadius, axisSpec, labelGap = 0 } = op;\n const radius = getRadius?.();\n if (!radius) {\n return convertDomainToTickData(scale.domain(), op);\n }\n\n let scaleTicks;\n if (isValid(tickStep)) {\n scaleTicks = scale.stepTicks(tickStep);\n } else if (isValid(forceTickCount)) {\n scaleTicks = scale.forceTicks(forceTickCount);\n } else if (isValid(tickCount)) {\n scaleTicks = scale.ticks(tickCount);\n } else if (op.sampling) {\n const domain = scale.domain();\n const range = scale.range();\n\n const labelOffset = getAxisLabelOffset(axisSpec);\n const labelBoundsList = getPolarAngleLabelBounds(scale, domain, op);\n\n const rangeStart = Math.min(...range);\n const rangeEnd = Math.max(...range);\n\n const axisLength = Math.abs(rangeEnd - rangeStart) * (radius + labelOffset);\n const incrementUnit = axisLength / domain.length;\n const { step, delCount } = getStep(\n domain,\n labelBoundsList,\n labelGap,\n Math.floor(\n labelBoundsList.reduce((min, curBounds) => {\n return Math.min(min, curBounds.width(), curBounds.height());\n }, Number.MAX_VALUE) / incrementUnit\n ) // 给step赋上合适的初值,有效改善外层循环次数\n );\n\n scaleTicks = (scale as BandScale).stepTicks(step);\n scaleTicks = scaleTicks.slice(0, scaleTicks.length - delCount);\n } else {\n scaleTicks = scale.domain();\n }\n\n return convertDomainToTickData(scaleTicks, op);\n};\n\n/** 计算合适的step */\nconst getStep = (domain: any[], labelBoundsList: AABBBounds[], labelGap: number, defaultStep: number) => {\n let step = defaultStep;\n // 通过循环来寻找最小的step,使:如果在这个step下采样,轴标签互不遮挡\n do {\n let success = true;\n step++;\n let ptr = 0;\n do {\n if (ptr + step < domain.length && labelOverlap(labelBoundsList[ptr], labelBoundsList[ptr + step], labelGap)) {\n success = false;\n }\n ptr += step;\n } while (success && ptr < domain.length);\n if (success) {\n break;\n }\n } while (step <= domain.length);\n\n let delCount = 0;\n if (domain.length > 2) {\n let ptr = domain.length - (domain.length % step);\n if (ptr >= domain.length) {\n ptr -= step;\n }\n // 判断首尾是否互相覆盖\n while (ptr > 0 && labelOverlap(labelBoundsList[0], labelBoundsList[ptr])) {\n delCount++;\n ptr -= step;\n }\n }\n\n return {\n step,\n delCount\n };\n};\n"]}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { isContinuous, isDiscrete } from "@visactor/vscale";
|
|
2
|
-
|
|
3
|
-
import { continuousTicks } from "./continuous";
|
|
4
|
-
|
|
5
|
-
import { linearDiscreteTicks } from "./discrete/linear";
|
|
6
|
-
|
|
7
|
-
import { polarAngleAxisDiscreteTicks } from "./discrete/polar-angle";
|
|
8
|
-
|
|
9
|
-
import { convertDomainToTickData } from "./util";
|
|
10
|
-
|
|
11
|
-
export const ticks = (scale, op) => {
|
|
12
|
-
if (isContinuous(scale.type)) return continuousTicks(scale, op);
|
|
13
|
-
if (isDiscrete(scale.type)) {
|
|
14
|
-
if ("cartesian" === op.coordinateType) return linearDiscreteTicks(scale, op);
|
|
15
|
-
if ("polar" === op.coordinateType && "angle" === op.axisOrientType) return polarAngleAxisDiscreteTicks(scale, op);
|
|
16
|
-
}
|
|
17
|
-
return convertDomainToTickData(scale.domain(), op);
|
|
18
|
-
};
|
|
19
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["components/util/tick-data/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,QAAQ,CAAC;AAGjD,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,KAAiB,EAAE,EAAO,EAAS,EAAE;IACzD,IAAI,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;QAC5B,OAAO,eAAe,CAAC,KAAwB,EAAE,EAAE,CAAC,CAAC;KACtD;SAAM,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;QACjC,IAAI,EAAE,CAAC,cAAc,KAAK,WAAW,EAAE;YACrC,OAAO,mBAAmB,CAAC,KAAkB,EAAE,EAAS,CAAC,CAAC;SAC3D;aAAM,IAAI,EAAE,CAAC,cAAc,KAAK,OAAO,EAAE;YACxC,IAAI,EAAE,CAAC,cAAc,KAAK,OAAO,EAAE;gBACjC,OAAO,2BAA2B,CAAC,KAAkB,EAAE,EAAS,CAAC,CAAC;aACnE;SACF;KACF;IACD,OAAO,uBAAuB,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;AACrD,CAAC,CAAC","file":"index.js","sourcesContent":["import type { BandScale, ContinuousScale, IBaseScale } from '@visactor/vscale';\n// eslint-disable-next-line no-duplicate-imports\nimport { isContinuous, isDiscrete } from '@visactor/vscale';\nimport { continuousTicks } from './continuous';\nimport { linearDiscreteTicks } from './discrete/linear';\nimport { polarAngleAxisDiscreteTicks } from './discrete/polar-angle';\nimport { convertDomainToTickData } from './util';\n\n// 总入口\nexport const ticks = (scale: IBaseScale, op: any): any[] => {\n if (isContinuous(scale.type)) {\n return continuousTicks(scale as ContinuousScale, op);\n } else if (isDiscrete(scale.type)) {\n if (op.coordinateType === 'cartesian') {\n return linearDiscreteTicks(scale as BandScale, op as any);\n } else if (op.coordinateType === 'polar') {\n if (op.axisOrientType === 'angle') {\n return polarAngleAxisDiscreteTicks(scale as BandScale, op as any);\n }\n }\n }\n return convertDomainToTickData(scale.domain(), op);\n};\n"]}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { IBaseScale } from '@visactor/vscale';
|
|
2
|
-
import type { IBoundsLike } from '@visactor/vutils';
|
|
3
|
-
import { AABBBounds } from '@visactor/vutils';
|
|
4
|
-
import { type IGraphic } from '@visactor/vrender';
|
|
5
|
-
export declare const radians: (angle?: number) => number;
|
|
6
|
-
export declare const convertDomainToTickData: (domain: any[], op: any) => any[];
|
|
7
|
-
export declare const labelOverlap: (prevLabel: AABBBounds, nextLabel: AABBBounds, gap?: number) => boolean;
|
|
8
|
-
export declare const labelDistance: (prevLabel: AABBBounds, nextLabel: AABBBounds) => [number, number];
|
|
9
|
-
export declare function intersect(a: IBoundsLike, b: IBoundsLike, sep: number): boolean;
|
|
10
|
-
export interface ILabelItem<T> extends Pick<IGraphic, 'AABBBounds'> {
|
|
11
|
-
value?: T;
|
|
12
|
-
}
|
|
13
|
-
export declare function hasOverlap<T>(items: ILabelItem<T>[], pad: number): boolean;
|
|
14
|
-
export declare const getCartesianLabelBounds: (scale: IBaseScale, domain: any[], op: any) => AABBBounds[];
|
|
15
|
-
export declare const getPolarAngleLabelBounds: (scale: IBaseScale, domain: any[], op: any) => AABBBounds[];
|
|
16
|
-
export declare function getAxisLabelOffset(axisSpec: any): number;
|
|
17
|
-
export declare function angleLabelOrientAttribute(angle: number): {
|
|
18
|
-
align: any;
|
|
19
|
-
baseline: any;
|
|
20
|
-
};
|
|
21
|
-
export declare function normalizeAngle(angle: number): number;
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { TextMeasure, degreeToRadian, isValidNumber, AABBBounds, get, polarToCartesian } from "@visactor/vutils";
|
|
2
|
-
|
|
3
|
-
import { getTextBounds } from "@visactor/vrender";
|
|
4
|
-
|
|
5
|
-
const DEFAULT_TEXT_FONT_FAMILY = "PingFang SC,Microsoft Yahei,system-ui,-apple-system,segoe ui,Roboto,Helvetica,Arial,sans-serif, apple color emoji,segoe ui emoji,segoe ui symbol", DEFAULT_TEXT_FONT_SIZE = 14, initTextMeasure = (textSpec, option, useNaiveCanvas) => new TextMeasure(Object.assign({
|
|
6
|
-
defaultFontParams: {
|
|
7
|
-
fontFamily: DEFAULT_TEXT_FONT_FAMILY,
|
|
8
|
-
fontSize: 14
|
|
9
|
-
},
|
|
10
|
-
getTextBounds: useNaiveCanvas ? void 0 : getTextBounds,
|
|
11
|
-
specialCharSet: "-/: .,@%'\"~" + TextMeasure.ALPHABET_CHAR_SET + TextMeasure.ALPHABET_CHAR_SET.toUpperCase()
|
|
12
|
-
}, null != option ? option : {}), textSpec);
|
|
13
|
-
|
|
14
|
-
export const radians = angle => isValidNumber(angle) ? degreeToRadian(angle) : null;
|
|
15
|
-
|
|
16
|
-
export const convertDomainToTickData = (domain, op) => domain.map(((t, index) => ({
|
|
17
|
-
index: index,
|
|
18
|
-
value: t
|
|
19
|
-
})));
|
|
20
|
-
|
|
21
|
-
export const labelOverlap = (prevLabel, nextLabel, gap = 0) => {
|
|
22
|
-
const prevBounds = new AABBBounds(prevLabel).expand(gap / 2), nextBounds = new AABBBounds(nextLabel).expand(gap / 2);
|
|
23
|
-
return prevBounds.intersects(nextBounds);
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export const labelDistance = (prevLabel, nextLabel) => {
|
|
27
|
-
let horizontal = 0;
|
|
28
|
-
prevLabel.x2 < nextLabel.x1 ? horizontal = nextLabel.x1 - prevLabel.x2 : nextLabel.x2 < prevLabel.x1 && (horizontal = prevLabel.x1 - nextLabel.x2);
|
|
29
|
-
let vertical = 0;
|
|
30
|
-
return prevLabel.y2 < nextLabel.y1 ? vertical = nextLabel.y1 - prevLabel.y2 : nextLabel.y2 < prevLabel.y1 && (vertical = prevLabel.y1 - nextLabel.y2),
|
|
31
|
-
[ horizontal, vertical ];
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export function intersect(a, b, sep) {
|
|
35
|
-
return sep > Math.max(b.x1 - a.x2, a.x1 - b.x2, b.y1 - a.y2, a.y1 - b.y2);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function hasOverlap(items, pad) {
|
|
39
|
-
for (let b, i = 1, n = items.length, a = items[0]; i < n; a = b, ++i) if (b = items[i],
|
|
40
|
-
intersect(a.AABBBounds, b.AABBBounds, pad)) return !0;
|
|
41
|
-
return !1;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const MIN_TICK_GAP = 12;
|
|
45
|
-
|
|
46
|
-
export const getCartesianLabelBounds = (scale, domain, op) => {
|
|
47
|
-
var _a;
|
|
48
|
-
const {labelStyle: labelStyle, axisOrientType: axisOrientType, labelFlush: labelFlush, labelFormatter: labelFormatter, startAngle: startAngle = 0} = op, labelAngle = null !== (_a = labelStyle.angle) && void 0 !== _a ? _a : 0, isHorizontal = [ "bottom", "top" ].includes(axisOrientType), isVertical = [ "left", "right" ].includes(axisOrientType);
|
|
49
|
-
let orientAngle = startAngle;
|
|
50
|
-
var angle;
|
|
51
|
-
isHorizontal ? orientAngle = 0 : isVertical && (orientAngle = isValidNumber(angle = -90) ? degreeToRadian(angle) : null);
|
|
52
|
-
const textMeasure = initTextMeasure(labelStyle), labelBoundsList = domain.map(((v, i) => {
|
|
53
|
-
var _a, _b;
|
|
54
|
-
const str = labelFormatter ? labelFormatter(v) : `${v}`, {width: width, height: height} = textMeasure.quickMeasure(str), textWidth = Math.max(width, 12), textHeight = Math.max(height, 12), pos = scale.scale(v);
|
|
55
|
-
let align, baseline, textX = Math.cos(orientAngle) * pos, textY = -Math.sin(orientAngle) * pos;
|
|
56
|
-
align = labelFlush && isHorizontal && 0 === i ? "left" : labelFlush && isHorizontal && i === domain.length - 1 ? "right" : null !== (_a = labelStyle.textAlign) && void 0 !== _a ? _a : "center",
|
|
57
|
-
"right" === align ? textX -= textWidth : "center" === align && (textX -= textWidth / 2),
|
|
58
|
-
baseline = labelFlush && isVertical && 0 === i ? "top" : labelFlush && isVertical && i === domain.length - 1 ? "bottom" : null !== (_b = labelStyle.textBaseline) && void 0 !== _b ? _b : "middle",
|
|
59
|
-
"bottom" === baseline ? textY -= textHeight : "middle" === baseline && (textY -= textHeight / 2);
|
|
60
|
-
return (new AABBBounds).set(textX, textY, textX + textWidth, textY + textHeight).rotate(labelAngle, textX + textWidth / 2, textY + textHeight / 2);
|
|
61
|
-
}));
|
|
62
|
-
return labelBoundsList;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
export const getPolarAngleLabelBounds = (scale, domain, op) => {
|
|
66
|
-
var _a;
|
|
67
|
-
const {labelStyle: labelStyle, getRadius: getRadius, axisSpec: axisSpec, labelFormatter: labelFormatter} = op, radius = null == getRadius ? void 0 : getRadius(), labelAngle = null !== (_a = labelStyle.angle) && void 0 !== _a ? _a : 0, labelOffset = getAxisLabelOffset(axisSpec), textMeasure = initTextMeasure(labelStyle);
|
|
68
|
-
return domain.map((v => {
|
|
69
|
-
const str = labelFormatter ? labelFormatter(v) : `${v}`, {width: width, height: height} = textMeasure.quickMeasure(str), textWidth = Math.max(width, 12), textHeight = Math.max(height, 12), angle = scale.scale(v);
|
|
70
|
-
let textX = 0, textY = 0;
|
|
71
|
-
const orient = angleLabelOrientAttribute(angle), {x: x, y: y} = polarToCartesian({
|
|
72
|
-
x: 0,
|
|
73
|
-
y: 0
|
|
74
|
-
}, radius + labelOffset, angle);
|
|
75
|
-
textX = x + ("right" === orient.align ? -textWidth : "center" === orient.align ? -textWidth / 2 : 0),
|
|
76
|
-
textY = y + ("bottom" === orient.baseline ? -textHeight : "middle" === orient.baseline ? -textHeight / 2 : 0);
|
|
77
|
-
return (new AABBBounds).set(textX, textY, textX + textWidth, textY + textHeight).rotate(labelAngle, textX + textWidth / 2, textY + textHeight / 2);
|
|
78
|
-
}));
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
export function getAxisLabelOffset(axisSpec) {
|
|
82
|
-
let labelOffset = 0;
|
|
83
|
-
return get(axisSpec, "tick.visible") && (labelOffset += get(axisSpec, "tick.tickSize")),
|
|
84
|
-
get(axisSpec, "label.visible") && (labelOffset += get(axisSpec, "label.space")),
|
|
85
|
-
labelOffset;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export function angleLabelOrientAttribute(angle) {
|
|
89
|
-
let align = "center", baseline = "middle";
|
|
90
|
-
return align = (angle = normalizeAngle(angle)) >= Math.PI * (5 / 3) || angle <= Math.PI * (1 / 3) ? "left" : angle >= Math.PI * (2 / 3) && angle <= Math.PI * (4 / 3) ? "right" : "center",
|
|
91
|
-
baseline = angle >= Math.PI * (7 / 6) && angle <= Math.PI * (11 / 6) ? "bottom" : angle >= Math.PI * (1 / 6) && angle <= Math.PI * (5 / 6) ? "top" : "middle",
|
|
92
|
-
{
|
|
93
|
-
align: align,
|
|
94
|
-
baseline: baseline
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export function normalizeAngle(angle) {
|
|
99
|
-
for (;angle < 0; ) angle += 2 * Math.PI;
|
|
100
|
-
for (;angle >= 2 * Math.PI; ) angle -= 2 * Math.PI;
|
|
101
|
-
return angle;
|
|
102
|
-
}
|
|
103
|
-
//# sourceMappingURL=util.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["components/util/tick-data/util.ts"],"names":[],"mappings":"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","file":"util.js","sourcesContent":["import type { IBaseScale } from '@visactor/vscale';\nimport type { IBoundsLike, ITextMeasureOption } from '@visactor/vutils';\nimport { TextMeasure, degreeToRadian, isValidNumber, AABBBounds, get, polarToCartesian } from '@visactor/vutils';\nimport { getTextBounds, type IGraphic } from '@visactor/vrender';\n\nconst DEFAULT_TEXT_FONT_FAMILY =\n // eslint-disable-next-line max-len\n 'PingFang SC,Microsoft Yahei,system-ui,-apple-system,segoe ui,Roboto,Helvetica,Arial,sans-serif, apple color emoji,segoe ui emoji,segoe ui symbol';\n\nconst DEFAULT_TEXT_FONT_SIZE = 14;\n\nconst initTextMeasure = (\n textSpec?: Partial<any>,\n option?: Partial<ITextMeasureOption>,\n useNaiveCanvas?: boolean\n): TextMeasure<any> => {\n return new TextMeasure<any>(\n {\n defaultFontParams: {\n fontFamily: DEFAULT_TEXT_FONT_FAMILY,\n fontSize: DEFAULT_TEXT_FONT_SIZE\n },\n getTextBounds: useNaiveCanvas ? undefined : getTextBounds,\n specialCharSet: '-/: .,@%\\'\"~' + TextMeasure.ALPHABET_CHAR_SET + TextMeasure.ALPHABET_CHAR_SET.toUpperCase(),\n ...(option ?? {})\n },\n textSpec\n );\n};\n\nexport const radians = (angle?: number) => {\n if (!isValidNumber(angle)) {\n return null;\n }\n return degreeToRadian(angle);\n};\n\nexport const convertDomainToTickData = (domain: any[], op: any): any[] => {\n const ticks = domain.map((t: number, index: number) => {\n return {\n index,\n value: t\n // label: op.labelFormatter ? op.labelFormatter(t) : `${t}`\n };\n });\n return ticks;\n};\n\n/** 判断两个label是否有重叠情况 */\nexport const labelOverlap = (prevLabel: AABBBounds, nextLabel: AABBBounds, gap: number = 0): boolean => {\n const prevBounds = new AABBBounds(prevLabel).expand(gap / 2);\n const nextBounds = new AABBBounds(nextLabel).expand(gap / 2);\n return prevBounds.intersects(nextBounds);\n};\n\n/** 判断两个不相交的label相隔的距离 */\nexport const labelDistance = (prevLabel: AABBBounds, nextLabel: AABBBounds): [number, number] => {\n let horizontal = 0;\n if (prevLabel.x2 < nextLabel.x1) {\n horizontal = nextLabel.x1 - prevLabel.x2;\n } else if (nextLabel.x2 < prevLabel.x1) {\n horizontal = prevLabel.x1 - nextLabel.x2;\n }\n\n let vertical = 0;\n if (prevLabel.y2 < nextLabel.y1) {\n vertical = nextLabel.y1 - prevLabel.y2;\n } else if (nextLabel.y2 < prevLabel.y1) {\n vertical = prevLabel.y1 - nextLabel.y2;\n }\n\n return [horizontal, vertical];\n};\n\nexport function intersect(a: IBoundsLike, b: IBoundsLike, sep: number) {\n return sep > Math.max(b.x1 - a.x2, a.x1 - b.x2, b.y1 - a.y2, a.y1 - b.y2);\n}\n\nexport interface ILabelItem<T> extends Pick<IGraphic, 'AABBBounds'> {\n value?: T;\n}\n\nexport function hasOverlap<T>(items: ILabelItem<T>[], pad: number): boolean {\n for (let i = 1, n = items.length, a = items[0], b; i < n; a = b, ++i) {\n b = items[i];\n if (intersect(a.AABBBounds, b.AABBBounds, pad)) {\n return true;\n }\n }\n return false;\n}\n\nconst MIN_TICK_GAP = 12;\n\nexport const getCartesianLabelBounds = (scale: IBaseScale, domain: any[], op: any): AABBBounds[] => {\n const { labelStyle, axisOrientType, labelFlush, labelFormatter, startAngle = 0 } = op;\n const labelAngle = labelStyle.angle ?? 0;\n const isHorizontal = ['bottom', 'top'].includes(axisOrientType);\n const isVertical = ['left', 'right'].includes(axisOrientType);\n let orientAngle = startAngle;\n if (isHorizontal) {\n orientAngle = 0;\n } else if (isVertical) {\n orientAngle = radians(-90);\n }\n\n const textMeasure = initTextMeasure(labelStyle);\n const labelBoundsList = domain.map((v: any, i: number) => {\n const str = labelFormatter ? labelFormatter(v) : `${v}`;\n\n // 估算文本宽高\n const { width, height } = textMeasure.quickMeasure(str);\n const textWidth = Math.max(width, MIN_TICK_GAP);\n const textHeight = Math.max(height, MIN_TICK_GAP);\n\n // 估算文本位置\n const pos = scale.scale(v);\n let textX = Math.cos(orientAngle) * pos;\n let textY = -Math.sin(orientAngle) * pos;\n\n let align: any;\n if (labelFlush && isHorizontal && i === 0) {\n align = 'left';\n } else if (labelFlush && isHorizontal && i === domain.length - 1) {\n align = 'right';\n } else {\n align = labelStyle.textAlign ?? 'center';\n }\n if (align === 'right') {\n textX -= textWidth;\n } else if (align === 'center') {\n textX -= textWidth / 2;\n }\n\n let baseline: any;\n if (labelFlush && isVertical && i === 0) {\n baseline = 'top';\n } else if (labelFlush && isVertical && i === domain.length - 1) {\n baseline = 'bottom';\n } else {\n baseline = labelStyle.textBaseline ?? 'middle';\n }\n if (baseline === 'bottom') {\n textY -= textHeight;\n } else if (baseline === 'middle') {\n textY -= textHeight / 2;\n }\n\n // 计算 label 包围盒\n const bounds = new AABBBounds()\n .set(textX, textY, textX + textWidth, textY + textHeight)\n .rotate(labelAngle, textX + textWidth / 2, textY + textHeight / 2);\n return bounds;\n });\n\n return labelBoundsList;\n};\n\nexport const getPolarAngleLabelBounds = (scale: IBaseScale, domain: any[], op: any): AABBBounds[] => {\n const { labelStyle, getRadius, axisSpec, labelFormatter } = op;\n const radius = getRadius?.();\n const labelAngle = labelStyle.angle ?? 0;\n\n const labelOffset = getAxisLabelOffset(axisSpec);\n\n const textMeasure = initTextMeasure(labelStyle);\n const labelBoundsList = domain.map((v: any) => {\n const str = labelFormatter ? labelFormatter(v) : `${v}`;\n\n // 估算文本宽高\n const { width, height } = textMeasure.quickMeasure(str);\n const textWidth = Math.max(width, MIN_TICK_GAP);\n const textHeight = Math.max(height, MIN_TICK_GAP);\n\n // 估算文本位置\n const angle = scale.scale(v);\n let textX = 0;\n let textY = 0;\n const orient = angleLabelOrientAttribute(angle);\n const { x, y } = polarToCartesian({ x: 0, y: 0 }, radius + labelOffset, angle);\n textX = x + (orient.align === 'right' ? -textWidth : orient.align === 'center' ? -textWidth / 2 : 0);\n textY = y + (orient.baseline === 'bottom' ? -textHeight : orient.baseline === 'middle' ? -textHeight / 2 : 0);\n\n // 计算 label 包围盒\n const bounds = new AABBBounds()\n .set(textX, textY, textX + textWidth, textY + textHeight)\n .rotate(labelAngle, textX + textWidth / 2, textY + textHeight / 2);\n return bounds;\n });\n\n return labelBoundsList;\n};\n\nexport function getAxisLabelOffset(axisSpec: any) {\n let labelOffset = 0;\n if (get(axisSpec, 'tick.visible')) {\n labelOffset += get(axisSpec, 'tick.tickSize');\n }\n\n if (get(axisSpec, 'label.visible')) {\n labelOffset += get(axisSpec, 'label.space');\n }\n\n return labelOffset;\n}\n\n/**\n * 计算对应角度下的角度轴标签定位属性\n * @param angle 弧度角,需要注意是逆时针计算的\n * @returns\n */\nexport function angleLabelOrientAttribute(angle: number) {\n let align: any = 'center';\n let baseline: any = 'middle';\n\n angle = normalizeAngle(angle);\n\n // left: 5/3 - 1/3; right: 2/3 - 4/3; center: 5/3 - 1/3 & 2/3 - 4/3\n if (angle >= Math.PI * (5 / 3) || angle <= Math.PI * (1 / 3)) {\n align = 'left';\n } else if (angle >= Math.PI * (2 / 3) && angle <= Math.PI * (4 / 3)) {\n align = 'right';\n } else {\n align = 'center';\n }\n\n // bottom: 7/6 - 11/6; top: 1/6 - 5/6; middle: 11/6 - 1/6 & 5/6 - 7/6\n if (angle >= Math.PI * (7 / 6) && angle <= Math.PI * (11 / 6)) {\n baseline = 'bottom';\n } else if (angle >= Math.PI * (1 / 6) && angle <= Math.PI * (5 / 6)) {\n baseline = 'top';\n } else {\n baseline = 'middle';\n }\n\n return { align, baseline };\n}\n\n/**\n * 角度标准化处理\n * @param angle 弧度角\n */\nexport function normalizeAngle(angle: number): number {\n while (angle < 0) {\n angle += Math.PI * 2;\n }\n while (angle >= Math.PI * 2) {\n angle -= Math.PI * 2;\n }\n return angle;\n}\n"]}
|