|
|
@ -1,8 +1,8 @@ |
|
|
import { Axis, Chart, Geom, Tooltip } from 'bizcharts'; |
|
|
import { Axis, Chart, Geom, Tooltip } from 'bizcharts'; |
|
|
import React, { Component } from 'react'; |
|
|
import React, { useCallback, useEffect, useRef, useState } from 'react'; |
|
|
import Debounce from 'lodash.debounce'; |
|
|
import Debounce from 'lodash.debounce'; |
|
|
import autoHeight from '../autoHeight'; |
|
|
|
|
|
import useStyles from '../index.style'; |
|
|
import useStyles from '../index.style'; |
|
|
|
|
|
|
|
|
export type BarProps = { |
|
|
export type BarProps = { |
|
|
title: React.ReactNode; |
|
|
title: React.ReactNode; |
|
|
color?: string; |
|
|
color?: string; |
|
|
@ -16,123 +16,107 @@ export type BarProps = { |
|
|
autoLabel?: boolean; |
|
|
autoLabel?: boolean; |
|
|
style?: React.CSSProperties; |
|
|
style?: React.CSSProperties; |
|
|
}; |
|
|
}; |
|
|
class Bar extends Component< |
|
|
const Bar: React.FC<BarProps> = ({ |
|
|
BarProps, |
|
|
height = 1, |
|
|
{ |
|
|
title, |
|
|
autoHideXLabels: boolean; |
|
|
forceFit = true, |
|
|
} |
|
|
data, |
|
|
> { |
|
|
color = 'rgba(24, 144, 255, 0.85)', |
|
|
state = { |
|
|
padding, |
|
|
autoHideXLabels: false, |
|
|
autoLabel = true, |
|
|
}; |
|
|
}) => { |
|
|
root: HTMLDivElement | undefined = undefined; |
|
|
const { styles } = useStyles(); |
|
|
node: HTMLDivElement | undefined = undefined; |
|
|
const [autoHideXLabels, setAutoHideXLabels] = useState(false); |
|
|
resize = Debounce(() => { |
|
|
const rootRef = useRef<HTMLDivElement | null>(null); |
|
|
if (!this.node || !this.node.parentNode) { |
|
|
const nodeRef = useRef<HTMLDivElement | null>(null); |
|
|
return; |
|
|
|
|
|
} |
|
|
const resize = useCallback( |
|
|
const canvasWidth = (this.node.parentNode as HTMLDivElement).clientWidth; |
|
|
Debounce(() => { |
|
|
const { data = [], autoLabel = true } = this.props; |
|
|
if (!nodeRef.current || !nodeRef.current.parentNode) { |
|
|
if (!autoLabel) { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
const canvasWidth = nodeRef.current.parentNode?.clientWidth || 0; |
|
|
const minWidth = data.length * 30; |
|
|
if (!autoLabel) { |
|
|
const { autoHideXLabels } = this.state; |
|
|
return; |
|
|
if (canvasWidth <= minWidth) { |
|
|
|
|
|
if (!autoHideXLabels) { |
|
|
|
|
|
this.setState({ |
|
|
|
|
|
autoHideXLabels: true, |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
} |
|
|
} else if (autoHideXLabels) { |
|
|
const minWidth = data?.length * 30; |
|
|
this.setState({ |
|
|
if (canvasWidth <= minWidth) { |
|
|
autoHideXLabels: false, |
|
|
if (!autoHideXLabels) { |
|
|
}); |
|
|
setAutoHideXLabels(true); |
|
|
} |
|
|
} |
|
|
}, 500); |
|
|
} else if (autoHideXLabels) { |
|
|
componentDidMount() { |
|
|
setAutoHideXLabels(false); |
|
|
window.addEventListener('resize', this.resize, { |
|
|
} |
|
|
|
|
|
}, 500), |
|
|
|
|
|
[autoHideXLabels, autoLabel, data?.length], |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
|
window.addEventListener('resize', resize, { |
|
|
passive: true, |
|
|
passive: true, |
|
|
}); |
|
|
}); |
|
|
} |
|
|
return () => { |
|
|
componentWillUnmount() { |
|
|
window.removeEventListener('resize', resize); |
|
|
window.removeEventListener('resize', this.resize); |
|
|
|
|
|
} |
|
|
|
|
|
handleRoot = (n: HTMLDivElement) => { |
|
|
|
|
|
this.root = n; |
|
|
|
|
|
}; |
|
|
|
|
|
handleRef = (n: HTMLDivElement) => { |
|
|
|
|
|
this.node = n; |
|
|
|
|
|
}; |
|
|
|
|
|
render() { |
|
|
|
|
|
const { |
|
|
|
|
|
height = 1, |
|
|
|
|
|
title, |
|
|
|
|
|
forceFit = true, |
|
|
|
|
|
data, |
|
|
|
|
|
color = 'rgba(24, 144, 255, 0.85)', |
|
|
|
|
|
padding, |
|
|
|
|
|
} = this.props; |
|
|
|
|
|
const { autoHideXLabels } = this.state; |
|
|
|
|
|
const scale = { |
|
|
|
|
|
x: { |
|
|
|
|
|
type: 'cat', |
|
|
|
|
|
}, |
|
|
|
|
|
y: { |
|
|
|
|
|
min: 0, |
|
|
|
|
|
}, |
|
|
|
|
|
}; |
|
|
}; |
|
|
const tooltip: [ |
|
|
}, [resize]); |
|
|
string, |
|
|
|
|
|
(...args: any[]) => { |
|
|
const handleRoot = useCallback((n: HTMLDivElement) => { |
|
|
name?: string; |
|
|
rootRef.current = n; |
|
|
value: string; |
|
|
}, []); |
|
|
}, |
|
|
|
|
|
] = [ |
|
|
const handleRef = useCallback((n: HTMLDivElement) => { |
|
|
'x*y', |
|
|
nodeRef.current = n; |
|
|
(x: string, y: string) => ({ |
|
|
}, []); |
|
|
name: x, |
|
|
|
|
|
value: y, |
|
|
const scale = { |
|
|
}), |
|
|
x: { |
|
|
]; |
|
|
type: 'cat', |
|
|
return ( |
|
|
}, |
|
|
<div |
|
|
y: { |
|
|
className={styles.chart} |
|
|
min: 0, |
|
|
style={{ |
|
|
}, |
|
|
height, |
|
|
}; |
|
|
}} |
|
|
|
|
|
ref={this.handleRoot} |
|
|
const tooltip = [ |
|
|
> |
|
|
'x*y', |
|
|
<div ref={this.handleRef}> |
|
|
(x: string, y: string) => ({ |
|
|
{title && ( |
|
|
name: x, |
|
|
<h4 |
|
|
value: y, |
|
|
style={{ |
|
|
}), |
|
|
marginBottom: 20, |
|
|
]; |
|
|
}} |
|
|
|
|
|
> |
|
|
return ( |
|
|
{title} |
|
|
<div className={styles.chart} style={{ height }} ref={handleRoot}> |
|
|
</h4> |
|
|
<div ref={handleRef}> |
|
|
)} |
|
|
{title && ( |
|
|
<Chart |
|
|
<h4 |
|
|
scale={scale} |
|
|
style={{ |
|
|
height={title ? height - 41 : height} |
|
|
marginBottom: 20, |
|
|
forceFit={forceFit} |
|
|
}} |
|
|
data={data} |
|
|
|
|
|
padding={padding || 'auto'} |
|
|
|
|
|
> |
|
|
> |
|
|
<Axis |
|
|
{title} |
|
|
name="x" |
|
|
</h4> |
|
|
title={false} |
|
|
)} |
|
|
label={autoHideXLabels ? undefined : {}} |
|
|
<Chart |
|
|
tickLine={autoHideXLabels ? undefined : {}} |
|
|
scale={scale} |
|
|
/> |
|
|
height={title ? height - 41 : height} |
|
|
<Axis name="y" min={0} /> |
|
|
forceFit={forceFit} |
|
|
<Tooltip showTitle={false} crosshairs={false} /> |
|
|
data={data} |
|
|
<Geom type="interval" position="x*y" color={color} tooltip={tooltip} /> |
|
|
padding={padding || 'auto'} |
|
|
</Chart> |
|
|
> |
|
|
</div> |
|
|
<Axis |
|
|
|
|
|
name="x" |
|
|
|
|
|
title={false} |
|
|
|
|
|
label={autoHideXLabels ? undefined : {}} |
|
|
|
|
|
tickLine={autoHideXLabels ? undefined : {}} |
|
|
|
|
|
/> |
|
|
|
|
|
<Axis name="y" min={0} /> |
|
|
|
|
|
<Tooltip showTitle={false} crosshairs={false} /> |
|
|
|
|
|
<Geom type="interval" position="x*y" color={color} tooltip={tooltip} /> |
|
|
|
|
|
</Chart> |
|
|
</div> |
|
|
</div> |
|
|
); |
|
|
</div> |
|
|
} |
|
|
); |
|
|
} |
|
|
}; |
|
|
export default autoHeight()(Bar); |
|
|
|
|
|
|
|
|
export default Bar; |
|
|
|