ColumnChart.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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 ColumnType = 'group' | 'stack';
  8. /**
  9. * 柱状图组件的 Props 接口
  10. */
  11. export interface ColumnChartProps extends Omit<BaseChartProps, 'type'> {
  12. /** 是否显示数据标签 */
  13. dataLabel?: boolean;
  14. /** 柱状图类型 */
  15. columnType?: ColumnType;
  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. * ColumnChart 柱状图组件
  33. *
  34. * 用于显示分类数据的柱状图,支持分组和堆叠模式
  35. */
  36. export const ColumnChart: React.FC<ColumnChartProps> = (props) => {
  37. const {
  38. dataLabel = true,
  39. columnType = 'group',
  40. xAxis,
  41. yAxis,
  42. legend = true,
  43. fontSize = 11,
  44. background = '#FFFFFF',
  45. animation = true,
  46. tooltipFormatter,
  47. categories = [],
  48. series = [],
  49. config = {},
  50. ...baseProps
  51. } = props;
  52. const chartRef = React.useRef<any>(null);
  53. /**
  54. * 默认配置
  55. */
  56. const defaultConfig = useMemo(() => {
  57. const legendConfig: LegendConfig = legend ? { show: true } : { show: false };
  58. const result = {
  59. legend: legendConfig,
  60. fontSize,
  61. background,
  62. animation,
  63. dataLabel,
  64. xAxis: xAxis ?? { disableGrid: true },
  65. yAxis: yAxis ?? {},
  66. extra: {
  67. column: {
  68. type: columnType,
  69. width: columnType === 'group'
  70. ? (baseProps.width ? baseProps.width * 0.45 / (categories.length || 1) : 20)
  71. : undefined
  72. }
  73. }
  74. };
  75. return result
  76. }, [legend, fontSize, background, animation, dataLabel, xAxis, yAxis, columnType, categories.length, baseProps.width]);
  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. const finalConfig = { ...defaultConfig, ...config }
  95. return (
  96. <BaseChart
  97. {...baseProps}
  98. categories={categories}
  99. series={series}
  100. type="column"
  101. config={finalConfig}
  102. onTouchStart={handleTouchStart}
  103. />
  104. );
  105. };
  106. export default ColumnChart;