Skip to content
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
1 change: 1 addition & 0 deletions homedocs/src/pages/docs/charts/time-axis.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ This example shows monthly data over two years using a column graph. The axis au
| `inverted` | `boolean` | Set to `true` to invert the axis direction. |
| `snapToTicks` | `number` | Range alignment: `0` = lowest ticks (default), `1` = medium ticks, `2` = major ticks. |
| `format` | `string` | Label format override. If not set, format is selected based on the time range. |
| `hideClippedLabels` | `boolean` | Drop a first/last label (with its tick) that would not fit and get clipped at the chart edge. Defaults to `true` on `TimeAxis`. |
| `deadZone` | `number` | Size of a zone reserved for labels at both ends of the axis. |
| `upperDeadZone`| `number` | Size of a zone reserved for labels near the upper end of the axis. |
| `lowerDeadZone`| `number` | Size of a zone reserved for labels near the lower end of the axis. |
32 changes: 31 additions & 1 deletion packages/cx/src/charts/axis/Axis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ export interface AxisConfig extends BoundedObjectConfig {
/** Set to true to hide the axis labels. */
hideLabels?: boolean;

/**
* Set to `true` to drop a boundary (first/last) label, together with its tick,
* when the label would not fit within the chart and get clipped at the edge.
* Minor ticks are unaffected. Only affects horizontal axes. Defaults to `false`,
* except on `TimeAxis` where it defaults to `true`.
*/
hideClippedLabels?: boolean;

/** Set to true to hide the axis line. */
hideLine?: boolean;

Expand Down Expand Up @@ -131,6 +139,7 @@ export class Axis extends BoundedObject<AxisConfig, AxisInstance> {
declare inverted: boolean;
declare hidden: boolean;
declare hideLabels: boolean;
declare hideClippedLabels: boolean;
declare hideTicks: boolean;
declare hideLine: boolean;
declare tickSize: number;
Expand Down Expand Up @@ -185,6 +194,7 @@ export class Axis extends BoundedObject<AxisConfig, AxisInstance> {
{
anchors: undefined,
hideLabels: undefined,
hideClippedLabels: undefined,
hideLine: undefined,
hideTicks: undefined,
labelRotation: undefined,
Expand Down Expand Up @@ -259,10 +269,27 @@ export class Axis extends BoundedObject<AxisConfig, AxisInstance> {
var t: string[] = [];
if (!!size && !data.hideLabels) {
var ticks = calculator.getTicks([size]);

// A boundary label is dropped when it would be clipped at the chart edge.
// How far a label reaches toward an edge depends only on its text anchor
// and minLabelDistance, so it is resolved once here rather than per tick.
// Chart bounds (parentRect) are used rather than axis bounds, since an
// axis can be inset within its chart and one Svg may host several charts.
let chartBounds = instance.parentRect;
let clipBoundaryLabels = !this.vertical && !!data.hideClippedLabels && !!chartBounds;
let reach = minLabelDistance * 0.8;
let leftReach = data.labelAnchor == "end" ? reach : data.labelAnchor == "middle" ? reach / 2 : 0;
let rightReach = data.labelAnchor == "start" ? reach : data.labelAnchor == "middle" ? reach / 2 : 0;

ticks.forEach((serie: any[], si: number) => {
serie.forEach((v: any, i: number) => {
var s = calculator.map(v);

// Drop this boundary label (and its major tick) if it would be
// clipped at the chart edge; minor ticks render separately and stay.
let clipped =
clipBoundaryLabels && (s + rightReach > chartBounds.r || s - leftReach < chartBounds.l);

if (this.secondary) {
x1 = this.vertical ? bounds.r + tickOffset : s;
y1 = this.vertical ? s : bounds.t - tickOffset;
Expand All @@ -275,7 +302,9 @@ export class Axis extends BoundedObject<AxisConfig, AxisInstance> {
y2 = this.vertical ? s : bounds.b + tickOffset + tickSize;
}

if (!this.useGridlineTicks) t.push(`M ${x1} ${y1} L ${x2} ${y2}`);
if (!this.useGridlineTicks && !clipped) t.push(`M ${x1} ${y1} L ${x2} ${y2}`);

if (clipped) return;

var x, y;
let labelOffset =
Expand Down Expand Up @@ -422,6 +451,7 @@ Axis.prototype.secondary = false;
Axis.prototype.inverted = false;
Axis.prototype.hidden = false;
Axis.prototype.hideLabels = false;
Axis.prototype.hideClippedLabels = false;
Axis.prototype.hideTicks = false;
Axis.prototype.hideLine = false;

Expand Down
1 change: 1 addition & 0 deletions packages/cx/src/charts/axis/TimeAxis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ TimeAxis.prototype.minLabelDistance = 60;
TimeAxis.prototype.minTickDistance = 60;
TimeAxis.prototype.minTickUnit = "second";
TimeAxis.prototype.useLabelDistanceFormatOverrides = false;
TimeAxis.prototype.hideClippedLabels = true;
TimeAxis.prototype.minLabelDistanceFormatOverrideDefaults = {
[TimeFormats.fullDateAndTime]: 150,
[TimeFormats.shortMonthDate]: 90,
Expand Down
Loading