Skip to content
This repository has been archived by the owner on Sep 30, 2024. It is now read-only.

Fix chart label in Firefox for code insight pie chart #20120

Merged
merged 3 commits into from
Apr 19, 2021
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
56 changes: 49 additions & 7 deletions client/web/src/views/ChartViewContent/annotation/Label.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
// This component is a fork of Lable component from @visx/annotaion package
// Replace this component by original when https://github.com/airbnb/visx/issues/1126 will be resolved
// This component is a fork of Label component from @visx/annotaion package
// Replace this component by original when https://github.com/airbnb/visx/issues/1111 will be resolved

import { AnnotationContext } from '@visx/annotation'
import Group from '@visx/group/lib/Group'
import Text, { TextProps } from '@visx/text/lib/Text'
import classnames from 'classnames'
import { useText } from '@visx/text'
import { TextProps as OriginTextProps } from '@visx/text/lib/Text'
import classname from 'classnames'
import React, { ReactElement, useContext, useMemo } from 'react'
import useMeasure, { Options as UseMeasureOptions } from 'react-use-measure'

import { Text, TextProps } from './Text'

export interface LabelProps {
/** Stroke color of anchor line. */
anchorLineStroke?: string
Expand Down Expand Up @@ -51,6 +54,8 @@ export interface LabelProps {
verticalAnchor?: TextProps['verticalAnchor']
/** Width of annotation, including background, for text wrapping. */
width?: number
/** Max width of annotation, including background, for text wrapping. */
maxWidth?: number
/** Left offset of entire AnnotationLabel, if not specified uses x + dx from Annotation. */
x?: number
/** Top offset of entire AnnotationLabel, if not specified uses y + dy from Annotation. */
Expand Down Expand Up @@ -91,6 +96,7 @@ export function Label({
titleProps,
verticalAnchor: propsVerticalAnchor,
width: propertyWidth,
maxWidth = 125,
x: propsX,
y: propsY,
}: LabelProps): ReactElement | null {
Expand All @@ -105,9 +111,45 @@ export function Label({
const { x = 0, y = 0, dx = 0, dy = 0 } = useContext(AnnotationContext)
const height = Math.floor(padding.top + padding.bottom + (titleBounds.height ?? 0) + (subtitleBounds.height ?? 0))

const measuredWidth = padding.right + padding.left + Math.max(titleBounds.width ?? 0, subtitleBounds.width ?? 0)
const { wordsByLines: titleWordsByLine } = useText({
children: title,
verticalAnchor: 'start',
capHeight: titleFontSize,
width: maxWidth,
style: {
fontSize: `${titleFontSize}px`,
fontWeight: titleFontWeight as any,
},
...(titleProps as OriginTextProps),
})

const { wordsByLines: subtitleWordsByLine } = useText({
children: subtitle,
verticalAnchor: 'start',
capHeight: subtitleFontSize,
width: maxWidth,
style: {
fontSize: `${subtitleFontSize}px`,
fontWeight: subtitleFontWeight as any,
// fontFamily: subtitleProps?.fontFamily,
},
...(subtitleProps as OriginTextProps),
})

const titleMeasuredWidth = titleWordsByLine.reduce(
(maxTitleWidth, line) => Math.max(maxTitleWidth, line.width ?? 0),
0
)

const subtitleMeasuredWidth = subtitleWordsByLine.reduce(
(maxSubtitleWidth, line) => Math.max(maxSubtitleWidth, line.width ?? 0),
0
)

const textMeasuredWidth = Math.ceil(Math.min(maxWidth, Math.max(titleMeasuredWidth, subtitleMeasuredWidth)))
const measuredWidth = padding.right + padding.left + textMeasuredWidth
const width = propertyWidth ?? measuredWidth
const innerWidth = (width ?? measuredWidth) - padding.left - padding.right
const innerWidth = width - padding.left - padding.right

// offset container position based on horizontal + vertical anchor
const horizontalAnchor =
Expand Down Expand Up @@ -163,7 +205,7 @@ export function Label({
top={containerCoords.y}
left={containerCoords.x}
pointerEvents="none"
className={classnames('visx-annotationlabel', className)}
className={classname('visx-annotationlabel', className)}
opacity={titleBounds.height === 0 && subtitleBounds.height === 0 ? 0 : 1}
>
{showBackground && (
Expand Down
56 changes: 56 additions & 0 deletions client/web/src/views/ChartViewContent/annotation/Text.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* Forked component from @visx/text package.
* Removed https://github.com/airbnb/visx/issues/1111 when will be resolved
* */
import { useText, TextProps as OriginTextProps } from '@visx/text'
import React, { ReactElement } from 'react'

const SVG_STYLE = { overflow: 'visible' }

/**
* Origin text props with changed innerRef is equal to ref of text element
* origin value = ref of svg element. Because firefox has bug with measurements
* nested svg element without sizes we have to measure sizes of text element instead.
* */
export interface TextProps extends Omit<OriginTextProps, 'innerRef'> {
/** Ref access to text element */
innerRef?: React.Ref<SVGTextElement>
}

/**
* Displays svg text element.
* */
export function Text(props: TextProps): ReactElement {
const {
dx: xCoord = 0,
dy: yCoord = 0,
textAnchor = 'start',
innerRef,
verticalAnchor,
angle,
lineHeight = '1em',
scaleToFit = false,
capHeight,
width,
...textProps
} = props

// eslint-disable-next-line id-length
const { x = 0, fontSize } = textProps
const { wordsByLines, startDy, transform } = useText(props as OriginTextProps)

return (
// eslint-disable-next-line react/forbid-dom-props
<svg x={xCoord} y={yCoord} fontSize={fontSize} style={SVG_STYLE}>
{wordsByLines.length > 0 ? (
<text ref={innerRef} transform={transform} {...textProps} textAnchor={textAnchor}>
{wordsByLines.map((line, index) => (
<tspan key={index} x={x} dy={index === 0 ? startDy : lineHeight}>
{line.words.join(' ')}
</tspan>
))}
</text>
) : null}
</svg>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ export function PieArc<Datum>(props: PieArcProps<Datum>): ReactElement {
showAnchorLine={false}
title={name}
subtitleDy={0}
titleFontWeight={200}
subtitleFontWeight={200}
titleProps={TITLE_PROPS}
subtitleProps={SUBTITLE_PROPS}
subtitle={labelSubtitle}
Expand Down