BarChart.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import React, { useMemo } from 'react';
  2. import { BaseChart, BaseChartProps } from './BaseChart';
  3. import type { TouchEvent, LegendConfig, XAxisConfig, YAxisConfig } from '../lib/charts/index';
  4. /**
  5. * 条形图类型(横向柱状图)
  6. */
  7. export type BarType = 'group' | 'stack';
  8. /**
  9. * BarChart 组件的 Props 接口
  10. */
  11. export interface BarChartProps extends Omit<BaseChartProps, 'type'> {
  12. /** 是否显示数据标签 */
  13. dataLabel?: boolean;
  14. /** 条形图类型 */
  15. barType?: BarType;
  16. /** X 轴配置 */
  17. xAxis?: XAxisConfig;
  18. /** Y 轴配置 */
  19. yAxis?: YAxisConfig;
  20. /** 图例是否显示 */
  21. legend?: boolean;
  22. /** 字体大小 */
  23. fontSize?: number;
  24. /** 背景颜色 */
  25. background?: string;
  26. /** 是否开启动画 */
  27. animation?: boolean;
  28. /** tooltip 格式化函数 */
  29. tooltipFormatter?: (item: any, category: string) => string;
  30. }
  31. /**
  32. * BarChart 横向柱状图组件
  33. *
  34. * 用于显示分类数据的横向柱状图,支持分组和堆叠模式
  35. * 与 ColumnChart 的区别在于坐标轴交换,类别在 Y 轴,数值在 X 轴
  36. */
  37. export const BarChart: React.FC<BarChartProps> = (props) => {
  38. const {
  39. dataLabel = true,
  40. barType = 'group',
  41. xAxis,
  42. yAxis,
  43. legend = true,
  44. fontSize = 11,
  45. background = '#FFFFFF',
  46. animation = true,
  47. tooltipFormatter,
  48. categories = [],
  49. series = [],
  50. config = {},
  51. ...baseProps
  52. } = props;
  53. const chartRef = React.useRef<any>(null);
  54. /**
  55. * 默认配置
  56. */
  57. const defaultConfig = useMemo(() => {
  58. const legendConfig: LegendConfig = legend ? { show: true } : { show: false };
  59. return {
  60. legend: legendConfig,
  61. fontSize,
  62. background,
  63. animation,
  64. dataLabel,
  65. xAxis: xAxis ?? { disableGrid: true },
  66. yAxis: yAxis ?? {},
  67. extra: {
  68. bar: {
  69. type: barType,
  70. width: barType === 'group'
  71. ? (baseProps.height ? baseProps.height * 0.45 / (categories.length || 1) : 20)
  72. : undefined
  73. }
  74. }
  75. };
  76. }, [legend, fontSize, background, animation, dataLabel, xAxis, yAxis, barType, categories.length, baseProps.height]);
  77. /**
  78. * tooltip 事件处理
  79. */
  80. const handleTouchStart = (e: TouchEvent) => {
  81. if (chartRef.current && tooltipFormatter) {
  82. chartRef.current.showToolTip(e, {
  83. formatter: tooltipFormatter
  84. });
  85. } else if (chartRef.current) {
  86. chartRef.current.showToolTip(e, {
  87. formatter: (item: any, category: string) => {
  88. return category + ' ' + item.name + ':' + item.data;
  89. }
  90. });
  91. }
  92. baseProps.onTouchStart?.(e);
  93. };
  94. return (
  95. <BaseChart
  96. {...baseProps}
  97. categories={categories}
  98. series={series}
  99. type="bar"
  100. config={{ ...defaultConfig, ...config }}
  101. onTouchStart={handleTouchStart}
  102. />
  103. );
  104. };
  105. export default BarChart;