Skip to content

Commit 47f118b

Browse files
feat: add tickLabelRotation and showGridLines features (#7)
1 parent 0a314d1 commit 47f118b

File tree

15 files changed

+603
-167
lines changed

15 files changed

+603
-167
lines changed

src/components/react_canvas/axis.tsx

Lines changed: 64 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import React from 'react';
22
import { Group, Line, Rect, Text } from 'react-konva';
3-
import { AxisTick, AxisTicksDimensions, isHorizontal, isVertical } from '../../lib/axes/axis_utils';
3+
import {
4+
AxisTick, AxisTicksDimensions, centerRotationOrigin, getHorizontalAxisTickLineProps,
5+
getTickLabelProps, getVerticalAxisTickLineProps, isHorizontal, isVertical,
6+
} from '../../lib/axes/axis_utils';
47
import { AxisSpec, Position } from '../../lib/series/specs';
58
import { Theme } from '../../lib/themes/theme';
69
import { Dimensions } from '../../lib/utils/dimensions';
@@ -12,6 +15,7 @@ interface AxisProps {
1215
axisPosition: Dimensions;
1316
ticks: AxisTick[];
1417
debug: boolean;
18+
chartDimensions: Dimensions;
1519
}
1620

1721
export class Axis extends React.PureComponent<AxisProps> {
@@ -23,33 +27,37 @@ export class Axis extends React.PureComponent<AxisProps> {
2327
axes: { tickFontFamily, tickFontSize, tickFontStyle },
2428
} = this.props.chartTheme;
2529
const {
26-
axisSpec: { tickSize, tickPadding, position },
27-
axisTicksDimensions: { maxTickHeight, maxTickWidth },
30+
axisSpec: {
31+
tickSize,
32+
tickPadding,
33+
position,
34+
},
35+
axisTicksDimensions,
2836
debug,
2937
} = this.props;
3038

39+
const tickLabelRotation = this.props.axisSpec.tickLabelRotation || 0;
40+
41+
const tickLabelProps = getTickLabelProps(
42+
tickLabelRotation,
43+
tickSize,
44+
tickPadding,
45+
tick.position,
46+
position,
47+
axisTicksDimensions,
48+
);
49+
50+
const { maxLabelTextWidth, maxLabelTextHeight } = axisTicksDimensions;
51+
const centeredRectProps = centerRotationOrigin(axisTicksDimensions, { x: tickLabelProps.x, y: tickLabelProps.y });
52+
3153
const textProps = {
32-
x: 0,
33-
y: 0,
34-
align: 'center',
35-
width: 0,
36-
height: 0,
37-
verticalAlign: 'middle',
54+
width: maxLabelTextWidth,
55+
height: maxLabelTextHeight,
56+
rotation: tickLabelRotation,
57+
...tickLabelProps,
58+
...centeredRectProps,
3859
};
39-
if (isVertical(position)) {
40-
textProps.y = tick.position - maxTickHeight / 2;
41-
textProps.align = position === Position.Left ? 'right' : 'left';
42-
textProps.x = position === Position.Left ? -maxTickWidth : tickSize + tickPadding;
43-
textProps.height = maxTickHeight;
44-
textProps.width = maxTickWidth;
45-
} else {
46-
textProps.y = position === Position.Top ? 0 : tickSize + tickPadding;
47-
textProps.x = tick.position - maxTickWidth / 2;
48-
textProps.align = 'center';
49-
textProps.height = maxTickHeight;
50-
textProps.width = maxTickWidth;
51-
textProps.verticalAlign = position === Position.Top ? 'bottom' : 'top';
52-
}
60+
5361
return (
5462
<Group key={`tick-${i}`}>
5563
{debug && <Rect {...textProps} stroke="black" strokeWidth={1} fill="violet" />}
@@ -68,30 +76,40 @@ export class Axis extends React.PureComponent<AxisProps> {
6876
private renderTickLine = (tick: AxisTick, i: number) => {
6977
const {
7078
axisSpec: { tickSize, tickPadding, position },
71-
axisTicksDimensions: { maxTickHeight },
79+
axisTicksDimensions: { maxLabelBboxHeight },
80+
chartDimensions,
81+
chartTheme: { chart: { paddings } },
7282
} = this.props;
7383

74-
const lineProps = [];
84+
const showGridLines = this.props.axisSpec.showGridLines || false;
7585

76-
if (isVertical(position)) {
77-
lineProps[0] = position === Position.Left ? tickPadding : 0;
78-
lineProps[1] = tick.position;
79-
lineProps[2] = position === Position.Left ? tickSize + tickPadding : tickSize;
80-
lineProps[3] = tick.position;
81-
} else {
82-
lineProps[0] = tick.position;
83-
lineProps[1] = position === Position.Top ? maxTickHeight + tickPadding : 0;
84-
lineProps[2] = tick.position;
85-
lineProps[3] = position === Position.Top ? maxTickHeight + tickPadding + tickSize : tickSize;
86-
}
86+
const lineProps = isVertical(position) ?
87+
getVerticalAxisTickLineProps(
88+
showGridLines,
89+
position,
90+
tickPadding,
91+
tickSize,
92+
tick.position,
93+
chartDimensions.width,
94+
paddings,
95+
) : getHorizontalAxisTickLineProps(
96+
showGridLines,
97+
position,
98+
tickPadding,
99+
tickSize,
100+
tick.position,
101+
maxLabelBboxHeight,
102+
chartDimensions.height,
103+
paddings,
104+
);
87105

88106
return <Line key={`tick-${i}`} points={lineProps} stroke={'gray'} strokeWidth={1} />;
89107
}
90108
private renderAxis = () => {
91109
const { ticks, axisPosition } = this.props;
92110
return (
93111
<Group x={axisPosition.left} y={axisPosition.top}>
94-
<Group key="lines">{this.renderLine()}</Group>
112+
<Group key="lines">{this.renderAxisLine()}</Group>
95113
<Group key="tick-lines">{ticks.map(this.renderTickLine)}</Group>
96114
<Group key="ticks">
97115
{ticks.filter((tick) => tick.label !== null).map(this.renderTickLabel)}
@@ -100,7 +118,7 @@ export class Axis extends React.PureComponent<AxisProps> {
100118
</Group>
101119
);
102120
}
103-
private renderLine = () => {
121+
private renderAxisLine = () => {
104122
const {
105123
axisSpec: { tickSize, tickPadding, position },
106124
axisPosition,
@@ -116,9 +134,9 @@ export class Axis extends React.PureComponent<AxisProps> {
116134
lineProps[0] = 0;
117135
lineProps[2] = axisPosition.width;
118136
lineProps[1] =
119-
position === Position.Top ? axisTicksDimensions.maxTickHeight + tickSize + tickPadding : 0;
137+
position === Position.Top ? axisTicksDimensions.maxLabelBboxHeight + tickSize + tickPadding : 0;
120138
lineProps[3] =
121-
position === Position.Top ? axisTicksDimensions.maxTickHeight + tickSize + tickPadding : 0;
139+
position === Position.Top ? axisTicksDimensions.maxLabelBboxHeight + tickSize + tickPadding : 0;
122140
}
123141
return <Line points={lineProps} stroke={'gray'} strokeWidth={1} />;
124142
}
@@ -138,7 +156,7 @@ export class Axis extends React.PureComponent<AxisProps> {
138156
const {
139157
axisPosition: { height },
140158
axisSpec: { title, position, tickSize, tickPadding },
141-
axisTicksDimensions: { maxTickWidth },
159+
axisTicksDimensions: { maxLabelBboxWidth },
142160
chartTheme: {
143161
axes: { titleFontFamily, titleFontSize, titleFontStyle, titlePadding },
144162
},
@@ -150,8 +168,8 @@ export class Axis extends React.PureComponent<AxisProps> {
150168
const top = height;
151169
const left =
152170
position === Position.Left
153-
? -(maxTickWidth + titleFontSize + titlePadding)
154-
: tickSize + tickPadding + maxTickWidth + titlePadding;
171+
? -(maxLabelBboxWidth + titleFontSize + titlePadding)
172+
: tickSize + tickPadding + maxLabelBboxWidth + titlePadding;
155173

156174
return (
157175
<Group>
@@ -186,7 +204,7 @@ export class Axis extends React.PureComponent<AxisProps> {
186204
const {
187205
axisPosition: { width, height },
188206
axisSpec: { title, position, tickSize, tickPadding },
189-
axisTicksDimensions: { maxTickHeight },
207+
axisTicksDimensions: { maxLabelBboxHeight },
190208
chartTheme: {
191209
axes: { titleFontSize },
192210
},
@@ -197,7 +215,7 @@ export class Axis extends React.PureComponent<AxisProps> {
197215
return;
198216
}
199217

200-
const top = position === Position.Top ? -maxTickHeight : maxTickHeight + tickPadding + tickSize;
218+
const top = position === Position.Top ? -maxLabelBboxHeight : maxLabelBboxHeight + tickPadding + tickSize;
201219
const left = 0;
202220
return (
203221
<Group>
@@ -206,7 +224,7 @@ export class Axis extends React.PureComponent<AxisProps> {
206224
x={left}
207225
y={top}
208226
width={width}
209-
height={maxTickHeight}
227+
height={maxLabelBboxHeight}
210228
stroke="black"
211229
strokeWidth={1}
212230
fill="violet"

src/components/react_canvas/reactive_chart.tsx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@ class Chart extends React.Component<ReactiveChartProps, ReactiveChartState> {
134134
axesPositions,
135135
chartTheme,
136136
debug,
137+
chartDimensions,
137138
} = this.props.chartStore!;
139+
138140
const axesComponents: JSX.Element[] = [];
139141
axesVisibleTicks.forEach((axisTicks, axisId) => {
140142
const axisSpec = axesSpecs.get(axisId);
@@ -153,6 +155,7 @@ class Chart extends React.Component<ReactiveChartProps, ReactiveChartState> {
153155
ticks={ticks}
154156
chartTheme={chartTheme}
155157
debug={debug}
158+
chartDimensions={chartDimensions}
156159
/>,
157160
);
158161
});
@@ -231,15 +234,15 @@ class Chart extends React.Component<ReactiveChartProps, ReactiveChartState> {
231234
const clippings = debug
232235
? {}
233236
: {
234-
clipX: 0,
235-
clipY: 0,
236-
clipWidth: [90, -90].includes(chartRotation)
237-
? chartDimensions.height
238-
: chartDimensions.width,
239-
clipHeight: [90, -90].includes(chartRotation)
240-
? chartDimensions.width
241-
: chartDimensions.height,
242-
};
237+
clipX: 0,
238+
clipY: 0,
239+
clipWidth: [90, -90].includes(chartRotation)
240+
? chartDimensions.height
241+
: chartDimensions.width,
242+
clipHeight: [90, -90].includes(chartRotation)
243+
? chartDimensions.width
244+
: chartDimensions.height,
245+
};
243246
let brushProps = {};
244247
const isBrushEnabled = this.props.chartStore!.isBrushEnabled();
245248
if (isBrushEnabled) {

src/components/svg/axis.tsx

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ export class Axis extends React.PureComponent<AxisProps> {
4040
className="euiSeriesChartAxis_tickLabel"
4141
key={`tick-${i}`}
4242
{...textProps}
43-
// textAnchor={textProps.textAnchor}
44-
// dominantBaseline={textProps.dominantBaseline}
45-
// transform={transform}
43+
// textAnchor={textProps.textAnchor}
44+
// dominantBaseline={textProps.dominantBaseline}
45+
// transform={transform}
4646
>
4747
{tick.label}
4848
</text>
@@ -52,7 +52,7 @@ export class Axis extends React.PureComponent<AxisProps> {
5252
private renderTickLine = (tick: AxisTick, i: number) => {
5353
const {
5454
axisSpec: { tickSize, tickPadding, position },
55-
axisTicksDimensions: { maxTickHeight },
55+
axisTicksDimensions: { maxLabelBboxHeight },
5656
} = this.props;
5757

5858
const lineProps: SVGProps<SVGLineElement> = {};
@@ -65,8 +65,8 @@ export class Axis extends React.PureComponent<AxisProps> {
6565
} else {
6666
lineProps.x1 = tick.position;
6767
lineProps.x2 = tick.position;
68-
lineProps.y1 = position === 'top' ? maxTickHeight + tickPadding : 0;
69-
lineProps.y2 = position === 'top' ? maxTickHeight + tickPadding + tickSize : tickSize;
68+
lineProps.y1 = position === 'top' ? maxLabelBboxHeight + tickPadding : 0;
69+
lineProps.y2 = position === 'top' ? maxLabelBboxHeight + tickPadding + tickSize : tickSize;
7070
}
7171

7272
return <line className="euiSeriesChartAxis_tickLine" key={`tick-${i}`} {...lineProps} />;
@@ -101,9 +101,9 @@ export class Axis extends React.PureComponent<AxisProps> {
101101
lineProps.x1 = 0;
102102
lineProps.x2 = axisPosition.width;
103103
lineProps.y1 =
104-
position === 'top' ? axisTicksDimensions.maxTickHeight + tickSize + tickPadding : 0;
104+
position === 'top' ? axisTicksDimensions.maxLabelBboxHeight + tickSize + tickPadding : 0;
105105
lineProps.y2 =
106-
position === 'top' ? axisTicksDimensions.maxTickHeight + tickSize + tickPadding : 0;
106+
position === 'top' ? axisTicksDimensions.maxLabelBboxHeight + tickSize + tickPadding : 0;
107107
}
108108
return <line className="euiSeriesChartAxis_line" {...lineProps} />;
109109
}
@@ -123,7 +123,7 @@ export class Axis extends React.PureComponent<AxisProps> {
123123
const {
124124
axisPosition: { height },
125125
axisSpec: { title, position, tickSize, tickPadding },
126-
axisTicksDimensions: { maxTickWidth },
126+
axisTicksDimensions: { maxLabelBboxWidth },
127127
chartTheme: {
128128
chart: { margins },
129129
},
@@ -132,8 +132,8 @@ export class Axis extends React.PureComponent<AxisProps> {
132132
const top = height / 2;
133133
const left =
134134
position === Position.Left
135-
? -(maxTickWidth + margins.left / 2)
136-
: tickSize + tickPadding + maxTickWidth + +margins.right / 2;
135+
? -(maxLabelBboxWidth + margins.left / 2)
136+
: tickSize + tickPadding + maxLabelBboxWidth + +margins.right / 2;
137137
const translate = `translate(${left} ${top}) rotate(-90)`;
138138
return (
139139
<g className="euiSeriesChartAxis_axisTitle">
@@ -147,7 +147,7 @@ export class Axis extends React.PureComponent<AxisProps> {
147147
const {
148148
axisPosition: { width },
149149
axisSpec: { title, position, tickSize, tickPadding },
150-
axisTicksDimensions: { maxTickHeight },
150+
axisTicksDimensions: { maxLabelBboxHeight },
151151
chartTheme: {
152152
chart: { margins },
153153
},
@@ -156,7 +156,7 @@ export class Axis extends React.PureComponent<AxisProps> {
156156
const top =
157157
position === Position.Top
158158
? -margins.top / 2
159-
: maxTickHeight + tickPadding + tickSize + margins.bottom / 2;
159+
: maxLabelBboxHeight + tickPadding + tickSize + margins.bottom / 2;
160160
const left = width / 2;
161161
const translate = `translate(${left} ${top} )`;
162162
return (

0 commit comments

Comments
 (0)