@tomaszjarosz/react-visualizers 0.2.13 → 0.2.14

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/dist/index.js CHANGED
@@ -1635,11 +1635,46 @@ const ALGORITHM_NAMES$1 = {
1635
1635
  merge: "MergeSort"
1636
1636
  };
1637
1637
  const ALGORITHM_COMPLEXITIES$1 = {
1638
- bubble: { time: "O(n²)", space: "O(1)" },
1639
- selection: { time: "O(n²)", space: "O(1)" },
1640
- insertion: { time: "O(n²)", space: "O(1)" },
1641
- quick: { time: "O(n log n)", space: "O(log n)" },
1642
- merge: { time: "O(n log n)", space: "O(n)" }
1638
+ bubble: {
1639
+ time: "O(n²)",
1640
+ best: "O(n)",
1641
+ average: "O(n²)",
1642
+ worst: "O(n²)",
1643
+ space: "O(1)",
1644
+ stable: true
1645
+ },
1646
+ selection: {
1647
+ time: "O(n²)",
1648
+ best: "O(n²)",
1649
+ average: "O(n²)",
1650
+ worst: "O(n²)",
1651
+ space: "O(1)",
1652
+ stable: false
1653
+ },
1654
+ insertion: {
1655
+ time: "O(n²)",
1656
+ best: "O(n)",
1657
+ average: "O(n²)",
1658
+ worst: "O(n²)",
1659
+ space: "O(1)",
1660
+ stable: true
1661
+ },
1662
+ quick: {
1663
+ time: "O(n log n)",
1664
+ best: "O(n log n)",
1665
+ average: "O(n log n)",
1666
+ worst: "O(n²)",
1667
+ space: "O(log n)",
1668
+ stable: false
1669
+ },
1670
+ merge: {
1671
+ time: "O(n log n)",
1672
+ best: "O(n log n)",
1673
+ average: "O(n log n)",
1674
+ worst: "O(n log n)",
1675
+ space: "O(n)",
1676
+ stable: true
1677
+ }
1643
1678
  };
1644
1679
  const ALGORITHM_CODE$1 = {
1645
1680
  bubble: [
@@ -2640,6 +2675,7 @@ const SortingVisualizerComponent = ({
2640
2675
  const [customArray, setCustomArray] = useState(null);
2641
2676
  const [historyCollapsed, setHistoryCollapsed] = useState(true);
2642
2677
  const [urlStateLoaded, setUrlStateLoaded] = useState(false);
2678
+ const [showComplexityTable, setShowComplexityTable] = useState(false);
2643
2679
  const playingRef = useRef(false);
2644
2680
  const timeoutRef = useRef(null);
2645
2681
  const VISUALIZER_ID = "sorting-visualizer";
@@ -2944,6 +2980,63 @@ const SortingVisualizerComponent = ({
2944
2980
  /* @__PURE__ */ jsx(HelpPanel, {})
2945
2981
  ] })
2946
2982
  ] }) }),
