Skip to content

Commit

Permalink
v4.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
novykh committed Nov 2, 2023
1 parent 0c6fc06 commit 8a8fa99
Show file tree
Hide file tree
Showing 14 changed files with 101 additions and 94 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
4 changes: 2 additions & 2 deletions src/chartLibraries/d3pie/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions src/components/bars/dimension.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ const AnnotationsValue = ({ children: annotations, ...rest }) => (
</Flex>
)

const Dimension = ({ id, strong, chars, rowFlavour, fullCols }) => {
const Dimension = ({ id, strong, rowFlavour, fullCols }) => {
const visible = useVisibleDimensionId(id)

const chart = useChart()
Expand All @@ -82,7 +82,7 @@ const Dimension = ({ id, strong, chars, rowFlavour, fullCols }) => {
>
<Color id={id} />
</ColorBackground>
<Name padding={[0.5, 1]} flex id={id} strong={strong} maxLength={chars} fontSize="1.1em" />
<Name padding={[0.5, 1]} flex id={id} strong={strong} fontSize="1.1em" />
</Flex>
<Value
id={id}
Expand Down
1 change: 0 additions & 1 deletion src/components/bars/dimensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ const Dimensions = ({ height, width }) => {
key={id}
id={id}
strong={row === id}
chars={parseInt(width / (cols === "full" ? 15 : 8))}
rowFlavour={rowFlavour}
fullCols={cols === "full"}
/>
Expand Down
2 changes: 1 addition & 1 deletion src/components/container.js
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
37 changes: 27 additions & 10 deletions src/components/helpers/shortener.js
Original file line number Diff line number Diff line change
@@ -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 (
<Tooltip content={text}>
<Component {...rest}>{truncated}</Component>
</Tooltip>
)
const [ref, setRef] = useState()

return <Component {...rest}>{truncated}</Component>
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 (
<Tooltip content={!noTooltip && shortenText ? text : ""} align="bottom" isBasic>
<Component truncate ref={setRef} {...rest}>
{text}
</Component>
</Tooltip>
)
}

export default Shortener
28 changes: 15 additions & 13 deletions src/components/hocs/withDeferredMount.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 <Component ref={ref} {...rest} />
})
return <Component ref={ref} height={height} width={width} {...rest} />
}
)

return DifferedMount
}
12 changes: 6 additions & 6 deletions src/components/hocs/withTile.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ export const HeadWrapper = ({ children, uiName, ...rest }) => {

return (
<ChartHeadWrapper size={size} {...rest} ref={hoverRef}>
<Flex column width="24px" padding={[2, 1]}>
<Flex column width={5} padding={[2, 0]}>
<Status plain />
<Collapsible open={focused} column>
<Collapsible open={focused} column width={5}>
<FilterToolbox
column
background="elementBackground"
Expand All @@ -104,7 +104,7 @@ export const HeadWrapper = ({ children, uiName, ...rest }) => {
<Title />
{children}
</Flex>
<Flex column width="24px" alignItems="center" padding={[4, 1]} gap={2}>
<Flex column width={5} alignItems="center" padding={[4, 0]} gap={2}>
{firstDim === "selected" && (
<>
<Flex
Expand Down Expand Up @@ -145,13 +145,13 @@ export const ChartWrapper = styled(Flex).attrs(props => ({
}))``

export default Component =>
({ count, tile = true, ...rest }) =>
({ count, tile = true, height = "100%", width = "100%", ...rest }) =>
tile ? (
<HeadWrapper count={count} uiName={rest.uiName}>
<HeadWrapper count={count} uiName={rest.uiName} height={height} width={width}>
<Component {...rest} />
</HeadWrapper>
) : (
<ChartHeadWrapper size={20}>
<ChartHeadWrapper size={20} height={height} width={width}>
<Component {...rest} />
</ChartHeadWrapper>
)
3 changes: 1 addition & 2 deletions src/components/line/dimensions/name.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) => (
<Shortener
text={children}
maxLength={maxLength}
Component={TextMicro}
color="textDescription"
whiteSpace="nowrap"
Expand Down
2 changes: 1 addition & 1 deletion src/components/line/legend/dimension.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ const Dimension = forwardRef(({ id }, ref) => {
content={visible ? <TooltipValue id={id} name={name} /> : null}
>
<Flex flex column overflow="hidden" data-testid="chartLegendDimension-details">
<Name id={id} maxLength={32} noTooltip />
<Name id={id} noTooltip />

<AnomalyProgressBar id={id} />

Expand Down
3 changes: 1 addition & 2 deletions src/components/line/popover/dimension.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const AnnotationsValue = ({ children: annotations, showFull, ...rest }) => (
</Flex>
)

const Dimension = ({ id, strong, chars, rowFlavour }) => {
const Dimension = ({ id, strong, rowFlavour }) => {
const visible = useVisibleDimensionId(id)

const chart = useChart()
Expand All @@ -86,7 +86,6 @@ const Dimension = ({ id, strong, chars, rowFlavour }) => {
flex
id={id}
strong={strong}
maxLength={chars}
noTooltip
color={strong ? "textFocus" : "text"}
/>
Expand Down
8 changes: 1 addition & 7 deletions src/components/line/popover/dimensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,7 @@ const Dimensions = ({ uiName }) => {
</TextMicro>
</GridHeader>
{ids.map(id => (
<Dimension
key={id}
id={id}
strong={row === id}
chars={chartWidth < 600 ? 50 : 100}
rowFlavour={rowFlavour}
/>
<Dimension key={id} id={id} strong={row === id} rowFlavour={rowFlavour} />
))}
</Grid>
<Flex flex={false} height={3}>
Expand Down
22 changes: 13 additions & 9 deletions src/components/tooltip/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,19 @@ const DefaultContent = ({ children, ...rest }) => (
</Flex>
)

const Tooltip = forwardRef(({ content, Content = DefaultContent, ...rest }, ref) => (
<BaseTooltip
ref={ref}
plain
content={<Content {...rest}>{content}</Content>}
{...rest}
dropProps={{ "data-toolbox": true }}
/>
))
const Tooltip = forwardRef(({ content, Content = DefaultContent, ...rest }, ref) =>
content ? (
<BaseTooltip
ref={ref}
plain
content={<Content {...rest}>{content}</Content>}
{...rest}
dropProps={{ "data-toolbox": true }}
/>
) : (
rest.children
)
)

Tooltip.defaultProps = {
align: "bottom",
Expand Down
67 changes: 30 additions & 37 deletions src/helpers/shorten/index.js
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 8a8fa99

Please sign in to comment.