diff --git a/CHANGELOG.md b/CHANGELOG.md index 67a51f42c..720e6edc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,24 @@ +## [26.1.1](https://github.com/dhis2/analytics/compare/v26.1.0...v26.1.1) (2023-10-05) + + +### Bug Fixes + +* **translations:** sync translations from transifex (master) ([dd9c23f](https://github.com/dhis2/analytics/commit/dd9c23f34a0489cae89f5f5c10ab1dc17e2c13ef)) + +# [26.1.0](https://github.com/dhis2/analytics/compare/v26.0.21...v26.1.0) (2023-10-03) + + +### Features + +* **pivot-table:** truncate title and show full in tooltip ([#1579](https://github.com/dhis2/analytics/issues/1579)) ([c37ba2d](https://github.com/dhis2/analytics/commit/c37ba2d1a187963b3b5aeee5b951bcf9c129dcd2)) + +## [26.0.21](https://github.com/dhis2/analytics/compare/v26.0.20...v26.0.21) (2023-09-28) + + +### Bug Fixes + +* avoid crash in DV with some chart types DHIS2-15882 ([#1582](https://github.com/dhis2/analytics/issues/1582)) ([f6c89e1](https://github.com/dhis2/analytics/commit/f6c89e1481dbbc2ea2cfe80a3c9ed7f81a63c83c)) + ## [26.0.20](https://github.com/dhis2/analytics/compare/v26.0.19...v26.0.20) (2023-09-25) diff --git a/i18n/nb.po b/i18n/nb.po index 14644d70c..0d8c22c53 100644 --- a/i18n/nb.po +++ b/i18n/nb.po @@ -1,15 +1,15 @@ # # Translators: -# Karoline Tufte Lien , 2022 # Caroline Hesthagen Holen , 2023 # Jen Jones Arnesen , 2023 +# Karoline Tufte Lien , 2023 # msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" "POT-Creation-Date: 2023-07-06T08:30:33.216Z\n" "PO-Revision-Date: 2020-04-28 22:05+0000\n" -"Last-Translator: Jen Jones Arnesen , 2023\n" +"Last-Translator: Karoline Tufte Lien , 2023\n" "Language-Team: Norwegian Bokmål (https://app.transifex.com/hisp-uio/teams/100509/nb/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -451,7 +451,7 @@ msgid "No results found" msgstr "Ingen resultater funnet" msgid "Not available offline" -msgstr "" +msgstr "Ikke tilgjengelig i frakoblet modus" msgid "Created by" msgstr "Opprettet av" diff --git a/package.json b/package.json index f719aeb6e..ef28c989a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/analytics", - "version": "26.0.20", + "version": "26.1.1", "main": "./build/cjs/index.js", "module": "./build/es/index.js", "exports": { diff --git a/src/__demo__/PivotTable.stories.js b/src/__demo__/PivotTable.stories.js index b4c46f346..e06782146 100644 --- a/src/__demo__/PivotTable.stories.js +++ b/src/__demo__/PivotTable.stories.js @@ -1119,3 +1119,44 @@ storiesOf('PivotTable', module).add('DEGS', (_, { pivotTableOptions }) => { ) }) + +storiesOf('PivotTable', module).add( + 'Truncated header cell', + (_, { pivotTableOptions }) => { + const widths = [250, 200, 500] + const [width, setWidth] = useState(250) + const toggleWidth = () => + setWidth( + (currentWidth) => + widths[widths.indexOf(currentWidth) + 1] ?? widths[0] + ) + const visualization = { + ...narrativeVisualization, + ...visualizationReset, + ...pivotTableOptions, + columns: narrativeVisualization.filters, + filters: narrativeVisualization.columns, + rowTotals: true, + colTotals: true, + } + + const data = { + ...narrativeData, + rows: [narrativeData.rows[0]], + } + + return ( +
+ + +
+ ) + } +) diff --git a/src/components/PivotTable/PivotTableTitleRow.js b/src/components/PivotTable/PivotTableTitleRow.js index 681eaf1ab..ae9bfb576 100644 --- a/src/components/PivotTable/PivotTableTitleRow.js +++ b/src/components/PivotTable/PivotTableTitleRow.js @@ -1,5 +1,6 @@ +import { Tooltip } from '@dhis2/ui' import PropTypes from 'prop-types' -import React, { useState, useEffect } from 'react' +import React, { useRef, useState, useEffect } from 'react' import { PivotTableCell } from './PivotTableCell.js' import { usePivotTableEngine } from './PivotTableEngineContext.js' import { cell as cellStyle } from './styles/PivotTable.style.js' @@ -8,34 +9,66 @@ export const PivotTableTitleRow = ({ title, scrollPosition, containerWidth, - totalWidth, }) => { + const containerRef = useRef(null) + const [scrollWidth, setScrollWidth] = useState(0) + const [isTitleTruncated, setIsTitleTruncated] = useState(false) const engine = usePivotTableEngine() const columnCount = engine.width + engine.rowDepth + const maxWidth = containerWidth - (engine.cellPadding * 2 + 2) + const marginLeft = Math.max(0, scrollPosition?.x ?? 0) - const [position, setPosition] = useState(scrollPosition.x) useEffect(() => { - setPosition( - Math.max(0, Math.min(scrollPosition.x, totalWidth - containerWidth)) - ) - }, [containerWidth, scrollPosition.x, totalWidth]) + if (containerRef.current) { + /* Only set `scrollWidth` once, because during a CSS transition + * the reported value can sometimes be equal to `clientWidth` + * even though the text doesn't fit. Due to `white-space: nowrap` + * and `overflow: hidden` the `scrollWidth` should remain constant, + * so we can assume this initial value is correct. */ + if (!scrollWidth) { + setScrollWidth(containerRef.current.scrollWidth) + } + const currentScrollWidth = + scrollWidth ?? containerRef.current.scrollWidth + const newIsTitleTruncated = + currentScrollWidth > containerRef.current.clientWidth + if (newIsTitleTruncated !== isTitleTruncated) { + setIsTitleTruncated(newIsTitleTruncated) + } + } + }, [containerWidth, scrollWidth, isTitleTruncated]) + return (
- {title} + {isTitleTruncated ? ( + + {({ ref: tooltipRef, onMouseOver, onMouseOut }) => ( +
+ {title} +
+ )} +
+ ) : ( + title + )}
@@ -47,5 +80,4 @@ PivotTableTitleRow.propTypes = { scrollPosition: PropTypes.shape({ x: PropTypes.number.isRequired }) .isRequired, title: PropTypes.string.isRequired, - totalWidth: PropTypes.number.isRequired, } diff --git a/src/components/PivotTable/PivotTableTitleRows.js b/src/components/PivotTable/PivotTableTitleRows.js index 34ad04e33..8a3439c9d 100644 --- a/src/components/PivotTable/PivotTableTitleRows.js +++ b/src/components/PivotTable/PivotTableTitleRows.js @@ -13,10 +13,6 @@ export const PivotTableTitleRows = ({ clippingResult, width }) => { title={engine.options.title} scrollPosition={clippingResult.scrollPosition} containerWidth={width} - totalWidth={ - engine.adaptiveClippingController.columns.totalSize + - engine.adaptiveClippingController.columns.headerSize - } /> ) : null} {engine.options.subtitle ? ( @@ -24,10 +20,6 @@ export const PivotTableTitleRows = ({ clippingResult, width }) => { title={engine.options.subtitle} scrollPosition={clippingResult.scrollPosition} containerWidth={width} - totalWidth={ - engine.adaptiveClippingController.columns.totalSize + - engine.adaptiveClippingController.columns.headerSize - } /> ) : null} {engine.visualization.filters?.length ? ( @@ -38,10 +30,6 @@ export const PivotTableTitleRows = ({ clippingResult, width }) => { )} scrollPosition={clippingResult.scrollPosition} containerWidth={width} - totalWidth={ - engine.adaptiveClippingController.columns.totalSize + - engine.adaptiveClippingController.columns.headerSize - } /> ) : null} diff --git a/src/components/PivotTable/styles/PivotTable.style.js b/src/components/PivotTable/styles/PivotTable.style.js index 23cfab64b..00bf7c6a6 100644 --- a/src/components/PivotTable/styles/PivotTable.style.js +++ b/src/components/PivotTable/styles/PivotTable.style.js @@ -109,9 +109,25 @@ export const cell = css` align-items: center; justify-content: center; } - .title { + .title-cell { font-weight: bold; background-color: #cddaed; + padding: 0; + } + .title-cell-content { + text-align: center; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + .title-cell.displaydensity-COMPACT > .title-cell-content { + padding: ${DISPLAY_DENSITY_PADDING_COMPACT}px; + } + .title-cell.displaydensity-NORMAL > .title-cell-content { + padding: ${DISPLAY_DENSITY_PADDING_NORMAL}px; + } + .title-cell.displaydensity-COMFORTABLE > .title-cell-content { + padding: ${DISPLAY_DENSITY_PADDING_COMFORTABLE}px; } .row-header { background-color: #dae6f8; diff --git a/src/visualizations/config/adapters/dhis_highcharts/chart.js b/src/visualizations/config/adapters/dhis_highcharts/chart.js index 9174ad816..e50a52ca9 100644 --- a/src/visualizations/config/adapters/dhis_highcharts/chart.js +++ b/src/visualizations/config/adapters/dhis_highcharts/chart.js @@ -22,7 +22,11 @@ const getEvents = () => ({ if (item.legendSymbol) { item.legendSymbol.attr({ translateY: - -((item.legendItem.getBBox().height * 0.75) / 4) + + -( + (item.legendItem.label.getBBox().height * + 0.75) / + 4 + ) + item.legendSymbol.r / 2, }) } diff --git a/src/visualizations/config/generators/highcharts/index.js b/src/visualizations/config/generators/highcharts/index.js index ca8ad2b3d..92a775910 100644 --- a/src/visualizations/config/generators/highcharts/index.js +++ b/src/visualizations/config/generators/highcharts/index.js @@ -20,6 +20,8 @@ function drawLegendSymbolWrap() { H.seriesTypes.column.prototype, 'drawLegendSymbol', function (proceed, legend, item) { + const legendItem = item.legendItem + if (this.options.legendSet?.legends?.length) { const ys = legend.baseline - legend.symbolHeight + 1, // y start x = legend.symbolWidth / 2 > 8 ? legend.symbolWidth / 2 : 8, // x start @@ -32,7 +34,7 @@ function drawLegendSymbolWrap() { .attr({ fill: legends[legends.length >= 5 ? 1 : 0].color, }) - .add(this.legendGroup) + .add(legendItem.group) this.chart.renderer .path(['M', x, ye, 'A', 1, 1, 0, 0, 0, x, ys, 'V', ye]) .attr({ @@ -42,13 +44,14 @@ function drawLegendSymbolWrap() { : legends.length - 1 ].color, }) - .add(this.legendGroup) + .add(legendItem.group) } else { var options = legend.options, symbolHeight = legend.symbolHeight, square = options.squareSymbol, symbolWidth = square ? symbolHeight : legend.symbolWidth - item.legendSymbol = this.chart.renderer + + legendItem.symbol = this.chart.renderer .rect( square ? (legend.symbolWidth - symbolHeight) / 2 : 0, legend.baseline - symbolHeight + 1, @@ -60,7 +63,7 @@ function drawLegendSymbolWrap() { .attr({ zIndex: 3, }) - .add(item.legendGroup) + .add(legendItem.group) } } )