diff --git a/package.json b/package.json
index afaf4c75f..b2a146d17 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@netdata/charts",
- "version": "4.2.1",
+ "version": "4.3.0",
"description": "Netdata frontend SDK and chart utilities",
"main": "dist/index.js",
"module": "dist/es6/index.js",
diff --git a/src/chartLibraries/d3pie/index.js b/src/chartLibraries/d3pie/index.js
index 740fda2bf..e379faaf1 100644
--- a/src/chartLibraries/d3pie/index.js
+++ b/src/chartLibraries/d3pie/index.js
@@ -2,7 +2,7 @@ import makeChartUI from "@/sdk/makeChartUI"
import { unregister } from "@/helpers/makeListeners"
import makeResizeObserver from "@/helpers/makeResizeObserver"
import makeExecuteLatest from "@/helpers/makeExecuteLatest"
-import shorten from "@/helpers/shorten"
+import { shortForLength } from "@/helpers/shorten"
import d3pie from "./library"
import getInitialOptions from "./getInitialOptions"
@@ -75,7 +75,7 @@ export default (sdk, chart) => {
const values = dimensionIds
.map(id => ({
- label: shorten(id, 30),
+ label: shortForLength(id, 30),
value: chart.getDimensionValue(id, index),
color: chart.selectDimensionColor(id),
caption: id,
diff --git a/src/components/bars/dimension.js b/src/components/bars/dimension.js
index 5a7168a3a..d301ef3c1 100644
--- a/src/components/bars/dimension.js
+++ b/src/components/bars/dimension.js
@@ -66,7 +66,7 @@ const AnnotationsValue = ({ children: annotations, ...rest }) => (
)
-const Dimension = ({ id, strong, chars, rowFlavour, fullCols }) => {
+const Dimension = ({ id, strong, rowFlavour, fullCols }) => {
const visible = useVisibleDimensionId(id)
const chart = useChart()
@@ -82,7 +82,7 @@ const Dimension = ({ id, strong, chars, rowFlavour, fullCols }) => {
>
-
+
{
key={id}
id={id}
strong={row === id}
- chars={parseInt(width / (cols === "full" ? 15 : 8))}
rowFlavour={rowFlavour}
fullCols={cols === "full"}
/>
diff --git a/src/components/container.js b/src/components/container.js
index 1363a7bee..46925611b 100644
--- a/src/components/container.js
+++ b/src/components/container.js
@@ -1,7 +1,7 @@
import styled from "styled-components"
import { Flex } from "@netdata/netdata-ui"
-const Container = styled(Flex).attrs(({ height, width, ...rest }) => ({
+const Container = styled(Flex).attrs(({ height = "100%", width = "100%", ...rest }) => ({
"data-testid": "chart",
column: true,
position: "relative",
diff --git a/src/components/helpers/shortener.js b/src/components/helpers/shortener.js
index 6f9950d55..a13715345 100644
--- a/src/components/helpers/shortener.js
+++ b/src/components/helpers/shortener.js
@@ -1,18 +1,35 @@
-import React, { useMemo } from "react"
+import React, { useState, useEffect } from "react"
import shorten from "@/helpers/shorten"
import Tooltip from "@/components/tooltip"
-const Shortener = ({ text, maxLength = 15, Component = "div", noTooltip, ...rest }) => {
- const truncated = useMemo(() => (text ? shorten(text, maxLength) : null), [text, maxLength])
+const Shortener = ({ text, Component = "div", noTooltip, ...rest }) => {
+ const [shortenText, setShortenText] = useState("")
- if (!noTooltip && truncated !== text)
- return (
-
- {truncated}
-
- )
+ const [ref, setRef] = useState()
- return {truncated}
+ useEffect(() => {
+ if (!ref) return
+
+ const containerWidth = ref.offsetWidth
+ let round = 0
+
+ while (ref.scrollWidth > containerWidth) {
+ ref.textContent = shorten(ref.textContent, round)
+ round = round + 1
+ }
+
+ if (ref.textContent !== text) {
+ setShortenText(text)
+ }
+ }, [text, ref])
+
+ return (
+
+
+ {text}
+
+
+ )
}
export default Shortener
diff --git a/src/components/hocs/withDeferredMount.js b/src/components/hocs/withDeferredMount.js
index ad8e7b578..e418214ce 100644
--- a/src/components/hocs/withDeferredMount.js
+++ b/src/components/hocs/withDeferredMount.js
@@ -2,23 +2,25 @@ import React, { forwardRef } from "react"
import { useChart, useImmediateListener } from "@/components/provider"
export default Component => {
- const DifferedMount = forwardRef(({ isVisible = true, ...rest }, ref) => {
- const chart = useChart()
+ const DifferedMount = forwardRef(
+ ({ isVisible = true, height = "100%", width = "100%", ...rest }, ref) => {
+ const chart = useChart()
- useImmediateListener(() => {
- if (!isVisible) return
- if (!!rest.uiName && rest.uiName !== "default") return
+ useImmediateListener(() => {
+ if (!isVisible) return
+ if (!!rest.uiName && rest.uiName !== "default") return
- const id = window.requestAnimationFrame(chart.activate)
+ const id = window.requestAnimationFrame(chart.activate)
- return () => {
- window.cancelAnimationFrame(id)
- chart.deactivate()
- }
- }, [isVisible, chart, rest.uiName])
+ return () => {
+ window.cancelAnimationFrame(id)
+ chart.deactivate()
+ }
+ }, [isVisible, chart, rest.uiName])
- return
- })
+ return
+ }
+ )
return DifferedMount
}
diff --git a/src/components/hocs/withTile.js b/src/components/hocs/withTile.js
index 88a8a7fcc..1a366c1cc 100644
--- a/src/components/hocs/withTile.js
+++ b/src/components/hocs/withTile.js
@@ -79,9 +79,9 @@ export const HeadWrapper = ({ children, uiName, ...rest }) => {
return (
-
+
-
+
{
{children}
-
+
{firstDim === "selected" && (
<>
({
}))``
export default Component =>
- ({ count, tile = true, ...rest }) =>
+ ({ count, tile = true, height = "100%", width = "100%", ...rest }) =>
tile ? (
-
+
) : (
-
+
)
diff --git a/src/components/line/dimensions/name.js b/src/components/line/dimensions/name.js
index 6ccf6b0ce..da74c92cb 100644
--- a/src/components/line/dimensions/name.js
+++ b/src/components/line/dimensions/name.js
@@ -4,10 +4,9 @@ import { useChart } from "@/components/provider"
import Shortener from "@/components/helpers/shortener"
export const Name = memo(
- forwardRef(({ children, maxLength = 32, ...rest }, ref) => (
+ forwardRef(({ children, ...rest }, ref) => (
{
content={visible ? : null}
>
-
+
diff --git a/src/components/line/popover/dimension.js b/src/components/line/popover/dimension.js
index 28e243d60..f616f6ace 100644
--- a/src/components/line/popover/dimension.js
+++ b/src/components/line/popover/dimension.js
@@ -64,7 +64,7 @@ const AnnotationsValue = ({ children: annotations, showFull, ...rest }) => (
)
-const Dimension = ({ id, strong, chars, rowFlavour }) => {
+const Dimension = ({ id, strong, rowFlavour }) => {
const visible = useVisibleDimensionId(id)
const chart = useChart()
@@ -86,7 +86,6 @@ const Dimension = ({ id, strong, chars, rowFlavour }) => {
flex
id={id}
strong={strong}
- maxLength={chars}
noTooltip
color={strong ? "textFocus" : "text"}
/>
diff --git a/src/components/line/popover/dimensions.js b/src/components/line/popover/dimensions.js
index 227233c53..32dd1ff28 100644
--- a/src/components/line/popover/dimensions.js
+++ b/src/components/line/popover/dimensions.js
@@ -144,13 +144,7 @@ const Dimensions = ({ uiName }) => {
{ids.map(id => (
-
+
))}
diff --git a/src/components/tooltip/index.js b/src/components/tooltip/index.js
index b7bc70d19..2e64c57d2 100644
--- a/src/components/tooltip/index.js
+++ b/src/components/tooltip/index.js
@@ -18,15 +18,19 @@ const DefaultContent = ({ children, ...rest }) => (
)
-const Tooltip = forwardRef(({ content, Content = DefaultContent, ...rest }, ref) => (
- {content}}
- {...rest}
- dropProps={{ "data-toolbox": true }}
- />
-))
+const Tooltip = forwardRef(({ content, Content = DefaultContent, ...rest }, ref) =>
+ content ? (
+ {content}}
+ {...rest}
+ dropProps={{ "data-toolbox": true }}
+ />
+ ) : (
+ rest.children
+ )
+)
Tooltip.defaultProps = {
align: "bottom",
diff --git a/src/helpers/shorten/index.js b/src/helpers/shorten/index.js
index 8345067a5..c062dcf2a 100644
--- a/src/helpers/shorten/index.js
+++ b/src/helpers/shorten/index.js
@@ -1,61 +1,54 @@
const removeMiddleVowels = word => {
- if (/\d/.test(word)) return word
+ if (/\d/.test(word) || word.length < 4) return word
+
const middle = word.substring(1, word.length - 1)
return [word.charAt(0), middle.replace(/([aeiou])/gi, ""), word.charAt(word.length - 1)].join("")
}
const removeDuplicateLetters = word => word.replace(/(\w)\1+/g, "$1")
-const ellipsisInMiddle = (text, maxLength) => {
- const partLength = Math.floor((maxLength - 3) / 2)
+const ellipsisInMiddle = (text, length) => {
+ const partLength = Math.floor((text.length - length) / 2)
const prefix = text.substring(0, partLength)
const suffix = text.substring(text.length - partLength)
return `${prefix}...${suffix}`
}
-const replaceIfNeeded = (text, func, maxLength) => {
- if (text.length <= maxLength) return text
- return text.replace(/(\w.+?|\d.+)([\s-_.@]+?)/g, (_, word, sep) => {
- word = func(word, maxLength)
+const replaceIfNeeded = (text, func, ...args) => {
+ if (!text) return ""
- return `${word}${sep}`
+ return text.replace(/([\w\d].+?)([\s-_@])([\w\d].+)+?/, (_, word, sep, word2) => {
+ return `${func(word, ...args)}${sep}${replaceIfNeeded(word2, func, ...args)}`
})
}
-const shortenSingleString = (string, maxLength) => {
- string = removeDuplicateLetters(removeMiddleVowels(string))
-
- if (string.length <= maxLength) return string
-
- return ellipsisInMiddle(string, maxLength)
+const shorten = (string, round = 0) => {
+ if (!string || typeof string !== "string") return string
+
+ switch (round) {
+ case 0:
+ return string.trim()
+ case 1:
+ return replaceIfNeeded(string, removeDuplicateLetters)
+ case 2:
+ return replaceIfNeeded(string, removeMiddleVowels)
+ default:
+ return ellipsisInMiddle(string, round)
+ }
}
-export default (string, maxLength = 60) => {
- if (!string) return string
- if (string.length <= maxLength) return string
-
- const match = string.trim().match(/(.+[\s-_.@])(.+)$/)
-
- if (!match) return shortenSingleString(string, maxLength)
+export const shortForLength = (string, maxLength = 30) => {
+ if (!string || typeof string !== "string") return string
- let [, text, lastText] = match
+ let round = 0
- const hasSeparators = text.match(/[\s-_.@]/)
-
- if (hasSeparators) {
- text = replaceIfNeeded(text, removeMiddleVowels, maxLength - lastText.length)
- text = replaceIfNeeded(text, removeDuplicateLetters, maxLength - lastText.length)
- } else {
- text = removeDuplicateLetters(removeMiddleVowels(lastText))
+ while (string.length > maxLength) {
+ string = shorten(string, round)
+ round = round + 1
}
- if ((text + lastText).length <= maxLength) return text + lastText
-
- lastText = removeDuplicateLetters(removeMiddleVowels(lastText))
-
- if ((text + lastText).length <= maxLength) return text + lastText
-
- text = text + lastText
- return ellipsisInMiddle(text, maxLength)
+ return string
}
+
+export default shorten