123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- import './components/markPoint';
- import {useMemo} from 'react';
- import {useTheme} from '@emotion/react';
- import type {GridComponentOption} from 'echarts';
- import set from 'lodash/set';
- import {formatAbbreviatedNumber} from 'sentry/utils/formatters';
- import type {BarChartProps, BarChartSeries} from './barChart';
- import {BarChart} from './barChart';
- import type {BaseChartProps} from './baseChart';
- function makeBaseChartOptions({
- animateBars,
- height,
- hideDelay,
- tooltipFormatter,
- labelYAxisExtents,
- showMarkLineLabel,
- markLineLabelSide,
- grid,
- yAxisOptions,
- showXAxisLine,
- xAxisLineColor,
- }: {
- animateBars: boolean;
- height: number;
- markLineLabelSide: 'right' | 'left';
- showXAxisLine: boolean;
- xAxisLineColor: string;
- grid?: GridComponentOption;
- hideDelay?: number;
- labelYAxisExtents?: boolean;
- showMarkLineLabel?: boolean;
- tooltipFormatter?: (value: number) => string;
- yAxisOptions?: BarChartProps['yAxis'];
- }): Omit<BarChartProps, 'series' | 'barOpacity'> {
- return {
- tooltip: {
- trigger: 'axis',
- hideDelay,
- valueFormatter: tooltipFormatter
- ? (value: number) => tooltipFormatter(value)
- : undefined,
- },
- yAxis: {
- max: getYAxisMaxFn(height),
- splitLine: {
- show: false,
- },
- ...yAxisOptions,
- },
- grid: grid ?? {
-
-
- top: labelYAxisExtents || showMarkLineLabel ? 6 : 0,
- bottom: labelYAxisExtents || showMarkLineLabel ? 4 : 0,
- left: markLineLabelSide === 'left' ? (showMarkLineLabel ? 35 : 4) : 0,
- right: markLineLabelSide === 'right' ? (showMarkLineLabel ? 25 : 4) : 0,
- },
- xAxis: {
- axisLine: showXAxisLine
- ? {
- show: true,
- lineStyle: {
- color: xAxisLineColor,
- },
- onZero: false,
- }
- : {show: false},
- axisTick: {
- show: false,
- alignWithLabel: true,
- },
- offset: showXAxisLine ? -1 : 0,
- axisLabel: {
- show: false,
- },
- axisPointer: {
- type: 'line' as const,
- label: {
- show: false,
- },
- lineStyle: {
- width: 0,
- },
- },
- },
- options: animateBars
- ? {
- animation: true,
- animationEasing: 'circularOut',
- }
- : {
- animation: false,
- },
- };
- }
- function makeLabelYAxisOptions(tooltipFormatter: Props['tooltipFormatter']) {
- return {
- showMinLabel: true,
- showMaxLabel: true,
- interval: Infinity,
- axisLabel: {
- formatter(value: number) {
- if (tooltipFormatter) {
- return tooltipFormatter(value);
- }
- return formatAbbreviatedNumber(value);
- },
- },
- };
- }
- const noLabelYAxisOptions = {
- axisLabel: {
- show: false,
- },
- };
- interface Props extends Omit<BaseChartProps, 'css' | 'colors' | 'series' | 'height'> {
-
- height: number;
-
- animateBars?: boolean;
-
- barOpacity?: number;
-
- colors?: string[];
-
- emphasisColors?: string[];
-
- grid?: GridComponentOption;
-
- hideDelay?: number;
-
- hideZeros?: boolean;
-
- labelYAxisExtents?: boolean;
-
- markLineLabelSide?: 'right' | 'left';
-
- series?: BarChartProps['series'];
-
- showMarkLineLabel?: boolean;
-
- showXAxisLine?: boolean;
-
- stacked?: boolean;
-
- tooltipFormatter?: (value: number) => string;
-
- utc?: boolean;
- }
- export function getYAxisMaxFn(height: number) {
- return (value: {max: number; min: number}) => {
-
-
- if (value.max < 10) {
- return 10;
- }
-
-
- return (value.max * (height + 10)) / height;
- };
- }
- function MiniBarChart({
- animateBars = false,
- barOpacity = 0.6,
- emphasisColors,
- series,
- hideDelay,
- hideZeros = false,
- tooltipFormatter,
- colors,
- stacked = false,
- labelYAxisExtents = false,
- showMarkLineLabel = false,
- markLineLabelSide = 'left',
- showXAxisLine = false,
- height,
- grid,
- ...props
- }: Props) {
- const theme = useTheme();
- const xAxisLineColor: string = theme.gray200;
- const updatedSeries: BarChartSeries[] = useMemo(() => {
- if (!series?.length) {
- return [];
- }
- const chartSeries: BarChartSeries[] = [];
- const colorList = Array.isArray(colors)
- ? colors
- : [theme.gray200, theme.purple300, theme.purple300];
- for (let i = 0; i < series.length; i++) {
- const original = series[i];
- const updated: BarChartSeries = {
- ...original,
- cursor: 'normal',
- type: 'bar',
- };
- if (i === 0) {
- updated.barMinHeight = 1;
- if (stacked === false) {
- updated.barGap = '-100%';
- }
- }
- if (stacked) {
- updated.stack = 'stack1';
- }
- set(updated, 'itemStyle.color', colorList[i]);
- set(updated, 'itemStyle.borderRadius', [1, 1, 0, 0]);
- set(updated, 'emphasis.itemStyle.color', emphasisColors?.[i] ?? colorList[i]);
- chartSeries.push(updated);
- }
- return chartSeries;
- }, [series, emphasisColors, stacked, colors, theme.gray200, theme.purple300]);
- const chartOptions = useMemo(() => {
- const yAxisOptions = labelYAxisExtents
- ? makeLabelYAxisOptions(tooltipFormatter)
- : noLabelYAxisOptions;
- const options = makeBaseChartOptions({
- animateBars,
- height,
- hideDelay,
- tooltipFormatter,
- labelYAxisExtents,
- showMarkLineLabel,
- markLineLabelSide,
- grid,
- yAxisOptions,
- showXAxisLine,
- xAxisLineColor,
- });
- return options;
- }, [
- animateBars,
- grid,
- height,
- hideDelay,
- labelYAxisExtents,
- markLineLabelSide,
- showMarkLineLabel,
- showXAxisLine,
- tooltipFormatter,
- xAxisLineColor,
- ]);
- return (
- <BarChart
- barOpacity={barOpacity}
- hideZeros={hideZeros}
- series={updatedSeries}
- height={height}
- {...chartOptions}
- {...props}
- />
- );
- }
- export default MiniBarChart;
|