2983
+ /* @__PURE__ */ jsxs("div", { className: "px-4 pb-2", children: [
2984
+ /* @__PURE__ */ jsxs(
2985
+ "button",
2986
+ {
2987
+ onClick: () => setShowComplexityTable(!showComplexityTable),
2988
+ className: "flex items-center gap-2 text-sm text-indigo-600 hover:text-indigo-800 font-medium transition-colors",
2989
+ children: [
2990
+ /* @__PURE__ */ jsx(
2991
+ "svg",
2992
+ {
2993
+ className: `w-4 h-4 transition-transform ${showComplexityTable ? "rotate-90" : ""}`,
2994
+ fill: "none",
2995
+ viewBox: "0 0 24 24",
2996
+ stroke: "currentColor",
2997
+ children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" })
2998
+ }
2999
+ ),
3000
+ "Algorithm Complexity Comparison"
3001
+ ]
3002
+ }
3003
+ ),
3004
+ showComplexityTable && /* @__PURE__ */ jsxs("div", { className: "mt-3 p-4 bg-gradient-to-r from-indigo-50 to-blue-50 rounded-xl border border-indigo-200", children: [
3005
+ /* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: "w-full text-sm", children: [
3006
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "text-left text-indigo-900", children: [
3007
+ /* @__PURE__ */ jsx("th", { className: "pb-2 pr-4 font-semibold", children: "Algorithm" }),
3008
+ /* @__PURE__ */ jsx("th", { className: "pb-2 px-3 font-semibold text-center", children: "Best" }),
3009
+ /* @__PURE__ */ jsx("th", { className: "pb-2 px-3 font-semibold text-center", children: "Average" }),
3010
+ /* @__PURE__ */ jsx("th", { className: "pb-2 px-3 font-semibold text-center", children: "Worst" }),
3011
+ /* @__PURE__ */ jsx("th", { className: "pb-2 px-3 font-semibold text-center", children: "Space" }),
3012
+ /* @__PURE__ */ jsx("th", { className: "pb-2 pl-3 font-semibold text-center", children: "Stable" })
3013
+ ] }) }),
3014
+ /* @__PURE__ */ jsx("tbody", { className: "text-gray-700", children: Object.keys(ALGORITHM_NAMES$1).map((alg) => {
3015
+ const comp = ALGORITHM_COMPLEXITIES$1[alg];
3016
+ const isCurrentAlgorithm = alg === algorithm;
3017
+ return /* @__PURE__ */ jsxs(
3018
+ "tr",
3019
+ {
3020
+ className: `border-t border-indigo-100 ${isCurrentAlgorithm ? "bg-indigo-100/50 font-medium" : ""}`,
3021
+ children: [
3022
+ /* @__PURE__ */ jsx("td", { className: "py-2 pr-4", children: /* @__PURE__ */ jsx("span", { className: isCurrentAlgorithm ? "text-indigo-700" : "", children: ALGORITHM_NAMES$1[alg] }) }),
3023
+ /* @__PURE__ */ jsx("td", { className: "py-2 px-3 text-center", children: /* @__PURE__ */ jsx("span", { className: `px-2 py-0.5 rounded text-xs ${comp.best.includes("log") ? "bg-green-100 text-green-700" : "bg-yellow-100 text-yellow-700"}`, children: comp.best }) }),
3024
+ /* @__PURE__ */ jsx("td", { className: "py-2 px-3 text-center", children: /* @__PURE__ */ jsx("span", { className: `px-2 py-0.5 rounded text-xs ${comp.average.includes("log") ? "bg-green-100 text-green-700" : "bg-yellow-100 text-yellow-700"}`, children: comp.average }) }),
3025
+ /* @__PURE__ */ jsx("td", { className: "py-2 px-3 text-center", children: /* @__PURE__ */ jsx("span", { className: `px-2 py-0.5 rounded text-xs ${comp.worst.includes("log") ? "bg-green-100 text-green-700" : "bg-red-100 text-red-700"}`, children: comp.worst }) }),
3026
+ /* @__PURE__ */ jsx("td", { className: "py-2 px-3 text-center", children: /* @__PURE__ */ jsx("span", { className: `px-2 py-0.5 rounded text-xs ${comp.space === "O(1)" ? "bg-green-100 text-green-700" : "bg-purple-100 text-purple-700"}`, children: comp.space }) }),
3027
+ /* @__PURE__ */ jsx("td", { className: "py-2 pl-3 text-center", children: comp.stable ? /* @__PURE__ */ jsx("span", { className: "text-green-600", children: "✓" }) : /* @__PURE__ */ jsx("span", { className: "text-red-400", children: "✗" }) })
3028
+ ]
3029
+ },
3030
+ alg
3031
+ );
3032
+ }) })
3033
+ ] }) }),
3034
+ /* @__PURE__ */ jsxs("p", { className: "mt-3 text-xs text-indigo-600", children: [
3035
+ /* @__PURE__ */ jsx("strong", { children: "Stable:" }),
3036
+ " A sorting algorithm is stable if elements with equal keys maintain their relative order."
3037
+ ] })
3038
+ ] })
3039
+ ] }),
2947
3040
  showControls && /* @__PURE__ */ jsxs("div", { className: "px-4 py-3 bg-gray-50 border-t border-gray-200", children: [
2948
3041
  /* @__PURE__ */ jsx(
2949
3042
  ControlPanel,
@@ -17458,15 +17551,75 @@ const SQLJoinVisualizerComponent = ({
17458
17551
  }) : /* @__PURE__ */ jsx("div", { className: "text-[10px] text-gray-400 text-center py-2", children: "No results yet" })
17459
17552
  ] })
17460
17553
  ] }),
