Skip to content

Commit

Permalink
Merge pull request #218 from Jeffy2012/bug-fix
Browse files Browse the repository at this point in the history
修复axis,以及title/ desc的bug
  • Loading branch information
paleface001 committed Nov 15, 2019
2 parents 230b313 + b9bd1c5 commit 32151f8
Show file tree
Hide file tree
Showing 13 changed files with 181 additions and 157 deletions.
20 changes: 20 additions & 0 deletions __tests__/unit/utils-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { isTextUsable, breakText } from '../../src/util/common';

test('check title description usable', () => {
expect(isTextUsable(null)).toBe(false);
expect(isTextUsable(undefined)).toBe(false);
expect(isTextUsable({ visible: false })).toBe(false);
expect(isTextUsable({ visible: true })).toBe(false);
expect(isTextUsable({ visible: true, text: '' })).toBe(false);
expect(isTextUsable({ visible: true, text: ' ' })).toBe(false);
expect(isTextUsable({ visible: true, text: 'title' })).toBe(true);
expect(isTextUsable({})).toBe(false);
});

test('break text by index', () => {
expect(breakText(['a', 'b', 'c'], [1])).toBe(`a
bc`);
expect(breakText(['a', 'b', 'c', 'd'], [1, 2])).toBe(`a
b
cd`);
});
23 changes: 14 additions & 9 deletions src/base/controller/padding.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
import { BBox, Element } from '@antv/g';
import { View } from '@antv/g2';
import { DataPointType } from '@antv/g2/lib/interface';
import * as _ from '@antv/util';
import { ViewLayer } from '../..';

interface ControllerConfig {
plot: ViewLayer;
}

/**
* 处理图表padding的逻辑:
* 注册参与padding的自定义组件
*/

