chart.tsx 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. 'use client';
  2. import { type ComponentRenderProps } from '@json-render/react';
  3. import { useData } from '@json-render/react';
  4. import { getByPath } from '@json-render/core';
  5. export function Chart({ element }: ComponentRenderProps) {
  6. const { title, dataPath } = element.props as { title?: string | null; dataPath: string };
  7. const { data } = useData();
  8. const chartData = getByPath(data, dataPath) as Array<{ label: string; value: number }> | undefined;
  9. if (!chartData || !Array.isArray(chartData)) {
  10. return <div style={{ padding: 20, color: 'var(--muted)' }}>No data</div>;
  11. }
  12. const maxValue = Math.max(...chartData.map((d) => d.value));
  13. return (
  14. <div>
  15. {title && <h4 style={{ margin: '0 0 16px', fontSize: 14, fontWeight: 600 }}>{title}</h4>}
  16. <div style={{ display: 'flex', gap: 8, alignItems: 'flex-end', height: 120 }}>
  17. {chartData.map((d, i) => (
  18. <div key={i} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4 }}>
  19. <div
  20. style={{
  21. width: '100%',
  22. height: `${(d.value / maxValue) * 100}%`,
  23. background: 'var(--foreground)',
  24. borderRadius: '4px 4px 0 0',
  25. minHeight: 4,
  26. }}
  27. />
  28. <span style={{ fontSize: 12, color: 'var(--muted)' }}>{d.label}</span>
  29. </div>
  30. ))}
  31. </div>
  32. </div>
  33. );
  34. }