17461
- /* @__PURE__ */ jsx("div", { className: "mb-4 p-3 bg-blue-50 rounded-lg", children: /* @__PURE__ */ jsxs("div", { className: "text-xs text-blue-700", children: [
17462
- /* @__PURE__ */ jsxs("strong", { children: [
17463
- joinType.toUpperCase(),
17464
- " JOIN:"
17554
+ /* @__PURE__ */ jsx("div", { className: "mb-4 p-3 bg-gradient-to-r from-cyan-50 to-blue-50 rounded-lg border border-cyan-200", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
17555
+ /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 100 60", className: "w-24 h-14 flex-shrink-0", children: [
17556
+ /* @__PURE__ */ jsx(
17557
+ "circle",
17558
+ {
17559
+ cx: "35",
17560
+ cy: "30",
17561
+ r: "22",
17562
+ fill: joinType === "left" || joinType === "full" ? "#06b6d4" : joinType === "inner" ? "transparent" : "#e5e7eb",
17563
+ fillOpacity: joinType === "left" || joinType === "full" ? 0.6 : joinType === "inner" ? 0 : 0.5,
17564
+ stroke: "#0891b2",
17565
+ strokeWidth: "2"
17566
+ }
17567
+ ),
17568
+ /* @__PURE__ */ jsx(
17569
+ "circle",
17570
+ {
17571
+ cx: "65",
17572
+ cy: "30",
17573
+ r: "22",
17574
+ fill: joinType === "right" || joinType === "full" ? "#06b6d4" : joinType === "inner" ? "transparent" : "#e5e7eb",
17575
+ fillOpacity: joinType === "right" || joinType === "full" ? 0.6 : joinType === "inner" ? 0 : 0.5,
17576
+ stroke: "#0891b2",
17577
+ strokeWidth: "2"
17578
+ }
17579
+ ),
17580
+ /* @__PURE__ */ jsx("clipPath", { id: "leftClip", children: /* @__PURE__ */ jsx("circle", { cx: "35", cy: "30", r: "22" }) }),
17581
+ /* @__PURE__ */ jsx(
17582
+ "circle",
17583
+ {
17584
+ cx: "65",
17585
+ cy: "30",
17586
+ r: "22",
17587
+ fill: "#22c55e",
17588
+ fillOpacity: "0.7",
17589
+ clipPath: "url(#leftClip)"
17590
+ }
17591
+ ),
17592
+ /* @__PURE__ */ jsx("text", { x: "22", y: "33", fontSize: "8", fill: "#0e7490", fontWeight: "bold", children: "L" }),
17593
+ /* @__PURE__ */ jsx("text", { x: "74", y: "33", fontSize: "8", fill: "#0e7490", fontWeight: "bold", children: "R" })
17465
17594
  ] }),
17466
- joinType === "inner" && " Returns only rows with matches in BOTH tables.",
17467
- joinType === "left" && " Returns ALL rows from left + matching rows from right (NULL if no match).",
17468
- joinType === "right" && " Returns ALL rows from right + matching rows from left (NULL if no match).",
17469
- joinType === "full" && " Returns ALL rows from BOTH tables (NULL where no match exists)."
17595
+ /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
17596
+ /* @__PURE__ */ jsxs("div", { className: "text-sm font-semibold text-cyan-800 mb-1", children: [
17597
+ joinType.toUpperCase(),
17598
+ " JOIN"
17599
+ ] }),
17600
+ /* @__PURE__ */ jsxs("div", { className: "text-xs text-cyan-700", children: [
17601
+ joinType === "inner" && /* @__PURE__ */ jsxs(Fragment, { children: [
17602
+ "Returns only rows with matches in ",
17603
+ /* @__PURE__ */ jsx("strong", { children: "both" }),
17604
+ " tables (green intersection)."
17605
+ ] }),
17606
+ joinType === "left" && /* @__PURE__ */ jsxs(Fragment, { children: [
17607
+ "Returns ",
17608
+ /* @__PURE__ */ jsx("strong", { children: "all" }),
17609
+ " rows from left table + matching rows from right. NULL if no match."
17610
+ ] }),
17611
+ joinType === "right" && /* @__PURE__ */ jsxs(Fragment, { children: [
17612
+ "Returns ",
17613
+ /* @__PURE__ */ jsx("strong", { children: "all" }),
17614
+ " rows from right table + matching rows from left. NULL if no match."
17615
+ ] }),
17616
+ joinType === "full" && /* @__PURE__ */ jsxs(Fragment, { children: [
17617
+ "Returns ",
17618
+ /* @__PURE__ */ jsx("strong", { children: "all" }),
17619
+ " rows from both tables. NULL where no match exists."
17620
+ ] })
17621
+ ] })
17622
+ ] })
17470
17623
  ] }) }),
17471
17624
  /* @__PURE__ */ jsx(
17472
17625
  StatusPanel,