@@ -10,25 +10,45 @@ type ChartKind =
1010 | "donut"
1111 | "progress"
1212 | "heatmap"
13+ | "radar"
14+ | "combined"
15+ | "candlestick"
1316 | "more" ;
1417
1518type ChartType = {
19+ docsHref ?: string ;
1620 kind : ChartKind ;
21+ pro ?: boolean ;
1722 title : string ;
1823 subtitle ?: string ;
1924} ;
2025
2126type ThemeMode = "dark" | "light" ;
2227
2328const chartTypes : ChartType [ ] = [
24- { kind : "line" , title : "Line Chart" } ,
25- { kind : "area" , title : "Area Chart" } ,
26- { kind : "bar" , title : "Bar Chart" } ,
27- { kind : "stackedBar" , title : "Stacked Bar Chart" } ,
28- { kind : "pie" , title : "Pie Chart" } ,
29- { kind : "donut" , title : "Donut Chart" } ,
30- { kind : "progress" , title : "Progress Circle" } ,
31- { kind : "heatmap" , title : "Contribution Heatmap" } ,
29+ { docsHref : "/docs/charts/line/" , kind : "line" , title : "Line Chart" } ,
30+ { docsHref : "/docs/charts/area/" , kind : "area" , title : "Area Chart" } ,
31+ { docsHref : "/docs/charts/bar/" , kind : "bar" , title : "Bar Chart" } ,
32+ {
33+ docsHref : "/docs/charts/bar/#stacked-bars" ,
34+ kind : "stackedBar" ,
35+ title : "Stacked Bar Chart"
36+ } ,
37+ { docsHref : "/docs/charts/pie/" , kind : "pie" , title : "Pie Chart" } ,
38+ { docsHref : "/docs/charts/donut/" , kind : "donut" , title : "Donut Chart" } ,
39+ {
40+ docsHref : "/docs/charts/progress/" ,
41+ kind : "progress" ,
42+ title : "Progress Circle"
43+ } ,
44+ {
45+ docsHref : "/docs/charts/contribution-heatmap/" ,
46+ kind : "heatmap" ,
47+ title : "Contribution Heatmap"
48+ } ,
49+ { kind : "radar" , pro : true , subtitle : "planned" , title : "Radar Chart" } ,
50+ { kind : "combined" , pro : true , title : "Combined Chart" } ,
51+ { kind : "candlestick" , pro : true , title : "Candlestick Chart" } ,
3252 { kind : "more" , title : "More charts" , subtitle : "coming soon" }
3353] ;
3454
@@ -167,6 +187,15 @@ const getThemeStyles = (mode: ThemeMode) => {
167187 label : {
168188 color : isLight ? "rgba(0, 0, 0, 0.68)" : "rgba(255, 255, 255, 0.72)"
169189 } ,
190+ pro : {
191+ backgroundColor : isLight
192+ ? "rgba(0, 0, 0, 0.045)"
193+ : "rgba(255, 255, 255, 0.075)" ,
194+ borderColor : isLight
195+ ? "rgba(0, 0, 0, 0.12)"
196+ : "rgba(255, 255, 255, 0.14)" ,
197+ color : isLight ? "rgba(0, 0, 0, 0.62)" : "rgba(255, 255, 255, 0.76)"
198+ } ,
170199 separator : {
171200 background : isLight
172201 ? "linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.09) 20%, rgba(0, 0, 0, 0.09) 80%, transparent)"
@@ -608,6 +637,175 @@ const ChartArtwork = ({
608637 </ g >
609638 </ SvgFrame >
610639 ) ;
640+ case "radar" :
641+ return (
642+ < SvgFrame label = { `${ title } illustration` } mode = { mode } >
643+ < g
644+ fill = "none"
645+ stroke = "currentColor"
646+ strokeLinejoin = "round"
647+ opacity = { lerp ( 0.24 , 0.3 , progress ) }
648+ >
649+ < path d = "M120 27L166 60L148 116H92L74 60Z" />
650+ < path d = "M120 45L148 65L137 99H103L92 65Z" opacity = "0.76" />
651+ < path d = "M120 75L120 27" />
652+ < path d = "M120 75L166 60" />
653+ < path d = "M120 75L148 116" />
654+ < path d = "M120 75L92 116" />
655+ < path d = "M120 75L74 60" />
656+ </ g >
657+ < MorphPath
658+ base = "M120 39L153 66L139 106L98 94L88 62Z"
659+ fill = "currentColor"
660+ hover = "M120 32L160 72L130 111L96 86L82 67Z"
661+ opacity = { 0.18 }
662+ progress = { progress }
663+ />
664+ < MorphPath
665+ base = "M120 39L153 66L139 106L98 94L88 62Z"
666+ fill = "none"
667+ hover = "M120 32L160 72L130 111L96 86L82 67Z"
668+ opacity = { 0.82 }
669+ progress = { progress }
670+ stroke = "currentColor"
671+ strokeLinejoin = "round"
672+ strokeWidth = "2.1"
673+ />
674+ { [
675+ [ 120 , 39 , 120 , 32 ] ,
676+ [ 153 , 66 , 160 , 72 ] ,
677+ [ 139 , 106 , 130 , 111 ] ,
678+ [ 98 , 94 , 96 , 86 ] ,
679+ [ 88 , 62 , 82 , 67 ]
680+ ] . map ( ( [ baseX , baseY , hoverX , hoverY ] , index ) => {
681+ const localProgress = staggerProgress ( progress , index , 0.04 ) ;
682+
683+ return (
684+ < circle
685+ key = { index }
686+ cx = { lerp ( baseX , hoverX , localProgress ) }
687+ cy = { lerp ( baseY , hoverY , localProgress ) }
688+ r = { lerp ( 3 , 3.3 , localProgress ) }
689+ fill = "currentColor"
690+ opacity = "0.9"
691+ />
692+ ) ;
693+ } ) }
694+ </ SvgFrame >
695+ ) ;
696+ case "combined" :
697+ return (
698+ < SvgFrame label = { `${ title } illustration` } mode = { mode } >
699+ < defs >
700+ < linearGradient
701+ id = { scopedId ( "chart-combined-fade" ) }
702+ x1 = "0"
703+ x2 = "0"
704+ y1 = "0"
705+ y2 = "1"
706+ >
707+ < stop stopColor = "currentColor" stopOpacity = "0.62" />
708+ < stop offset = "1" stopColor = "currentColor" stopOpacity = "0.06" />
709+ </ linearGradient >
710+ </ defs >
711+ < g opacity = "0.58" >
712+ { [ 46 , 72 , 54 , 86 , 68 ] . map ( ( baseHeight , index ) => {
713+ const localProgress = staggerProgress ( progress , index , 0.045 ) ;
714+ const height = lerp (
715+ baseHeight ,
716+ [ 68 , 52 , 74 , 62 , 94 ] [ index ] ,
717+ localProgress
718+ ) ;
719+
720+ return (
721+ < rect
722+ key = { index }
723+ x = { 52 + index * 30 }
724+ y = { 124 - height }
725+ width = "12"
726+ height = { height }
727+ rx = "1.5"
728+ fill = { `url(#${ scopedId ( "chart-combined-fade" ) } )` }
729+ />
730+ ) ;
731+ } ) }
732+ </ g >
733+ < MorphPath
734+ base = "M50 103C68 85 82 92 96 71C111 48 128 58 142 78C158 102 174 72 192 50"
735+ fill = "none"
736+ hover = "M50 94C68 78 82 82 96 91C111 105 128 49 142 56C158 64 174 82 192 40"
737+ progress = { progress }
738+ stroke = "currentColor"
739+ strokeLinecap = "round"
740+ strokeLinejoin = "round"
741+ strokeWidth = "2.5"
742+ />
743+ < circle
744+ cx = "142"
745+ cy = { lerp ( 78 , 56 , staggerProgress ( progress , 3 ) ) }
746+ r = { lerp ( 3.6 , 4.6 , progress ) }
747+ fill = "currentColor"
748+ />
749+ </ SvgFrame >
750+ ) ;
751+ case "candlestick" :
752+ return (
753+ < SvgFrame label = { `${ title } illustration` } mode = { mode } >
754+ < g
755+ stroke = "currentColor"
756+ strokeLinecap = "round"
757+ strokeWidth = "2"
758+ opacity = { lerp ( 0.55 , 0.38 , progress ) }
759+ >
760+ { [
761+ [ 52 , 48 , 116 , 60 , 120 ] ,
762+ [ 82 , 36 , 104 , 58 , 118 ] ,
763+ [ 112 , 56 , 126 , 42 , 116 ] ,
764+ [ 142 , 42 , 108 , 50 , 114 ] ,
765+ [ 172 , 60 , 118 , 48 , 108 ] ,
766+ [ 202 , 34 , 94 , 62 , 112 ]
767+ ] . map ( ( [ x , y1 , y2 , activeY1 , activeY2 ] , index ) => {
768+ const localProgress = staggerProgress ( progress , index , 0.035 ) ;
769+
770+ return (
771+ < path
772+ d = { `M${ x } ${ formatSvgNumber ( lerp ( y1 , activeY1 , localProgress ) ) } V${ formatSvgNumber ( lerp ( y2 , activeY2 , localProgress ) ) } ` }
773+ key = { index }
774+ />
775+ ) ;
776+ } ) }
777+ </ g >
778+ < g fill = "currentColor" >
779+ { [
780+ [ 43 , 72 , 26 , 82 , 24 , 0.34 , 0.26 ] ,
781+ [ 73 , 52 , 38 , 64 , 30 , 0.9 , 0.74 ] ,
782+ [ 103 , 82 , 28 , 60 , 40 , 0.34 , 0.42 ] ,
783+ [ 133 , 58 , 32 , 42 , 48 , 0.9 , 0.95 ] ,
784+ [ 163 , 82 , 24 , 50 , 44 , 0.34 , 0.48 ] ,
785+ [ 193 , 48 , 30 , 70 , 28 , 0.9 , 0.62 ]
786+ ] . map (
787+ (
788+ [ x , y , height , activeY , activeHeight , opacity , activeOpacity ] ,
789+ index
790+ ) => {
791+ const localProgress = staggerProgress ( progress , index , 0.04 ) ;
792+
793+ return (
794+ < rect
795+ key = { index }
796+ x = { x }
797+ y = { lerp ( y , activeY , localProgress ) }
798+ width = "18"
799+ height = { lerp ( height , activeHeight , localProgress ) }
800+ rx = "1.5"
801+ opacity = { lerp ( opacity , activeOpacity , localProgress ) }
802+ />
803+ ) ;
804+ }
805+ ) }
806+ </ g >
807+ </ SvgFrame >
808+ ) ;
611809 case "more" :
612810 return (
613811 < SvgFrame label = { `${ title } illustration` } mode = { mode } >
@@ -701,13 +899,17 @@ const ChartTile = ({
701899 enterDuration ,
702900 exitDuration
703901 ) ;
902+ const tileClassName =
903+ "group relative block min-w-0 text-current no-underline outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-4px] focus-visible:outline-white/45 [html[data-theme='light']_&]:focus-visible:outline-black/40" ;
904+ const tileEvents = {
905+ onBlur : ( ) => setActive ( false ) ,
906+ onFocus : ( ) => setActive ( true ) ,
907+ onPointerEnter : ( ) => setActive ( true ) ,
908+ onPointerLeave : ( ) => setActive ( false )
909+ } ;
704910
705- return (
706- < article
707- className = "group relative min-w-0"
708- onPointerEnter = { ( ) => setActive ( true ) }
709- onPointerLeave = { ( ) => setActive ( false ) }
710- >
911+ const content = (
912+ < >
711913 { index % 2 === 0 && index < chartTypes . length - 1 && (
712914 < span
713915 aria-hidden = "true"
@@ -739,6 +941,14 @@ const ChartTile = ({
739941
740942 < div className = "px-5 py-9 sm:px-8 sm:py-11 lg:px-10 lg:py-12" >
741943 < div className = "relative mx-auto h-24 max-w-[168px] text-current sm:h-28 sm:max-w-[188px]" >
944+ { chart . pro && (
945+ < span
946+ className = "absolute -top-4 right-3 z-10 inline-flex h-[17px] min-w-[34px] items-center justify-center rounded-full border px-[6px] text-[8.5px] font-bold leading-none tracking-[0.12em] uppercase transition-colors duration-300"
947+ style = { theme . pro }
948+ >
949+ Pro
950+ </ span >
951+ ) }
742952 < ChartIllustration
743953 kind = { chart . kind }
744954 mode = { mode }
@@ -761,7 +971,26 @@ const ChartTile = ({
761971 </ p >
762972 ) }
763973 </ div >
764- </ article >
974+ </ >
975+ ) ;
976+
977+ if ( ! chart . docsHref ) {
978+ return (
979+ < article className = { tileClassName } { ...tileEvents } >
980+ { content }
981+ </ article >
982+ ) ;
983+ }
984+
985+ return (
986+ < a
987+ aria-label = { `${ chart . title } docs` }
988+ className = { tileClassName }
989+ href = { chart . docsHref }
990+ { ...tileEvents }
991+ >
992+ { content }
993+ </ a >
765994 ) ;
766995} ;
767996
@@ -811,7 +1040,7 @@ export default function ChartsSupported() {
8111040
8121041 < div className = "mt-7 flex justify-center" >
8131042 < a
814- href = "/docs/charts/line-and-area "
1043+ href = "/docs/charts/line"
8151044 className = "inline-flex h-10 items-center justify-center rounded-full border border-white/15 px-5 text-sm font-semibold tracking-[-0.01em] text-white/78 transition-colors hover:border-white/28 hover:text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-white/45 [html[data-theme='light']_&]:border-black/15 [html[data-theme='light']_&]:text-black/70 [html[data-theme='light']_&]:hover:border-black/28 [html[data-theme='light']_&]:hover:text-black [html[data-theme='light']_&]:focus-visible:outline-black/40"
8161045 >
8171046 Read docs
0 commit comments