You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by ov...@apache.org on 2022/07/04 09:32:28 UTC
[echarts] 01/02: fix(axis): add time axis special tick logic
This is an automated email from the ASF dual-hosted git repository.
ovilia pushed a commit to branch fix-17198
in repository https://gitbox.apache.org/repos/asf/echarts.git
commit a9a39296669299ed5951526bfe8c6cc2859296e7
Author: Ovilia <zw...@gmail.com>
AuthorDate: Mon Jul 4 15:04:01 2022 +0800
fix(axis): add time axis special tick logic
---
src/coord/Axis.ts | 1 +
src/coord/axisTickLabelBuilder.ts | 112 ++++++++++++++++++++++++++++++++++++++
2 files changed, 113 insertions(+)
diff --git a/src/coord/Axis.ts b/src/coord/Axis.ts
index 7a334a0a4..ebbfbb221 100644
--- a/src/coord/Axis.ts
+++ b/src/coord/Axis.ts
@@ -193,6 +193,7 @@ class Axis {
this, ticksCoords, alignWithLabel, opt.clamp
);
+ console.log('ticksCoords', ticksCoords);
return ticksCoords;
}
diff --git a/src/coord/axisTickLabelBuilder.ts b/src/coord/axisTickLabelBuilder.ts
index fbc2e5c97..b56442573 100644
--- a/src/coord/axisTickLabelBuilder.ts
+++ b/src/coord/axisTickLabelBuilder.ts
@@ -31,6 +31,7 @@ import { AxisBaseOption } from './axisCommonTypes';
import OrdinalScale from '../scale/Ordinal';
import { AxisBaseModel } from './AxisBaseModel';
import type Axis2D from './cartesian/Axis2D';
+import { TimeScaleTick } from '../util/types';
type CacheKey = string | number;
@@ -72,6 +73,8 @@ export function createAxisLabels(axis: Axis): {
// Only ordinal scale support tick interval
return axis.type === 'category'
? makeCategoryLabels(axis)
+ : axis.type === 'time'
+ ? makeTimeLabels(axis)
: makeRealNumberLabels(axis);
}
@@ -90,6 +93,8 @@ export function createAxisTicks(axis: Axis, tickModel: AxisBaseModel): {
// Only ordinal scale support tick interval
return axis.type === 'category'
? makeCategoryTicks(axis, tickModel)
+ : axis.type === 'time'
+ ? makeTimeTicks(axis, tickModel)
: {ticks: zrUtil.map(axis.scale.getTicks(), tick => tick.value) };
}
@@ -102,6 +107,15 @@ function makeCategoryLabels(axis: Axis) {
: result;
}
+function makeTimeLabels(axis: Axis) {
+ const labelModel = axis.getLabelModel();
+ const result = makeTimeLabelsActually(axis, labelModel);
+
+ return (!labelModel.get('show') || axis.scale.isBlank())
+ ? {labels: []}
+ : result;
+}
+
function makeCategoryLabelsActually(axis: Axis, labelModel: Model<AxisBaseOption['axisLabel']>) {
const labelsCache = getListCache(axis, 'labels');
const optionLabelInterval = getOptionCategoryInterval(labelModel);
@@ -129,6 +143,104 @@ function makeCategoryLabelsActually(axis: Axis, labelModel: Model<AxisBaseOption
});
}
+function makeTimeLabelsActually(axis: Axis, labelModel: Model<AxisBaseOption['axisLabel']>) {
+ const labelsCache = getListCache(axis, 'labels');
+ const timeKey = 'time'; // TODO: change key name
+ const result = listCacheGet(labelsCache, timeKey);
+
+ if (result) {
+ return result;
+ }
+
+ const labels = makeNonOverlappedTimeLabels(axis);
+
+ // Cache to avoid calling interval function repeatly.
+ return listCacheSet(labelsCache, timeKey, {
+ labels: labels
+ });
+}
+
+function makeNonOverlappedTimeLabels(axis: Axis): MakeLabelsResultObj[];
+function makeNonOverlappedTimeLabels(axis: Axis, onlyTick: false): MakeLabelsResultObj[];
+function makeNonOverlappedTimeLabels(axis: Axis, onlyTick: true): number[];
+function makeNonOverlappedTimeLabels(axis: Axis, onlyTick?: boolean) {
+ const ticks = axis.scale.getTicks() as TimeScaleTick[];
+ const ordinalScale = axis.scale as OrdinalScale;
+ const labelFormatter = makeLabelFormatter(axis);
+
+ const result: (MakeLabelsResultObj | number)[] = [];
+
+ function addItem(tickValue: number) {
+ const tickObj = { value: tickValue };
+ result.push(onlyTick
+ ? tickValue
+ : {
+ formattedLabel: labelFormatter(tickObj),
+ rawLabel: ordinalScale.getLabel(tickObj), // TODO: ?
+ tickValue: tickValue
+ }
+ );
+ }
+
+ let lastMaxLevel = Number.MAX_VALUE;
+ let maxLevel;
+ while (true) {
+ maxLevel = -1;
+
+ for (let i = 0; i < ticks.length; i++) {
+ if (ticks[i].level > maxLevel && ticks[i].level < lastMaxLevel) {
+ maxLevel = ticks[i].level;
+ }
+ }
+
+ if (maxLevel < 0) {
+ break;
+ }
+
+ for (let i = 0; i < ticks.length; i++) {
+ const tick = ticks[i];
+ if (tick.level === maxLevel) {
+ // Add the tick only if it has no overlap with current ones
+ // TODO:
+ addItem(tick.value);
+ }
+ }
+
+ if (maxLevel <= 0) {
+ break;
+ }
+ lastMaxLevel = maxLevel;
+ }
+ return result;
+}
+
+function makeTimeTicks(axis: Axis, tickModel: AxisBaseModel) {
+ const ticksCache = getListCache(axis, 'ticks');
+ const result = listCacheGet(ticksCache, 'time');
+
+ if (result) {
+ return result;
+ }
+
+ let ticks: number[];
+
+ // Optimize for the case that large category data and no label displayed,
+ // we should not return all ticks.
+ if (!tickModel.get('show') || axis.scale.isBlank()) {
+ ticks = [];
+ }
+
+ const labelsResult = makeTimeLabelsActually(axis, axis.getLabelModel());
+ ticks = zrUtil.map(labelsResult.labels, function (labelItem) {
+ return labelItem.tickValue;
+ });
+
+ // Cache to avoid calling interval function repeatly.
+ return listCacheSet(ticksCache, 'time', {
+ ticks: ticks
+ });
+}
+
function makeCategoryTicks(axis: Axis, tickModel: AxisBaseModel) {
const ticksCache = getListCache(axis, 'ticks');
const optionTickInterval = getOptionCategoryInterval(tickModel);
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org