Skip to content

Commit

Permalink
Merge pull request #202 from VisActor/feat/pivot-chart-axis
Browse files Browse the repository at this point in the history
feat: add basic axis component auto width function
  • Loading branch information
Rui-Sun committed Aug 8, 2023
2 parents f93708f + 12ff925 commit 2dd8f60
Show file tree
Hide file tree
Showing 19 changed files with 450 additions and 257 deletions.
2 changes: 1 addition & 1 deletion packages/vtable/examples/pivot-chart/pivotChart-3W.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ export function createTable() {
window.tableInstance = tableInstance;

bindDebugTool(tableInstance.scenegraph.stage as any, {
customGrapicKeys: ['role', '_updateTag']
customGrapicKeys: ['role', 'row']
});
});
}
8 changes: 4 additions & 4 deletions packages/vtable/examples/pivot-chart/pivotChart-adaptive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ export function createTable() {
yField: '230417171050011',
seriesField: '230417171050030',
axes: [
{ orient: 'left', visible: true, label: { visible: true } },
{ orient: 'left', visible: true, label: { visible: true }, title: { visible: true } },
{ orient: 'bottom', visible: true }
],
bar: {
Expand Down Expand Up @@ -207,7 +207,7 @@ export function createTable() {
}
],
axes: [
{ orient: 'left', visible: true, label: { visible: true } },
{ orient: 'left', visible: true, label: { visible: true }, title: { visible: true } },
{ orient: 'bottom', visible: true }
]
}
Expand Down Expand Up @@ -237,7 +237,7 @@ export function createTable() {
yField: '230707112948009',
seriesField: '230417171050030',
axes: [
{ orient: 'left', visible: true, label: { visible: true } },
{ orient: 'left', visible: true, label: { visible: true }, title: { visible: true } },
{ orient: 'bottom', visible: true }
],
line: {
Expand Down Expand Up @@ -9263,7 +9263,7 @@ export function createTable() {
defaultRowHeight: 200,
defaultHeaderRowHeight: 30,
defaultColWidth: 280,
defaultHeaderColWidth: [80, 50],
defaultHeaderColWidth: [80, 'auto'],

corner: {
titleOnDimension: 'row',
Expand Down
5 changes: 2 additions & 3 deletions packages/vtable/src/components/axis/axis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export class CartesianAxis {
this.type = option.type ?? 'band';
this.inverse = 'inverse' in option ? !!option.inverse : false;
if (option.type === 'band') {
this.data = option.data;
this.data = option.domain;
}

this.initScale();
Expand Down Expand Up @@ -190,8 +190,7 @@ export class CartesianAxis {

updateScaleRange() {
const { width, height } = this.getLayoutRect();
// const inverse = this.option.inverse;
const inverse = false;
const inverse = (this.option as any).inverse || false;
let newRange: [number, number] = [0, 0];
if (isXAxis(this.orient)) {
if (isValidNumber(width)) {
Expand Down
80 changes: 80 additions & 0 deletions packages/vtable/src/components/axis/get-axis-component-size.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { merge } from '@visactor/vutils';
import type { BaseTableAPI } from '../../ts-types/base-table';
import type { ICellAxisOption } from '../../ts-types/component/axis';
import { commonAxis } from './get-axis-attributes';

/**
* @description: compuational vertical axis width
* @param {ICellAxisOption} config
* @return {*}
*/
export function computeAxisConpomentWidth(config: ICellAxisOption, table: BaseTableAPI) {
const attribute = merge({}, commonAxis, config);
// tick
const tickWidth = attribute.tick.width ?? 4;

// text
let labelWidth = 0;
if (attribute.label.visible) {
if (attribute.type === 'band') {
const domain = attribute.domain;
domain.forEach((text: string) => {
labelWidth = Math.max(
labelWidth,
table.measureText(text, {
fontSize: attribute.label?.style?.fontSize,
fontFamily: attribute.label?.style?.fontFamily
}).width
);
});
} else {
const range = attribute.range;
const minNumber = Math.abs(range.min) > 1 ? Math.round(range.min) : range.min;
const maxNumber = Math.abs(range.max) > 1 ? Math.round(range.max) : range.max;
// abs>1取整保留两位有效数字,abs<1保留一位有效数字
const minString = formatDecimal(minNumber);
const maxString = formatDecimal(maxNumber);
// 这里测量的是预估的最大最小range,与实际现实的label可能不同
[minString, maxString].forEach(text => {
labelWidth = Math.max(
labelWidth,
table.measureText(text, {
fontSize: attribute.label?.style?.fontSize,
fontFamily: attribute.label?.style?.fontFamily
}).width + 2
);
});
}
labelWidth += attribute.label.space ?? 4;
}

// title
let titleWidth = 0;
if (attribute.title.visible && attribute.title.text) {
if (attribute.title.autoRotate) {
titleWidth =
table.measureText(attribute.title.text as string, {
fontSize: attribute.title?.style?.fontSize,
fontFamily: attribute.title?.style?.fontFamily
}).height + 2;
} else {
titleWidth =
table.measureText(attribute.title.text as string, {
fontSize: attribute.title?.style?.fontSize,
fontFamily: attribute.title?.style?.fontFamily
}).width + 2;
}
titleWidth += attribute.title.space ?? 4;
}

return tickWidth + labelWidth + titleWidth;
}

// 保留一位有效数字
function formatDecimal(number: number) {
if (typeof number !== 'number') {
number = Number(number);
}

return Number(number.toPrecision(1)).toString(); // 避免科学计数法
}
5 changes: 5 additions & 0 deletions packages/vtable/src/components/axis/linear-scale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ export class LinearAxisScale {
setExtraAttrFromSpec(nice: boolean, zero: boolean, range: Required<IRange>, expand?: IRange) {
this.nice = nice;
this.zero = zero;
// this.domain = range;
if (this.zero) {
range.min = Math.min(range.min, 0);
range.max = Math.max(range.max, 0);
}
this.domain = range;
this.expand = expand;
}
Expand Down
106 changes: 10 additions & 96 deletions packages/vtable/src/core/BaseTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -500,13 +500,13 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI {
/**
* Get the default column width.
*/
get defaultHeaderColWidth(): number | number[] {
get defaultHeaderColWidth(): (number | 'auto') | (number | 'auto')[] {
return this.internalProps.defaultHeaderColWidth;
}
/**
* Set the default column width.
*/
set defaultHeaderColWidth(defaultHeaderColWidth: number | number[]) {
set defaultHeaderColWidth(defaultHeaderColWidth: (number | 'auto') | (number | 'auto')[]) {
this.internalProps.defaultHeaderColWidth = defaultHeaderColWidth;
this.options.defaultHeaderColWidth = defaultHeaderColWidth;
}
Expand Down Expand Up @@ -632,84 +632,13 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI {
* @private
*/
private _colWidthDefineToPxWidth(width: string | number): number {
if (isAutoDefine(width)) {
return _toPxWidth(this, this._calculateAutoColWidthExpr());
if (width === 'auto') {
// hack for defaultWidht support 'auto'
return 0;
}
return _toPxWidth(this, width);
}

/**
* 计算列宽为auto情况下的宽度.
* @returns {string}
* @private
*/
private _calculateAutoColWidthExpr(): string {
const fullWidth = this.internalProps.calcWidthContext.full;
let sumMin = 0;
const others: (string | number)[] = [];
let autoCount = 0;
const hasLimitsOnAuto = [];
for (let col = 0; col < this.internalProps.colCount; col++) {
const def = this.getColWidthDefine(col);
const limits = this._getColWidthLimits(col);

if (isAutoDefine(def)) {
if (limits) {
hasLimitsOnAuto.push(limits);
if (limits.min) {
sumMin += limits.min;
}
}
autoCount++;
} else {
let expr = def;
if (limits) {
const orgWidth = _toPxWidth(this, expr);
const newWidth = _applyColWidthLimits(limits, orgWidth);
if (orgWidth !== newWidth) {
expr = `${newWidth}px`;
}
sumMin += newWidth;
}
others.push(expr);
}
if (sumMin > fullWidth) {
return '0px';
}
}
if (hasLimitsOnAuto.length && others.length) {
const autoPx =
(fullWidth - _toPxWidth(this, `calc(${others.map(c => (typeof c === 'number' ? `${c}px` : c)).join(' + ')})`)) /
autoCount;
hasLimitsOnAuto.forEach(limits => {
if (limits.min && autoPx < limits.min) {
others.push(limits.minDef);
autoCount--;
} else if (limits.max && limits.max < autoPx) {
others.push(limits.maxDef);
autoCount--;
}
});
if (autoCount <= 0) {
return `${autoPx}px`;
}
}
if (others.length) {
const strDefs: string[] = [];
let num = 0;
others.forEach(c => {
if (typeof c === 'number') {
num += c;
} else {
strDefs.push(c);
}
});
strDefs.push(`${num}px`);
return `calc((100% - (${strDefs.join(' + ')})) / ${autoCount})`;
}
return `${100 / autoCount}%`;
}

/**
* 获取列宽的最大最小限制
* @param {number} col number of column
Expand Down Expand Up @@ -854,12 +783,7 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI {
} else {
// adjustW = 0;
// use default column width if no width in colWidthsMap
adjustW =
this.isRowHeader(endCol, 0) || this.isCornerHeader(endCol, 0)
? Array.isArray(this.defaultHeaderColWidth)
? this.defaultHeaderColWidth[endCol] ?? this.internalProps.defaultColWidth
: this.defaultHeaderColWidth
: this.internalProps.defaultColWidth;
adjustW = this.getColWidth(endCol);
}
const addWidth = cachedLowerColWidth + adjustW;
// 合法地址存入缓存
Expand All @@ -871,33 +795,23 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI {

let w = 0;
for (let col = startCol; col <= endCol; col++) {
w +=
this.isRowHeader(col, 0) || this.isCornerHeader(col, 0)
? Array.isArray(this.defaultHeaderColWidth)
? this.defaultHeaderColWidth[col] ?? this.internalProps.defaultColWidth
: this.defaultHeaderColWidth
: this.internalProps.defaultColWidth;
w += this.getColWidth(col);
}

this.colWidthsMap.each(startCol, endCol, (width, col) => {
// adaptive模式下,不受max min配置影响,直接使用width
w +=
(this.widthMode === 'adaptive' || (this as any).transpose
? Number(width)
: this._adjustColWidth(col, this._colWidthDefineToPxWidth(width))) -
(this.isRowHeader(col, 0) || this.isCornerHeader(col, 0)
? Array.isArray(this.defaultHeaderColWidth)
? this.defaultHeaderColWidth[col] ?? this.internalProps.defaultColWidth
: this.defaultHeaderColWidth
: this.internalProps.defaultColWidth);
: this._adjustColWidth(col, this._colWidthDefineToPxWidth(width))) - this.getColWidth(col);
});
for (let col = startCol; col <= endCol; col++) {
if (this.colWidthsMap.has(col)) {
continue;
}
const adj = this._adjustColWidth(col, this.internalProps.defaultColWidth);
const adj = this._adjustColWidth(col, this.internalProps.defaultColWidth as number);
if (adj !== this.internalProps.defaultColWidth) {
w += adj - this.internalProps.defaultColWidth;
w += adj - (this.internalProps.defaultColWidth as number);
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/vtable/src/event/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ export class EventManeger {
}

dealColumnResize(xInTable: number, yInTable: number) {
this.table.stateManeger.updateResizeCol(xInTable, xInTable);
this.table.stateManeger.updateResizeCol(xInTable, yInTable);
}

chechColumnMover(eventArgsSet: SceneEvent): boolean {
Expand Down
Loading

0 comments on commit 2dd8f60

Please sign in to comment.