diff --git a/packages/carbon-graphs/src/js/helpers/axis.js b/packages/carbon-graphs/src/js/helpers/axis.js index bc59fb342..2385f70a5 100644 --- a/packages/carbon-graphs/src/js/helpers/axis.js +++ b/packages/carbon-graphs/src/js/helpers/axis.js @@ -897,12 +897,19 @@ const createAxes = (axis, scale, config, canvasSVG) => { .attr('id', 'x') .selectAll('text') .style('text-anchor', () => { - if (config.axis.x.ticks.rotateAngle !== undefined) { - return config.axis.x.ticks.rotateAngle >= 0 ? 'start' : 'end'; + const validRotations = Object.values(utils.TickLabelRotations); + if ( + utils.isDefined(config.axis.x.ticks.TickLabelRotations) + && validRotations.includes(config.axis.x.ticks.TickLabelRotations) + ) { + const rotation = config.axis.x.ticks.TickLabelRotations; + console.warn(`tickLabelsRotation Using ${rotation} rotation for x-axis labels to avoid overlapping.`); + return rotation === utils.TickLabelRotations.NEGATIVE_45 ? 'end' : 'middle'; } + console.warn('Warning: Invalid tickLabelsRotation angle. Using default rotation (0 or -45) for x-axis labels.'); return 'middle'; }) - .attr('transform', () => `rotate(${config.axis.x.ticks.rotateAngle})`); + .attr('transform', () => `rotate(${config.axis.x.ticks.TickLabelRotations})`); canvasSVG .append('g') .classed(styles.axis, true) @@ -1130,6 +1137,14 @@ const getXAxisHeight = (config) => { const dummy = d3.select('body').append('div'); const svg = dummy.append('svg'); const group = svg.append('g').call(axis); + if (config.axis.x.ticks && config.axis.x.ticks.TickLabelRotations === -45) { + // Add extra padding for rotated tick labels + const extraPadding = 5; + group.selectAll('.tick text').attr('transform', `rotate(${config.axis.x.ticks.TickLabelRotations})`); + const rotatedHeight = group.node().getBoundingClientRect().height; + dummy.remove(); + return rotatedHeight + extraPadding; + } const { height } = group.node().getBoundingClientRect(); dummy.remove(); return height; @@ -1213,10 +1228,16 @@ const getAxisLabelWidth = (label, axis, config) => { * @param {string} label - Label text * @returns {number} label height */ -const getAxisLabelHeight = (label) => { +const getAxisLabelHeight = (label, TickLabelRotations) => { const dummy = d3.select('body').append('div'); const svg = dummy.append('svg'); const grouper = svg.append('g'); + + if (TickLabelRotations && TickLabelRotations === -45) { + // Adding extra padding for rotated labels + grouper.attr('transform', `rotate(${TickLabelRotations})`); + } + buildAxisLabel(grouper, label); const { height } = grouper.node().getBoundingClientRect(); dummy.remove(); @@ -1301,7 +1322,8 @@ const calculateAxesLabelSize = (config) => { config.axisLabelWidths.y2 = 0; if (config.showLabel) { if (config.axis.x.label) { - config.axisLabelHeights.x = getAxisLabelHeight(config.axis.x.label); + const TickLabelRotations = config.axis.x.ticks && config.axis.x.ticks.TickLabelRotations; + config.axisLabelHeights.x = getAxisLabelHeight(config.axis.x.label, TickLabelRotations); } if (config.axis.y.label) { config.axisLabelWidths.y = constants.DEFAULT_CHARACTER_SVG_ELEMENT_WIDTH; diff --git a/packages/carbon-graphs/src/js/helpers/utils.js b/packages/carbon-graphs/src/js/helpers/utils.js index ad4f30684..1dfaeb11f 100644 --- a/packages/carbon-graphs/src/js/helpers/utils.js +++ b/packages/carbon-graphs/src/js/helpers/utils.js @@ -217,6 +217,15 @@ const getEpocFromDateString = (dateISO) => parseInt(new Date(dateISO).getTime(), * @returns {object typeof Date} - Date object based on epoc */ const getDateFromEpoc = (epocDate) => new Date(epocDate); +/** + * Enum for tick label rotations. + * @readonly + * @enum {number} + */ +const TickLabelRotations = { + DEFAULT: 0, + NEGATIVE_45: -45, +}; /** * @enum {Function} @@ -242,4 +251,5 @@ export default { notEmpty, parseDateTime, sanitize, + TickLabelRotations, }; diff --git a/packages/terra-graphs-docs/src/example-datasets/graphConfigObjects/General/generalDefaultXAxisOverlapping.js b/packages/terra-graphs-docs/src/example-datasets/graphConfigObjects/General/generalDefaultXAxisOverlapping.js index 40ae19f21..3d612005b 100644 --- a/packages/terra-graphs-docs/src/example-datasets/graphConfigObjects/General/generalDefaultXAxisOverlapping.js +++ b/packages/terra-graphs-docs/src/example-datasets/graphConfigObjects/General/generalDefaultXAxisOverlapping.js @@ -22,7 +22,7 @@ const getLineTimeseriesConfig = (id) => ({ new Date(2016, 0, 10).toISOString(), new Date(2016, 0, 11).toISOString(), ], - rotateAngle: -45, + TickLabelRotations: -45, format: '%Y, %X', }, }, diff --git a/packages/terra-graphs-docs/src/terra-dev-site/graph/CoreConfiguration.b/Documentation/Axes.3.graph.mdx b/packages/terra-graphs-docs/src/terra-dev-site/graph/CoreConfiguration.b/Documentation/Axes.3.graph.mdx index 105063af0..77fd4667e 100644 --- a/packages/terra-graphs-docs/src/terra-dev-site/graph/CoreConfiguration.b/Documentation/Axes.3.graph.mdx +++ b/packages/terra-graphs-docs/src/terra-dev-site/graph/CoreConfiguration.b/Documentation/Axes.3.graph.mdx @@ -82,7 +82,7 @@ axis: { | suppressTrailingZeros | boolean | `false` | no | Toggle to suppress tick values's trailing zeros when default d3 tick formatting is used. For X axis, this property works only when X axis type is set to AXIS_TYPE.DEFAULT. Specifying `~` in the tick format takes precedence over `suppressTrailingZeros` property. | | ticks | object | `null` | no | See [Ticks](./Ticks). | | type | string | `AXIS_TYPE.DEFAULT` | no | See [type](#type). Normal number value or time-based. Only for x-axis. | -| rotateAngle | integer | - | no | allows consumer to add a rotateAngle to x-axis to avoid the overlapping (angle will be in between `+90` to `-90` Positive values move in clock wise direction & negative values moves in anticlock wise direction).Only for x-axis. | +| TickLabelRotations | integer | - | no | Sets the rotation of the tick labels to `-45ยบ`. Only for x-axis. | - ### `allowCalibration` Set calibration for the axis.