export default class PaddingController {
private plot: any;
private bleeding;
private plot: ViewLayer;
private bleeding: number[];

private innerPaddingComponents: any[] = [];
private outerPaddingComponents: any[] = [];

constructor(cfg) {
_.assign(this, cfg);
constructor(cfg: ControllerConfig) {
this.plot = cfg.plot;
}

public registerPadding(component, type: 'outer' | 'inner' = 'outer') {
public registerPadding(component: any, type: 'outer' | 'inner' = 'outer') {
if (type === 'inner') {
this.innerPaddingComponents.push(component);
} else {
Expand Down Expand Up @@ -52,10 +57,10 @@ export default class PaddingController {
this.plot.render();
}

public processOuterPadding() {
public processOuterPadding(): BBox {
let viewMinX = this.plot.layerBBox.minX;
let viewMaxX = this.plot.layerBBox.maxX;
let viewMinY = _.clone(this.plot.layerBBox.minY);
let viewMinY = this.plot.layerBBox.minY;
let viewMaxY = this.plot.layerBBox.maxY;
_.each(this.outerPaddingComponents, (component) => {
const { position } = component;
Expand All @@ -79,7 +84,7 @@ export default class PaddingController {
private _getInnerAutoPadding() {
const props = this.plot.options;
const view = this.plot.view;
const viewRange = view.get('viewRange');
const viewRange: BBox = view.get('viewRange');
const { maxX, maxY } = viewRange;
const bleeding = this.plot.config.theme.bleeding;
if (_.isArray(bleeding)) {
Expand Down
2 changes: 1 addition & 1 deletion src/base/controller/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default class ThemeController<T extends ViewConfig = ViewConfig> {
public getTheme(props: T, type: string): any {
const plotG2Theme = convertToG2Theme(this.getPlotTheme(props, type));
const g2Theme = _.deepMix({}, G2DefaultTheme, plotG2Theme);
this._processVisible(g2Theme);
// this._processVisible(g2Theme);
return g2Theme;
}

Expand Down
26 changes: 16 additions & 10 deletions src/base/view-layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import PaddingController from './controller/padding';
import StateController from './controller/state';
import ThemeController from './controller/theme';
import Layer, { LayerConfig, Region } from './layer';
import { isTextUsable } from '../util/common';

export interface ViewConfig {
data: object[];
Expand Down Expand Up @@ -137,7 +138,7 @@ export default abstract class ViewLayer<T extends ViewLayerConfig = ViewLayerCon
protected paddingController: PaddingController;
protected stateController: StateController;
protected themeController: ThemeController;
protected config: G2Config;
public config: G2Config;
private interactions: BaseInteraction[] = [];

constructor(props: T) {
Expand Down Expand Up @@ -398,7 +399,7 @@ export default abstract class ViewLayer<T extends ViewLayerConfig = ViewLayerCon
this.config.elements.push(config as G2Config['element']);
return;
}
if ((config as boolean) === false) {
if (config === false) {
this.config[key] = false;
return;
}
Expand All @@ -424,9 +425,10 @@ export default abstract class ViewLayer<T extends ViewLayerConfig = ViewLayerCon
const range = this.layerBBox;
if (this.title) {
this.title.destroy();
this.title = null;
}
this.title = null;
if (props.title.visible) {

if (isTextUsable(props.title)) {
const width = this.width;
const theme = this.config.theme;
const title = new TextDescription({
Expand All @@ -448,22 +450,26 @@ export default abstract class ViewLayer<T extends ViewLayerConfig = ViewLayerCon
const range = this.layerBBox;
if (this.description) {
this.description.destroy();
this.description = null;
}
this.description = null;

if (props.description.visible) {
if (isTextUsable(props.description)) {
const width = this.width;
const theme = this.config.theme;
let topMargin = 0;

let topMargin = range.minY;
if (this.title) {
const titleBBox = this.title.getBBox();
topMargin = titleBBox.minY + titleBBox.height;
topMargin += titleBBox.minY + titleBBox.height;
topMargin += theme.description.padding[0];
} else {
// 无title的情况下使用title的上padding
topMargin += range.minY + theme.title.padding[0];
}

const theme = this.config.theme;
const description = new TextDescription({
leftMargin: range.minX + theme.description.padding[3],
topMargin: topMargin + theme.description.padding[0],
topMargin,
text: props.description.text,
style: _.mix(theme.description, props.description.style),
wrapperWidth: width - theme.description.padding[3] - theme.description.padding[1],
Expand Down
47 changes: 27 additions & 20 deletions src/components/axis/parser.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,47 @@
import { DataPointType } from '@antv/g2/lib/interface';
import * as _ from '@antv/util';
import { ViewLayer } from '../..';

function propertyMapping(source, target, field) {
if (source[field]) {
target[field] = source[field];
}
}

interface AxisConfig {
plot: ViewLayer;
dim: string;
}

export default class AxisParser {
public config: any;
public config: any = false;
private plot: any;
private dim: string;
private localProps: any;

constructor(cfg) {
_.assign(this, cfg);
constructor(cfg: AxisConfig) {
this.plot = cfg.plot;
this.dim = cfg.dim;
this._init();
}

private _init() {
this.config = false;
if (this._needDraw()) {
/** 如果在图表配置项里没有设置坐标轴整体的visibility则去对应的theme取 */
const propos = this.plot.options;
const { dim } = this;
const axisConfig = propos[`${this.dim}Axis`];
if (axisConfig !== undefined) {
if (!(axisConfig && axisConfig.visible)) return;
}
const propsConfig = axisConfig || {};
const theme = this.plot.theme;
const themeConfig = theme.axis[dim];
const config = _.deepMix({}, themeConfig, propsConfig);
if (dim === 'x' || dim === 'y') {
config.position = { x: 'bottom', y: 'left' }[dim];
}
this.localProps = config;
if (config.visible) {
this._styleParser();
}
}
Expand All @@ -39,20 +60,6 @@ export default class AxisParser {
propertyMapping(this.localProps, this.config, 'autoRotateTitle');
}

private _needDraw() {
/** 如果在图表配置项里没有设置坐标轴整体的visibility则去对应的theme取 */
const propos = this.plot.options;
const theme = this.plot.theme;
const propsConfig = propos[`${this.dim}Axis`] ? propos[`${this.dim}Axis`] : {};
const themeConfig = theme.axis[this.dim];
const config = _.deepMix({}, themeConfig, propsConfig);
this.localProps = config;
if (config.visible) {
return true;
}
return false;
}

private _lineParser() {
this.config.line = this.localProps.line;
if (this.localProps.line.style) {
Expand Down Expand Up @@ -113,7 +120,7 @@ export default class AxisParser {
this.config.title = titleConfig;
}

private _isVisible(name) {
private _isVisible(name: string) {
if (this.localProps[name] && this.localProps[name].visible) {
return true;
} else if (_.isFunction(this.localProps[name])) {
Expand Down
40 changes: 16 additions & 24 deletions src/components/description.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,15 @@
import { BBox, Canvas, Group, Text } from '@antv/g';
import * as _ from '@antv/util';
import { breakText } from '../util/common';

/**
* 为字符串添加换行符
* @param source - 字符串数组 ['a', 'b', 'c']
* @param breaks - 要添加换行的index
*
* @example
* ```js
* breakText(['a','b','c'], [1])
*
* // a\nbc
* ```
*/
function breakText(source: string[], breaks: number[]): string {
const result = [...source];
breaks.forEach((pos, index) => {
result.splice(pos + index, 0, '\n');
});
return result.join('');
interface TextConfig {
leftMargin: number;
topMargin: number;
text: string;
style: any;
wrapperWidth: number;
container: Canvas | Group;
theme: any;
}

/**
Expand All @@ -29,16 +20,14 @@ export default class TextDescription {
public shape: Text;
public position: string = 'top';
private container: Canvas | Group;
private theme: any;
private alignWithAxis: boolean;
private topMargin: number;
private leftMargin: number;
private wrapperWidth: number;
private text: string;
private style: any;

constructor(cfg) {
_.assign(this, cfg);
constructor(cfg: TextConfig) {
_.assign(this as any, cfg);
this._init();
}

Expand All @@ -62,7 +51,7 @@ export default class TextDescription {
}

private _init() {
const content = this._textWrapper(this.wrapperWidth, this.style);
const content = this._textWrapper();
this.shape = this.container.addShape('text', {
attrs: _.mix(
{
Expand All @@ -79,7 +68,9 @@ export default class TextDescription {
* 当text过长时,默认换行
* 1. 注意初始text带换行符的场景
*/
private _textWrapper(width: number, style) {
private _textWrapper() {
const width = this.wrapperWidth;
const style = this.style;
const textContent: string = this.text;
const tShape = new Text({
attrs: {
Expand All @@ -101,6 +92,7 @@ export default class TextDescription {
const textWidth = Math.floor(tShape.measureText());
currentWidth += textWidth;
if (currentWidth > width) {
// 如果是第一个字符就大于宽度不做任何换行处理
if (i === 0) {
break;
}
Expand Down
7 changes: 6 additions & 1 deletion src/components/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import axisState from './axis/state';
import labelState from './label/state';
import tooltipState from './tooltip/state';

type FirstArgs<T> = T extends new (first: infer U) => any ? U : never;

const COMPONENT_MAPPER = {
axis: AxisParser,
label: LabelParser,
Expand All @@ -20,7 +22,10 @@ const STATE_MAPPER = {
axis: axisState,
};

export function getComponent(name, cfg) {
export function getComponent<K extends keyof typeof COMPONENT_MAPPER>(
name: K,
cfg: FirstArgs<typeof COMPONENT_MAPPER[K]>
) {
const Components = COMPONENT_MAPPER[name];
return new Components(cfg).config;
}
Expand Down
1 change: 0 additions & 1 deletion src/interface/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ interface IBaseAxis {
/** 轴类型,对应scale类型 */
type?: 'linear' | 'time' | 'cat' | 'dateTime' | 'category' | 'log' | 'pow' | 'timeCat';
/** 轴位置,默认下和左 */
position?: 'default' | 'opposite';
line?: {
visible?: boolean;
style?: {};
Expand Down
22 changes: 0 additions & 22 deletions src/plots/area/layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import ViewLayer, { ViewConfig } from '../../base/view-layer';
import { getComponent } from '../../components/factory';
import { getGeom } from '../../geoms/factory';
import { ElementOption, ICatAxis, ITimeAxis, IValueAxis, Label } from '../../interface/config';
import { extractAxis } from '../../util/axis';
import { extractScale } from '../../util/scale';
import responsiveMethods from './apply-responsive';
import * as EventParser from './event';
Expand Down Expand Up @@ -137,27 +136,6 @@ export default class AreaLayer<T extends AreaLayerConfig = AreaLayerConfig> exte

protected coord() {}

protected axis() {
const props = this.options;
const axesConfig = { fields: {} };
axesConfig.fields[props.xField] = {};
axesConfig.fields[props.yField] = {};

if (props.xAxis.visible === false) {
axesConfig.fields[props.xField] = false;
} else {
extractAxis(axesConfig.fields[props.xField], props.xAxis);
}

if (props.yAxis.visible === false) {
axesConfig.fields[props.yField] = false;
} else {
extractAxis(axesConfig.fields[props.yField], props.yAxis);
}
/** 存储坐标轴配置项到config */
this.setConfig('axes', axesConfig);
}

protected addGeometry() {
const props = this.options;
const area = getGeom('area', 'main', {
Expand Down
Loading

0 comments on commit 32151f8

Please sign in to comment.