@coinbase/cds-mcp-server 8.48.0 → 8.48.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/mcp-docs/mobile/components/AreaChart.txt +475 -2
- package/mcp-docs/mobile/components/BarChart.txt +633 -3
- package/mcp-docs/mobile/components/CartesianChart.txt +250 -2
- package/mcp-docs/mobile/components/LineChart.txt +15 -15
- package/mcp-docs/mobile/components/Link.txt +98 -36
- package/mcp-docs/mobile/components/Point.txt +3 -2
- package/mcp-docs/mobile/components/Scrubber.txt +2 -1
- package/mcp-docs/mobile/components/SparklineGradient.txt +1 -1
- package/mcp-docs/mobile/routes.txt +9 -9
- package/mcp-docs/web/components/AreaChart.txt +9 -6
- package/mcp-docs/web/components/BarChart.txt +427 -135
- package/mcp-docs/web/components/CartesianChart.txt +251 -2
- package/mcp-docs/web/components/LineChart.txt +15 -14
- package/mcp-docs/web/components/Link.txt +112 -25
- package/mcp-docs/web/components/Point.txt +3 -2
- package/mcp-docs/web/components/ReferenceLine.txt +3 -2
- package/mcp-docs/web/components/Scrubber.txt +3 -2
- package/mcp-docs/web/components/SparklineGradient.txt +1 -1
- package/mcp-docs/web/routes.txt +15 -15
- package/package.json +1 -1
|
@@ -364,7 +364,9 @@ You can also round the baseline of the bars by setting the `roundBaseline` prop
|
|
|
364
364
|
/>
|
|
365
365
|
```
|
|
366
366
|
|
|
367
|
-
###
|
|
367
|
+
### Data
|
|
368
|
+
|
|
369
|
+
#### Negative
|
|
368
370
|
|
|
369
371
|
```jsx live
|
|
370
372
|
function PositiveAndNegativeCashFlow() {
|
|
@@ -404,7 +406,7 @@ function PositiveAndNegativeCashFlow() {
|
|
|
404
406
|
}
|
|
405
407
|
```
|
|
406
408
|
|
|
407
|
-
|
|
409
|
+
#### Null
|
|
408
410
|
|
|
409
411
|
You can pass in `null` or `0` values to not render a bar for that data point.
|
|
410
412
|
|
|
@@ -502,6 +504,40 @@ function MonthlyRewards() {
|
|
|
502
504
|
}
|
|
503
505
|
```
|
|
504
506
|
|
|
507
|
+
#### Range
|
|
508
|
+
|
|
509
|
+
You can pass in `[min, max]` tuples as data points to render bars that span a range of values.
|
|
510
|
+
|
|
511
|
+
```jsx live
|
|
512
|
+
function PriceRange() {
|
|
513
|
+
const candles = btcCandles.slice(0, 180).reverse();
|
|
514
|
+
const data = candles.map((candle) => [parseFloat(candle.low), parseFloat(candle.high)]);
|
|
515
|
+
|
|
516
|
+
const min = Math.min(...data.map(([low]) => low));
|
|
517
|
+
const max = Math.max(...data.map(([, high]) => high));
|
|
518
|
+
|
|
519
|
+
const tickFormatter = useCallback(
|
|
520
|
+
(value) =>
|
|
521
|
+
new Intl.NumberFormat('en-US', {
|
|
522
|
+
style: 'currency',
|
|
523
|
+
currency: 'USD',
|
|
524
|
+
notation: 'compact',
|
|
525
|
+
maximumFractionDigits: 0,
|
|
526
|
+
}).format(value),
|
|
527
|
+
[],
|
|
528
|
+
);
|
|
529
|
+
|
|
530
|
+
return (
|
|
531
|
+
<BarChart
|
|
532
|
+
series={[{ id: 'prices', data, color: assets.btc.color }]}
|
|
533
|
+
showYAxis
|
|
534
|
+
yAxis={{ domain: { min, max }, showGrid: true, tickLabelFormatter: tickFormatter }}
|
|
535
|
+
height={250}
|
|
536
|
+
/>
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
```
|
|
540
|
+
|
|
505
541
|
### Customization
|
|
506
542
|
|
|
507
543
|
#### Bar Spacing
|
|
@@ -670,9 +706,288 @@ You can render bars from separate y axes in one `BarPlot`, however they aren't a
|
|
|
670
706
|
|
|
671
707
|
#### Custom Components
|
|
672
708
|
|
|
673
|
-
#####
|
|
709
|
+
##### Outlined Stacks
|
|
710
|
+
|
|
711
|
+
You can set the `BarStackComponent` prop to render a custom component for stacks.
|
|
712
|
+
|
|
713
|
+
```jsx live
|
|
714
|
+
function MonthlyRewards() {
|
|
715
|
+
const CustomBarStackComponent = ({ children, ...props }) => {
|
|
716
|
+
return (
|
|
717
|
+
<>
|
|
718
|
+
<Bar
|
|
719
|
+
roundBottom
|
|
720
|
+
roundTop
|
|
721
|
+
borderRadius={1000}
|
|
722
|
+
stroke="var(--color-fg)"
|
|
723
|
+
strokeWidth={4}
|
|
724
|
+
height={props.height}
|
|
725
|
+
width={props.width}
|
|
726
|
+
x={props.x}
|
|
727
|
+
y={props.y}
|
|
728
|
+
clip
|
|
729
|
+
/>
|
|
730
|
+
<DefaultBarStack {...props}>{children}</DefaultBarStack>
|
|
731
|
+
</>
|
|
732
|
+
);
|
|
733
|
+
};
|
|
734
|
+
|
|
735
|
+
return (
|
|
736
|
+
<BarChart
|
|
737
|
+
roundBaseline
|
|
738
|
+
stacked
|
|
739
|
+
BarStackComponent={CustomBarStackComponent}
|
|
740
|
+
borderRadius={1000}
|
|
741
|
+
height={300}
|
|
742
|
+
maxWidth={400}
|
|
743
|
+
padding={0}
|
|
744
|
+
series={[
|
|
745
|
+
{ id: 'purple', data: [null, 6, 8, 10, 7, 6, 6, 8, 9, 12, 10, 4], color: '#b399ff' },
|
|
746
|
+
{ id: 'blue', data: [null, 10, 12, 11, 10, 9, 10, 11, 7, 4, 12, 18], color: '#4f7cff' },
|
|
747
|
+
{ id: 'cyan', data: [null, 7, 10, 12, 11, 10, 8, 11, 5, 12, 2, 9], color: '#00c2df' },
|
|
748
|
+
{
|
|
749
|
+
id: 'green',
|
|
750
|
+
data: [10, null, null, null, 1, null, null, 6, null, null, null, null],
|
|
751
|
+
color: '#33c481',
|
|
752
|
+
},
|
|
753
|
+
]}
|
|
754
|
+
showXAxis
|
|
755
|
+
xAxis={{
|
|
756
|
+
data: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'],
|
|
757
|
+
tickLabelFormatter: (value) => {
|
|
758
|
+
if (value === 'D') {
|
|
759
|
+
return <tspan style={{ fontWeight: 'bold' }}>{value}</tspan>;
|
|
760
|
+
}
|
|
761
|
+
return value;
|
|
762
|
+
},
|
|
763
|
+
}}
|
|
764
|
+
yAxis={{ range: ({ min, max }) => ({ min, max: max - 4 }) }}
|
|
765
|
+
style={{ margin: '0 auto' }}
|
|
766
|
+
/>
|
|
767
|
+
);
|
|
768
|
+
}
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
### Animations
|
|
772
|
+
|
|
773
|
+
You can configure chart transitions using the `transitions` prop.
|
|
774
|
+
|
|
775
|
+
#### Customized Transitions
|
|
776
|
+
|
|
777
|
+
You can pass in a custom spring based transition to your `BarChart` for a custom update transition.
|
|
778
|
+
|
|
779
|
+
```jsx live
|
|
780
|
+
function AnimatedStackedBars() {
|
|
781
|
+
const dataCount = 12;
|
|
782
|
+
const minValue = 20;
|
|
783
|
+
const maxValue = 100;
|
|
784
|
+
const minStep = 10;
|
|
785
|
+
const maxStep = 40;
|
|
786
|
+
const updateInterval = 600;
|
|
787
|
+
const seriesSpacing = 30;
|
|
788
|
+
|
|
789
|
+
const seriesConfig = [
|
|
790
|
+
{ id: 'red', label: 'Red', color: 'rgb(var(--red40))' },
|
|
791
|
+
{ id: 'orange', label: 'Orange', color: 'rgb(var(--orange40))' },
|
|
792
|
+
{ id: 'yellow', label: 'Yellow', color: 'rgb(var(--yellow40))' },
|
|
793
|
+
{ id: 'green', label: 'Green', color: 'rgb(var(--green40))' },
|
|
794
|
+
{ id: 'blue', label: 'Blue', color: 'rgb(var(--blue40))' },
|
|
795
|
+
{ id: 'indigo', label: 'Indigo', color: 'rgb(var(--indigo40))' },
|
|
796
|
+
{ id: 'purple', label: 'Purple', color: 'rgb(var(--purple40))' },
|
|
797
|
+
];
|
|
798
|
+
|
|
799
|
+
const domainLimit = maxValue + seriesConfig.length * seriesSpacing;
|
|
800
|
+
|
|
801
|
+
function generateNextValue(previousValue) {
|
|
802
|
+
const range = maxStep - minStep;
|
|
803
|
+
const offset = Math.random() * range + minStep;
|
|
804
|
+
|
|
805
|
+
let direction;
|
|
806
|
+
if (previousValue >= maxValue) {
|
|
807
|
+
direction = -1;
|
|
808
|
+
} else if (previousValue <= minValue) {
|
|
809
|
+
direction = 1;
|
|
810
|
+
} else {
|
|
811
|
+
direction = Math.random() < 0.5 ? -1 : 1;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
let newValue = previousValue + offset * direction;
|
|
815
|
+
newValue = Math.max(minValue, Math.min(maxValue, newValue));
|
|
816
|
+
return newValue;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
function generateInitialData() {
|
|
820
|
+
const data = [];
|
|
821
|
+
|
|
822
|
+
let previousValue = minValue + Math.random() * (maxValue - minValue);
|
|
823
|
+
data.push(previousValue);
|
|
824
|
+
|
|
825
|
+
for (let i = 1; i < dataCount; i++) {
|
|
826
|
+
const newValue = generateNextValue(previousValue);
|
|
827
|
+
data.push(newValue);
|
|
828
|
+
previousValue = newValue;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
return data;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
function AnimatedChart() {
|
|
835
|
+
const [data, setData] = useState(generateInitialData);
|
|
836
|
+
|
|
837
|
+
useEffect(() => {
|
|
838
|
+
const intervalId = setInterval(() => {
|
|
839
|
+
setData((currentData) => {
|
|
840
|
+
const lastValue = currentData[currentData.length - 1] ?? minValue;
|
|
841
|
+
const newValue = generateNextValue(lastValue);
|
|
842
|
+
|
|
843
|
+
return [...currentData.slice(1), newValue];
|
|
844
|
+
});
|
|
845
|
+
}, updateInterval);
|
|
846
|
+
|
|
847
|
+
return () => clearInterval(intervalId);
|
|
848
|
+
}, []);
|
|
849
|
+
|
|
850
|
+
const series = seriesConfig.map((config, index) => ({
|
|
851
|
+
id: config.id,
|
|
852
|
+
label: config.label,
|
|
853
|
+
color: config.color,
|
|
854
|
+
data: index === 0 ? data : Array(dataCount).fill(seriesSpacing),
|
|
855
|
+
}));
|
|
856
|
+
|
|
857
|
+
return (
|
|
858
|
+
<BarChart
|
|
859
|
+
stacked
|
|
860
|
+
height={{ base: 200, tablet: 250, desktop: 300 }}
|
|
861
|
+
series={series}
|
|
862
|
+
transitions={{
|
|
863
|
+
enter: { type: 'spring', stiffness: 700, damping: 80 },
|
|
864
|
+
update: { type: 'spring', stiffness: 700, damping: 20 },
|
|
865
|
+
}}
|
|
866
|
+
inset={0}
|
|
867
|
+
showYAxis
|
|
868
|
+
yAxis={{
|
|
869
|
+
showGrid: true,
|
|
870
|
+
width: 0,
|
|
871
|
+
tickLabelFormatter: () => '',
|
|
872
|
+
domain: { min: 0, max: domainLimit },
|
|
873
|
+
}}
|
|
874
|
+
/>
|
|
875
|
+
);
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
return <AnimatedChart />;
|
|
879
|
+
}
|
|
880
|
+
```
|
|
881
|
+
|
|
882
|
+
#### Disable Animations
|
|
883
|
+
|
|
884
|
+
You can also disable animations by setting the `animate` prop to `false`.
|
|
885
|
+
|
|
886
|
+
```jsx live
|
|
887
|
+
function AnimatedStackedBars() {
|
|
888
|
+
const dataCount = 12;
|
|
889
|
+
const minValue = 20;
|
|
890
|
+
const maxValue = 100;
|
|
891
|
+
const minStep = 10;
|
|
892
|
+
const maxStep = 40;
|
|
893
|
+
const updateInterval = 600;
|
|
894
|
+
const seriesSpacing = 30;
|
|
895
|
+
|
|
896
|
+
const seriesConfig = [
|
|
897
|
+
{ id: 'red', label: 'Red', color: 'rgb(var(--red40))' },
|
|
898
|
+
{ id: 'orange', label: 'Orange', color: 'rgb(var(--orange40))' },
|
|
899
|
+
{ id: 'yellow', label: 'Yellow', color: 'rgb(var(--yellow40))' },
|
|
900
|
+
{ id: 'green', label: 'Green', color: 'rgb(var(--green40))' },
|
|
901
|
+
{ id: 'blue', label: 'Blue', color: 'rgb(var(--blue40))' },
|
|
902
|
+
{ id: 'indigo', label: 'Indigo', color: 'rgb(var(--indigo40))' },
|
|
903
|
+
{ id: 'purple', label: 'Purple', color: 'rgb(var(--purple40))' },
|
|
904
|
+
];
|
|
905
|
+
|
|
906
|
+
const domainLimit = maxValue + seriesConfig.length * seriesSpacing;
|
|
907
|
+
|
|
908
|
+
function generateNextValue(previousValue) {
|
|
909
|
+
const range = maxStep - minStep;
|
|
910
|
+
const offset = Math.random() * range + minStep;
|
|
911
|
+
|
|
912
|
+
let direction;
|
|
913
|
+
if (previousValue >= maxValue) {
|
|
914
|
+
direction = -1;
|
|
915
|
+
} else if (previousValue <= minValue) {
|
|
916
|
+
direction = 1;
|
|
917
|
+
} else {
|
|
918
|
+
direction = Math.random() < 0.5 ? -1 : 1;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
let newValue = previousValue + offset * direction;
|
|
922
|
+
newValue = Math.max(minValue, Math.min(maxValue, newValue));
|
|
923
|
+
return newValue;
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
function generateInitialData() {
|
|
927
|
+
const data = [];
|
|
928
|
+
|
|
929
|
+
let previousValue = minValue + Math.random() * (maxValue - minValue);
|
|
930
|
+
data.push(previousValue);
|
|
674
931
|
|
|
675
|
-
|
|
932
|
+
for (let i = 1; i < dataCount; i++) {
|
|
933
|
+
const newValue = generateNextValue(previousValue);
|
|
934
|
+
data.push(newValue);
|
|
935
|
+
previousValue = newValue;
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
return data;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
function AnimatedChart() {
|
|
942
|
+
const [data, setData] = useState(generateInitialData);
|
|
943
|
+
|
|
944
|
+
useEffect(() => {
|
|
945
|
+
const intervalId = setInterval(() => {
|
|
946
|
+
setData((currentData) => {
|
|
947
|
+
const lastValue = currentData[currentData.length - 1] ?? minValue;
|
|
948
|
+
const newValue = generateNextValue(lastValue);
|
|
949
|
+
|
|
950
|
+
return [...currentData.slice(1), newValue];
|
|
951
|
+
});
|
|
952
|
+
}, updateInterval);
|
|
953
|
+
|
|
954
|
+
return () => clearInterval(intervalId);
|
|
955
|
+
}, []);
|
|
956
|
+
|
|
957
|
+
const series = seriesConfig.map((config, index) => ({
|
|
958
|
+
id: config.id,
|
|
959
|
+
label: config.label,
|
|
960
|
+
color: config.color,
|
|
961
|
+
data: index === 0 ? data : Array(dataCount).fill(seriesSpacing),
|
|
962
|
+
}));
|
|
963
|
+
|
|
964
|
+
return (
|
|
965
|
+
<BarChart
|
|
966
|
+
animate={false}
|
|
967
|
+
stacked
|
|
968
|
+
height={{ base: 200, tablet: 250, desktop: 300 }}
|
|
969
|
+
series={series}
|
|
970
|
+
inset={0}
|
|
971
|
+
showYAxis
|
|
972
|
+
yAxis={{
|
|
973
|
+
showGrid: true,
|
|
974
|
+
width: 0,
|
|
975
|
+
tickLabelFormatter: () => '',
|
|
976
|
+
domain: { min: 0, max: domainLimit },
|
|
977
|
+
}}
|
|
978
|
+
/>
|
|
979
|
+
);
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
return <AnimatedChart />;
|
|
983
|
+
}
|
|
984
|
+
```
|
|
985
|
+
|
|
986
|
+
### Composed Examples
|
|
987
|
+
|
|
988
|
+
#### Candlesticks
|
|
989
|
+
|
|
990
|
+
You can render a candlestick chart by setting the `BarComponent` prop to a custom candlestick component.
|
|
676
991
|
|
|
677
992
|
```jsx live
|
|
678
993
|
function Candlesticks() {
|
|
@@ -710,10 +1025,26 @@ function Candlesticks() {
|
|
|
710
1025
|
|
|
711
1026
|
const candlesData = stockData.map((data) => [parseFloat(data.low), parseFloat(data.high)]);
|
|
712
1027
|
|
|
1028
|
+
const staggerDelay = 0.25;
|
|
1029
|
+
|
|
713
1030
|
const CandlestickBarComponent = memo(({ x, y, width, height, originY, dataX, ...props }) => {
|
|
714
|
-
const { getYScale } = useCartesianChartContext();
|
|
1031
|
+
const { getYScale, drawingArea } = useCartesianChartContext();
|
|
715
1032
|
const yScale = getYScale();
|
|
716
1033
|
|
|
1034
|
+
const normalizedX = React.useMemo(
|
|
1035
|
+
() => (drawingArea.width > 0 ? (x - drawingArea.x) / drawingArea.width : 0),
|
|
1036
|
+
[x, drawingArea.x, drawingArea.width],
|
|
1037
|
+
);
|
|
1038
|
+
|
|
1039
|
+
const transition = React.useMemo(
|
|
1040
|
+
() => ({
|
|
1041
|
+
type: 'tween',
|
|
1042
|
+
duration: 0.325,
|
|
1043
|
+
delay: normalizedX * staggerDelay,
|
|
1044
|
+
}),
|
|
1045
|
+
[normalizedX],
|
|
1046
|
+
);
|
|
1047
|
+
|
|
717
1048
|
const wickX = x + width / 2;
|
|
718
1049
|
|
|
719
1050
|
const timePeriodValue = stockData[dataX];
|
|
@@ -730,10 +1061,10 @@ function Candlesticks() {
|
|
|
730
1061
|
const bodyY = openY < closeY ? openY : closeY;
|
|
731
1062
|
|
|
732
1063
|
return (
|
|
733
|
-
<g>
|
|
1064
|
+
<m.g animate={{ opacity: 1, y: 0 }} initial={{ opacity: 0, y: 12 }} transition={transition}>
|
|
734
1065
|
<line stroke={color} strokeWidth={1} x1={wickX} x2={wickX} y1={y} y2={y + height} />
|
|
735
1066
|
<rect fill={color} height={bodyHeight} width={width} x={x} y={bodyY} />
|
|
736
|
-
</g>
|
|
1067
|
+
</m.g>
|
|
737
1068
|
);
|
|
738
1069
|
});
|
|
739
1070
|
|
|
@@ -807,7 +1138,6 @@ function Candlesticks() {
|
|
|
807
1138
|
showYAxis
|
|
808
1139
|
BarComponent={CandlestickBarComponent}
|
|
809
1140
|
BarStackComponent={({ children }) => <g>{children}</g>}
|
|
810
|
-
animate={false}
|
|
811
1141
|
borderRadius={0}
|
|
812
1142
|
height={{ base: 150, tablet: 200, desktop: 250 }}
|
|
813
1143
|
inset={{ top: 8, bottom: 8, left: 0, right: 0 }}
|
|
@@ -842,143 +1172,104 @@ function Candlesticks() {
|
|
|
842
1172
|
}
|
|
843
1173
|
```
|
|
844
1174
|
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
You can
|
|
1175
|
+
#### Monthly Sunlight
|
|
1176
|
+
|
|
1177
|
+
You can combine custom and BarPlot components and transitions to create a springy sunlight chart.
|
|
1178
|
+
|
|
1179
|
+
```tsx live
|
|
1180
|
+
function SunlightChartExample() {
|
|
1181
|
+
const dayLength = 1440;
|
|
1182
|
+
type SunlightChartData = Array<{
|
|
1183
|
+
label: string;
|
|
1184
|
+
value: number;
|
|
1185
|
+
}>;
|
|
1186
|
+
const sunlightData: SunlightChartData = [
|
|
1187
|
+
{ label: 'Jan', value: 598 },
|
|
1188
|
+
{ label: 'Feb', value: 635 },
|
|
1189
|
+
{ label: 'Mar', value: 688 },
|
|
1190
|
+
{ label: 'Apr', value: 753 },
|
|
1191
|
+
{ label: 'May', value: 812 },
|
|
1192
|
+
{ label: 'Jun', value: 855 },
|
|
1193
|
+
{ label: 'Jul', value: 861 },
|
|
1194
|
+
{ label: 'Aug', value: 828 },
|
|
1195
|
+
{ label: 'Sep', value: 772 },
|
|
1196
|
+
{ label: 'Oct', value: 710 },
|
|
1197
|
+
{ label: 'Nov', value: 648 },
|
|
1198
|
+
{ label: 'Dec', value: 605 },
|
|
1199
|
+
];
|
|
848
1200
|
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
1201
|
+
function SunlightChart({
|
|
1202
|
+
data,
|
|
1203
|
+
height = 300,
|
|
1204
|
+
...props
|
|
1205
|
+
}: Omit<CartesianChartProps, 'series' | 'children'> & { data: SunlightChartData }) {
|
|
852
1206
|
return (
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
roundTop
|
|
857
|
-
borderRadius={1000}
|
|
858
|
-
stroke="var(--color-fg)"
|
|
859
|
-
strokeWidth={4}
|
|
860
|
-
height={props.height}
|
|
861
|
-
width={props.width}
|
|
862
|
-
x={props.x}
|
|
863
|
-
y={props.y}
|
|
864
|
-
clip
|
|
865
|
-
/>
|
|
866
|
-
<DefaultBarStack {...props}>{children}</DefaultBarStack>
|
|
867
|
-
</>
|
|
868
|
-
);
|
|
869
|
-
};
|
|
870
|
-
|
|
871
|
-
return (
|
|
872
|
-
<BarChart
|
|
873
|
-
roundBaseline
|
|
874
|
-
stacked
|
|
875
|
-
BarStackComponent={CustomBarStackComponent}
|
|
876
|
-
borderRadius={1000}
|
|
877
|
-
height={300}
|
|
878
|
-
maxWidth={400}
|
|
879
|
-
padding={0}
|
|
880
|
-
series={[
|
|
881
|
-
{ id: 'purple', data: [null, 6, 8, 10, 7, 6, 6, 8, 9, 12, 10, 4], color: '#b399ff' },
|
|
882
|
-
{ id: 'blue', data: [null, 10, 12, 11, 10, 9, 10, 11, 7, 4, 12, 18], color: '#4f7cff' },
|
|
883
|
-
{ id: 'cyan', data: [null, 7, 10, 12, 11, 10, 8, 11, 5, 12, 2, 9], color: '#00c2df' },
|
|
884
|
-
{
|
|
885
|
-
id: 'green',
|
|
886
|
-
data: [10, null, null, null, 1, null, null, 6, null, null, null, null],
|
|
887
|
-
color: '#33c481',
|
|
888
|
-
},
|
|
889
|
-
]}
|
|
890
|
-
showXAxis
|
|
891
|
-
xAxis={{
|
|
892
|
-
data: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'],
|
|
893
|
-
tickLabelFormatter: (value) => {
|
|
894
|
-
if (value === 'D') {
|
|
895
|
-
return <tspan style={{ fontWeight: 'bold' }}>{value}</tspan>;
|
|
896
|
-
}
|
|
897
|
-
return value;
|
|
898
|
-
},
|
|
899
|
-
}}
|
|
900
|
-
yAxis={{ range: ({ min, max }) => ({ min, max: max - 4 }) }}
|
|
901
|
-
style={{ margin: '0 auto' }}
|
|
902
|
-
/>
|
|
903
|
-
);
|
|
904
|
-
}
|
|
905
|
-
```
|
|
906
|
-
|
|
907
|
-
### Custom Transitions
|
|
908
|
-
|
|
909
|
-
You can customize the transition animations for your bar chart using the `transition` prop.
|
|
910
|
-
This allows you to control enter, update, and exit animations separately.
|
|
911
|
-
|
|
912
|
-
```jsx live
|
|
913
|
-
function UpdatingChartValues() {
|
|
914
|
-
const [data, setData] = React.useState([45, 80, 120, 95, 150, 110, 85]);
|
|
915
|
-
const [nullIndex, setNullIndex] = React.useState(null);
|
|
916
|
-
|
|
917
|
-
const displayData = React.useMemo(() => {
|
|
918
|
-
if (nullIndex === null) return data;
|
|
919
|
-
return data.map((d, i) => (i === nullIndex ? null : d));
|
|
920
|
-
}, [data, nullIndex]);
|
|
921
|
-
|
|
922
|
-
return (
|
|
923
|
-
<VStack gap={2}>
|
|
924
|
-
<HStack gap={2}>
|
|
925
|
-
<Button
|
|
926
|
-
size="sm"
|
|
927
|
-
onClick={() =>
|
|
928
|
-
setData((prev) =>
|
|
929
|
-
prev[0] > 200 ? [45, 80, 120, 95, 150, 110, 85] : prev.map((d) => d + 25),
|
|
930
|
-
)
|
|
931
|
-
}
|
|
932
|
-
>
|
|
933
|
-
Update Data
|
|
934
|
-
</Button>
|
|
935
|
-
<Button size="sm" onClick={() => setNullIndex((prev) => (prev === null ? 3 : null))}>
|
|
936
|
-
{nullIndex === null ? 'Hide Bar' : 'Show Bar'}
|
|
937
|
-
</Button>
|
|
938
|
-
</HStack>
|
|
939
|
-
|
|
940
|
-
<Text font="label">Default Animations</Text>
|
|
941
|
-
<BarChart
|
|
942
|
-
height={150}
|
|
1207
|
+
<CartesianChart
|
|
1208
|
+
{...props}
|
|
1209
|
+
height={height}
|
|
943
1210
|
series={[
|
|
944
1211
|
{
|
|
945
|
-
id: '
|
|
946
|
-
data:
|
|
1212
|
+
id: 'sunlight',
|
|
1213
|
+
data: data.map(({ value }) => value),
|
|
1214
|
+
yAxisId: 'sunlight',
|
|
1215
|
+
color: 'rgb(var(--yellow40))',
|
|
1216
|
+
},
|
|
1217
|
+
{
|
|
1218
|
+
id: 'day',
|
|
1219
|
+
data: data.map(() => dayLength),
|
|
1220
|
+
yAxisId: 'day',
|
|
1221
|
+
color: 'rgb(var(--blue100))',
|
|
947
1222
|
},
|
|
948
1223
|
]}
|
|
949
|
-
showXAxis
|
|
950
|
-
showYAxis
|
|
951
1224
|
xAxis={{
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
showGrid: true,
|
|
956
|
-
domain: { max: 250 },
|
|
1225
|
+
...props.xAxis,
|
|
1226
|
+
scaleType: 'band',
|
|
1227
|
+
data: data.map(({ label }) => label),
|
|
957
1228
|
}}
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
1229
|
+
yAxis={[
|
|
1230
|
+
{
|
|
1231
|
+
id: 'day',
|
|
1232
|
+
domain: { min: 0, max: dayLength },
|
|
1233
|
+
domainLimit: 'strict',
|
|
1234
|
+
},
|
|
964
1235
|
{
|
|
965
|
-
id: '
|
|
966
|
-
|
|
1236
|
+
id: 'sunlight',
|
|
1237
|
+
domain: { min: 0, max: dayLength },
|
|
1238
|
+
domainLimit: 'strict',
|
|
967
1239
|
},
|
|
968
1240
|
]}
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
1241
|
+
>
|
|
1242
|
+
<YAxis axisId="day" showGrid showLine position="left" label="Minutes of sunlight" />
|
|
1243
|
+
<XAxis showLine />
|
|
1244
|
+
<BarPlot seriesIds={['day']} transitions={{ enter: null }} />
|
|
1245
|
+
<BarPlot
|
|
1246
|
+
borderRadius={0}
|
|
1247
|
+
seriesIds={['sunlight']}
|
|
1248
|
+
transitions={{ enter: { type: 'spring', stiffness: 700, damping: 40, staggerDelay: 1 } }}
|
|
1249
|
+
/>
|
|
1250
|
+
</CartesianChart>
|
|
1251
|
+
);
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
function Example() {
|
|
1255
|
+
return (
|
|
1256
|
+
<VStack gap={2}>
|
|
1257
|
+
<SunlightChart data={sunlightData} />
|
|
1258
|
+
<Text color="fgMuted" font="legal" textAlign="center">
|
|
1259
|
+
2026 sunlight data for the first day of each month in Atlanta, Georgia, provided by{' '}
|
|
1260
|
+
<Link
|
|
1261
|
+
href="https://gml.noaa.gov/grad/solcalc/table.php?lat=33.733&lon=-84.383&year=2026"
|
|
1262
|
+
target="_blank"
|
|
1263
|
+
>
|
|
1264
|
+
NOAA
|
|
1265
|
+
</Link>
|
|
1266
|
+
.
|
|
1267
|
+
</Text>
|
|
1268
|
+
</VStack>
|
|
1269
|
+
);
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
return <Example />;
|
|
982
1273
|
}
|
|
983
1274
|
```
|
|
984
1275
|
|
|
@@ -1102,7 +1393,8 @@ function UpdatingChartValues() {
|
|
|
1102
1393
|
| `textTransform` | `ResponsiveProp<none \| uppercase \| lowercase \| capitalize>` | No | `-` | - |
|
|
1103
1394
|
| `top` | `ResponsiveProp<Top<string \| number>>` | No | `-` | - |
|
|
1104
1395
|
| `transform` | `inherit \| none \| revert \| -moz-initial \| initial \| revert-layer \| unset` | No | `-` | - |
|
|
1105
|
-
| `transition` | `Orchestration & Repeat & Tween \| Orchestration & Repeat & Spring \| Orchestration & Repeat & Keyframes \| Orchestration & Repeat & Inertia \| Orchestration & Repeat & Just \| Orchestration & Repeat & None \| Orchestration & Repeat & PermissiveTransitionDefinition \| Orchestration & Repeat & Tween & { [key: string]: TransitionDefinition; } \| Orchestration & Repeat & Spring & { [key: string]: TransitionDefinition; } \| Orchestration & Repeat & Keyframes & { [key: string]: TransitionDefinition; } \| Orchestration & Repeat & Inertia & { [key: string]: TransitionDefinition; } \| Orchestration & Repeat & Just & { [key: string]: TransitionDefinition; } \| Orchestration & Repeat & None & { [key: string]: TransitionDefinition; } \| Orchestration & Repeat & PermissiveTransitionDefinition & { [key: string]: TransitionDefinition; }` | No | `-` | Transition
|
|
1396
|
+
| `transition` | `Orchestration & Repeat & Tween \| Orchestration & Repeat & Spring \| Orchestration & Repeat & Keyframes \| Orchestration & Repeat & Inertia \| Orchestration & Repeat & Just \| Orchestration & Repeat & None \| Orchestration & Repeat & PermissiveTransitionDefinition \| Orchestration & Repeat & Tween & { [key: string]: TransitionDefinition; } \| Orchestration & Repeat & Spring & { [key: string]: TransitionDefinition; } \| Orchestration & Repeat & Keyframes & { [key: string]: TransitionDefinition; } \| Orchestration & Repeat & Inertia & { [key: string]: TransitionDefinition; } \| Orchestration & Repeat & Just & { [key: string]: TransitionDefinition; } \| Orchestration & Repeat & None & { [key: string]: TransitionDefinition; } \| Orchestration & Repeat & PermissiveTransitionDefinition & { [key: string]: TransitionDefinition; }` | No | `-` | Transition for updates. |
|
|
1397
|
+
| `transitions` | `{ enter?: BarTransition \| null; update?: BarTransition \| null \| undefined; } \| undefined` | No | `transitions = {{ enter: { type: 'spring', stiffness: 900, damping: 120, mass: 4, staggerDelay: 0.25 }, update: { type: 'spring', stiffness: 900, damping: 120, mass: 4 } }}` | Transition configuration for enter and update animations. |
|
|
1106
1398
|
| `userSelect` | `ResponsiveProp<text \| none \| all \| auto>` | No | `-` | - |
|
|
1107
1399
|
| `visibility` | `ResponsiveProp<hidden \| visible>` | No | `-` | - |
|
|
1108
1400
|
| `width` | `ResponsiveProp<Width<string \| number>>` | No | `-` | - |
|