Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Component | Axis: Fixing tick text formatting; new CSS vars #223

Merged
merged 1 commit into from
Jun 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/angular/src/components/axis/axis.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ export class VisAxisComponent<Datum> implements AxisConfigInterface<Datum>, Afte
/** Maximum width in pixels for the tick text to be wrapped or trimmed. Default: `undefined` */
@Input() tickTextWidth?: number

/** Tick text wrapping separator. String or array of strings. Default: `' '` */
/** Tick text wrapping separator. String or array of strings. Default: `undefined` */
@Input() tickTextSeparator?: string | string[]

/** Force word break for ticks when they don't fit. Default: `false` */
Expand Down
25 changes: 25 additions & 0 deletions packages/dev/src/examples/xy-components/axis/single-axis/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react'
import { Axis } from '@unovis/ts'
import { VisXYContainer, VisAxis } from '@unovis/react'


// Style
import s from './style.module.css'

export const title = 'Axis'
export const subTitle = 'Single axis with styling'
export const component = (): JSX.Element => {
return (
<VisXYContainer className={s.axis} xDomain={[0, 1000]} height={75}>
<VisAxis
type='x'
numTicks={10}
events={{
[Axis.selectors.tickLabel]: {
click: (tickValue: number) => alert(`Clicked tick: ${tickValue}`),
},
}}
/>
</VisXYContainer>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.axis {
--vis-axis-tick-label-cursor: pointer;
--vis-axis-tick-label-text-decoration: underline;
--vis-axis-tick-label-color: #366ACE;
}
4 changes: 2 additions & 2 deletions packages/ts/src/components/axis/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export interface AxisConfigInterface<Datum> extends Partial<XYComponentConfigInt
tickTextFitMode?: FitMode | string;
/** Maximum width in pixels for the tick text to be wrapped or trimmed. Default: `undefined` */
tickTextWidth?: number;
/** Tick text wrapping separator. String or array of strings. Default: `' '` */
/** Tick text wrapping separator. String or array of strings. Default: `undefined` */
tickTextSeparator?: string | string[];
/** Force word break for ticks when they don't fit. Default: `false` */
tickTextForceWordBreak?: boolean;
Expand All @@ -62,7 +62,7 @@ export class AxisConfig<Datum> extends XYComponentConfig<Datum> implements AxisC
numTicks = undefined
minMaxTicksOnly = false
tickTextWidth = undefined
tickTextSeparator = ' '
tickTextSeparator = undefined
tickTextForceWordBreak = false
tickTextTrimType = TrimMode.Middle
tickTextFitMode = FitMode.Wrap
Expand Down
3 changes: 3 additions & 0 deletions packages/ts/src/components/axis/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ export class Axis<Datum> extends XYComponentCore<Datum, AxisConfig<Datum>, AxisC
// will include exiting elements, so we're filtering them out.
const tickText = selection.selectAll<SVGTextElement, number | Date>('g.tick > text')
.filter(tickValue => tickValues.some(t => isEqual(tickValue, t))) // We use isEqual to compare Dates
.classed(s.tickLabel, true)

// We interrupt the transition on tick's <text> to make it 'wrappable'
tickText.nodes().forEach(node => interrupt(node))
Expand All @@ -228,6 +229,8 @@ export class Axis<Datum> extends XYComponentCore<Datum, AxisConfig<Datum>, AxisC
const textOptions: UnovisTextOptions = {
verticalAlign: config.type === AxisType.X ? VerticalAlign.Top : VerticalAlign.Middle,
width: textMaxWidth,
separator: config.tickTextSeparator,
wordBreak: config.tickTextForceWordBreak,
}
renderTextToSvgTextElement(textElement, textBlock, textOptions)
}
Expand Down
10 changes: 7 additions & 3 deletions packages/ts/src/components/axis/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ export const globalStyles = injectGlobal`
/* --vis-axis-font-family: */
--vis-axis-tick-color: #e8e9ef;
/* --vis-axis-domain-color: // Undefined by default to allow fallback to var(--vis-axis-tick-color) */
--vis-axis-tick-label-color: #6c778c;
--vis-axis-grid-color: #e8e9ef;
--vis-axis-label-color: #6c778c;
--vis-axis-tick-label-color: #6c778c;
--vis-axis-tick-label-font-size: 12px;
--vis-axis-tick-label-cursor: default;
--vis-axis-tick-label-text-decoration: none;
--vis-axis-label-font-size: 14px;
--vis-axis-tick-line-width: 1px;
--vis-axis-grid-line-width: 1px;
Expand Down Expand Up @@ -93,6 +95,8 @@ export const tick = css`
text, tspan {
fill: var(--vis-axis-tick-label-color);
font-family: var(--vis-axis-font-family, var(--vis-font-family));
cursor: var(--vis-axis-tick-label-cursor);
text-decoration: var(--vis-axis-tick-label-text-decoration);
stroke: none;
}
`
Expand All @@ -105,6 +109,6 @@ export const label = css`
text-anchor: middle;
`

export const tickText = css`
label: tick-text;
export const tickLabel = css`
label: tick-label;
`
38 changes: 15 additions & 23 deletions packages/website/docs/auxiliary/Axis.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -116,28 +116,6 @@ Change the tick's label alignment with respect to the tick marker using `tickTex
options={['right', 'center', 'left']}
property="tickTextAlign"/>

### Label Length
To limit the string length of the tick labels, use the `tickTextLength` property:
<XYWrapperWithInput
{...defaultProps()}
inputType="range"
defaultValue={10}
inputProps={{min: 1, max: 20}}
property="tickTextLength"
data={generateTimeSeries(10)}
hiddenProps={{gridLine: false, x: d => d.timestamp, tickFormat: d=> new Date(d).toDateString()}}
/>

### Label Trim Type
When a tick label becomes too long, you can customize the trimming method with the `tickTextLength` property.
_Axis_ accepts a `TrimMode` or a string. When we provide the previous example with `TrimMode.End` property, we can see the end of the label gets cut off instead of the middle.
<XYWrapperWithInput inputType="select"
{...defaultProps()}
tickTextLength={10}
data={generateTimeSeries(10)}
hiddenProps={{gridLine: false, x: d => d.timestamp, tickFormat: d=> new Date(d).toDateString()}}
options={['start', 'middle', 'end']}
property="tickTextTrimType"/>

### Label Width
To limit the width of the tick labels (in pixels), you can use the `tickTextWidth` property.
Expand All @@ -151,7 +129,7 @@ To limit the width of the tick labels (in pixels), you can use the `tickTextWidt
/>

### Label Fit Mode
_Axis_ accepts the following values for the tickTextFitMode property: `FitMode.Wrap` or `FitMode.Trim`. This determines how the axis will
_Axis_ accepts the following values for the `tickTextFitMode` property: `FitMode.Wrap` or `FitMode.Trim`. This determines how the axis will
handle tick text overflow. The following example showcases the previous example using `"trim"` instead of `"wrap"`.
<XYWrapperWithInput inputType="select"
{...defaultProps()}
Expand All @@ -161,6 +139,18 @@ handle tick text overflow. The following example showcases the previous example
options={['trim', 'wrap']}
property="tickTextFitMode"/>

### Label Trim Type
When a tick label becomes too long, and you want to trim it, you can customize the trimming method with the `tickTextTrimType` property.
_Axis_ accepts a `TrimMode` or a string. For example, when we configure `tickTextTrimType` to `TrimMode.Start`, we can see the start of the label gets cut off instead of the middle.
<XYWrapperWithInput inputType="select"
{...defaultProps()}
tickTextFitMode="trim"
tickTextWidth={30}
data={generateTimeSeries(10)}
hiddenProps={{gridLine: false, x: d => d.timestamp, tickFormat: d=> new Date(d).toDateString()}}
options={['start', 'middle', 'end']}
property="tickTextTrimType"/>

### Force Word Break
In addition, you can enable a forced word break for overflowing tick labels with the `tickTextForceWordBreak` property.
<XYWrapperWithInput
Expand Down Expand Up @@ -253,6 +243,8 @@ The _Axis_ component supports additional styling via CSS variables that you can
--vis-axis-grid-color: #e8e9ef;
--vis-axis-label-color: #6c778c;
--vis-axis-tick-label-font-size: 12px;
--vis-axis-tick-label-cursor: default;
--vis-axis-tick-label-text-decoration: none;
--vis-axis-label-font-size: 14px;
--vis-axis-tick-line-width: 1px;
--vis-axis-grid-line-width: 1px;
Expand Down