Showing total visitors for the last 6 months
January - June 2024
Showing total visitors for the last 6 months
January - June 2024
Showing total visitors for the last 6 months
Desktop
Mobile
January - June 2024
Showing total visitors for the last 6 months
January - June 2024
Showing total visitors for the last 6 months
January - June 2024
Showing total visitors for the last 6 months
January - June 2024
Showing total visitors for the last 6 months
January - June 2024
Online Transactions
Desktop
Mobile
Tablet
import reflex as rx
from typing import Any, Dict, List, Optional, Union, Literal
class BarChart:
def __init__(self, data: List[Dict[str, Any]]):
self._data = data
self._x_key: Optional[str] = None
self._series: List[Dict[str, Any]] = []
self._layout: Literal["horizontal", "vertical"] = "horizontal"
self._width: Union[int, str] = "100%"
self._height: int = 250
self._extra: Dict[str, Any] = {}
self._components: List[Any] = []
self._custom_legend: Optional[Dict[str, str]] = None
self._legend_position: str = "bottom"
self._show_tooltip: bool = True
self._show_grid: bool = True
self._show_y_axis: bool = False
self._y_axis_props: Dict[str, Any] = {}
self._show_x_axis: bool = True
self._x_axis_props: Dict[str, Any] = {}
def x(self, key: str) -> "BarChart":
self._x_key = key
return self
def layout(self, layout: Literal["horizontal", "vertical"]) -> "BarChart":
self._layout = layout
return self
def series(
self,
key: str,
fill: str = "chart-1",
stack_id: Optional[str] = None,
radius: Optional[Union[int, List[int]]] = None,
label: Optional[Union[bool, Dict[str, Any]]] = None,
is_animation_active: Optional[bool] = True,
bar_size: Optional[int] = None,
legend_type: Optional[str] = None,
name: Optional[str] = None,
**kwargs: Any,
) -> "BarChart":
# Handle fill color with rx.cond for reactive variables
fill_color = rx.cond(
fill.startswith("var("),
fill,
rx.cond(
fill.startswith("#") | fill.startswith("rgb") | fill.startswith("hsl"),
fill,
f"var(--{fill})",
),
)
bar_props = {
"data_key": key,
"fill": fill_color,
"stack_id": stack_id,
"radius": radius,
"label": label,
"is_animation_active": is_animation_active,
"bar_size": bar_size,
"legend_type": legend_type,
"name": name,
}
bar_props.update(kwargs)
# Don't filter None values here - let Reflex handle it
self._series.append(bar_props)
return self
def x_axis(
self,
show: bool = True,
type_: Optional[str] = None,
data_key: Optional[str] = None,
hide: bool = False,
axis_line: bool = False,
tick_size: Optional[int] = 10,
tick_line: bool = False,
custom_attrs: Optional[Dict[str, Any]] = None,
interval: Optional[str] = "preserveStartEnd",
**kwargs: Any,
) -> "BarChart":
self._show_x_axis = show
if show:
props = {
"data_key": data_key,
"hide": hide,
"type_": type_,
"axis_line": axis_line,
"tick_size": tick_size,
"tick_line": tick_line,
"custom_attrs": custom_attrs or {"fontSize": "12px"},
"interval": interval,
}
# Add type_ only if specified
if type_ is not None:
props["type_"] = type_
props.update(kwargs)
self._x_axis_props = props
return self
def y_axis(
self,
show: bool = True,
type_: Optional[str] = None,
hide: bool = False,
data_key: Optional[str] = None,
axis_line: bool = False,
min_tick_gap: Optional[int] = 5,
tick_size: Optional[int] = 10,
tick_line: bool = False,
custom_attrs: Optional[Dict[str, Any]] = None,
**kwargs: Any,
) -> "BarChart":
self._show_y_axis = show
if show:
props = {
"hide": hide,
"type_": type_,
"data_key": data_key,
"axis_line": axis_line,
"min_tick_gap": min_tick_gap,
"tick_size": tick_size,
"tick_line": tick_line,
"custom_attrs": custom_attrs or {"fontSize": "12px"},
}
# Add type_ only if specified
if type_ is not None:
props["type_"] = type_
props.update(kwargs)
self._y_axis_props = props
return self
def tooltip(self, show: bool = True) -> "BarChart":
self._show_tooltip = show
return self
def grid(self, show: bool = True) -> "BarChart":
self._show_grid = show
return self
def size(self, width: Union[int, str], height: int) -> "BarChart":
self._width = width
self._height = height
return self
def config(
self,
margin: Optional[Dict[str, int]] = None,
stack_offset: Optional[str] = None,
sync_id: Optional[str] = None,
sync_method: Optional[str] = None,
reverse_stack_order: Optional[bool] = None,
bar_category_gap: Optional[Union[str, int]] = None,
bar_gap: Optional[Union[str, int]] = None,
max_bar_size: Optional[int] = None,
**kwargs: Any,
) -> "BarChart":
if margin is not None:
self._extra["margin"] = margin
if stack_offset is not None:
self._extra["stack_offset"] = stack_offset
if sync_id is not None:
self._extra["sync_id"] = sync_id
if sync_method is not None:
self._extra["sync_method"] = sync_method
if reverse_stack_order is not None:
self._extra["reverse_stack_order"] = reverse_stack_order
if bar_category_gap is not None:
self._extra["bar_category_gap"] = bar_category_gap
if bar_gap is not None:
self._extra["bar_gap"] = bar_gap
if max_bar_size is not None:
self._extra["max_bar_size"] = max_bar_size
self._extra.update(kwargs)
return self
def legend(self, labels: Dict[str, str], position: str = "bottom") -> "BarChart":
self._custom_legend = labels
self._legend_position = position
return self
def add(self, *components: Any) -> "BarChart":
self._components.extend(components)
return self
def _create_legend_item(self, series_data: Dict[str, Any]) -> rx.Component:
"""Create a legend item for a series"""
data_key = series_data["data_key"]
label = rx.cond(
self._custom_legend is not None,
self._custom_legend.get(data_key, data_key),
data_key,
)
return rx.hstack(
rx.box(bg=series_data["fill"], class_name="w-3 h-3 rounded-sm"),
rx.text(
label,
class_name="text-sm font-semibold",
color=rx.color("slate", 11),
),
spacing="2",
align="center",
)
def __call__(self, **kwargs: Any) -> rx.Component:
if not self._x_key:
raise ValueError("X axis key must be set with `.x()` before rendering.")
if not self._series:
raise ValueError(
"At least one series must be added with `.series()` before rendering."
)
components = []
# Add tooltip first (like in AreaChart)
if self._show_tooltip:
components.append(
rx.recharts.tooltip(
is_animation_active=False,
separator="",
cursor=False,
item_style={
"color": "currentColor",
"display": "flex",
"paddingBottom": "0px",
"justifyContent": "space-between",
"textTransform": "capitalize",
},
label_style={"color": rx.color("slate", 10), "fontWeight": "500"},
content_style={
"background": rx.color_mode_cond(
"oklch(0.97 0.00 0)", "oklch(0.14 0.00 286)"
),
"borderColor": rx.color("slate", 5),
"borderRadius": "5px",
"fontFamily": "IBM Plex Mono,ui-monospace,monospace",
"fontSize": "0.875rem",
"lineHeight": "1.25rem",
"fontWeight": "500",
"letterSpacing": "-0.01rem",
"minWidth": "8rem",
"width": "175px",
"padding": "0.375rem 0.625rem",
"position": "relative",
},
)
)
# Add grid
if self._show_grid:
components.append(
rx.recharts.cartesian_grid(
horizontal=True, vertical=False, class_name="opacity-25"
)
)
# Add Y axis (like in AreaChart pattern)
if self._show_y_axis:
components.append(rx.recharts.y_axis(**self._y_axis_props))
# Add bars (series) - CRITICAL: Add bars before X axis (like AreaChart adds areas before x_axis)
for s in self._series:
label_list = []
if s.get("label") and isinstance(s["label"], dict):
label_list.append(rx.recharts.label_list(**s["label"]))
elif s.get("label") is True:
label_list.append(rx.recharts.label_list())
# Create bar component - filter None values at render time
bar_props = {k: v for k, v in s.items() if v is not None and k != "label"}
components.append(rx.recharts.bar(*label_list, **bar_props))
# Add X axis LAST (like in AreaChart)
if self._show_x_axis:
if self._x_axis_props:
x_axis_props = dict(self._x_axis_props)
# Set data_key to x_key if not explicitly provided
if x_axis_props.get("data_key") is None:
x_axis_props["data_key"] = self._x_key
components.append(rx.recharts.x_axis(**x_axis_props))
else:
# Default X axis
components.append(
rx.recharts.x_axis(
data_key=self._x_key,
axis_line=False,
tick_size=10,
tick_line=False,
interval="preserveStartEnd",
custom_attrs={"fontSize": "12px"},
)
)
# Add any custom components
components.extend(self._components)
# Create the bar chart
chart = rx.recharts.bar_chart(
*components,
data=self._data,
layout=self._layout,
width=self._width,
height=self._height,
**self._extra,
**kwargs,
)
# Handle custom legend with reactive components
if self._custom_legend:
legend_items = [self._create_legend_item(s) for s in self._series]
legend = rx.hstack(
*legend_items,
class_name="justify-center gap-4 py-2",
)
return rx.cond(
self._legend_position == "top",
rx.box(legend, chart, class_name="w-full flex flex-col"),
rx.box(chart, legend, class_name="w-full flex flex-col"),
)
return chart
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
--chart-1: oklch(0.81 0.1 252);
--chart-2: oklch(0.62 0.19 260);
--chart-3: oklch(0.55 0.22 263);
--chart-4: oklch(0.49 0.22 264);
--chart-5: oklch(0.42 0.18 266);
}
.dark {
--chart-1: oklch(0.81 0.1 252);
--chart-2: oklch(0.62 0.19 260);
--chart-3: oklch(0.55 0.22 263);
--chart-4: oklch(0.49 0.22 264);
--chart-5: oklch(0.42 0.18 266);
}
BarChart
Instantiate the BarChart with data.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
data | List[Dict[str, Any]] | True | The list of data points to be plotted. |
x
Set the X axis data key (category axis).
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
key | str | True | The key in data to use for the X axis. |
series
Add a data series (bar) to the chart.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
key | str | True | Data key for this bar series. | |
fill | str | False | 'chart-1' | Fill color (CSS variable or raw color). |
stack_id | Optional[str] | False | None | ID to stack bars together. |
radius | Optional[Union[int, List[int]]] | False | 0 | Corner radius of bars; can be int or list of 4 ints. |
stroke | Optional[str] | False | None | Stroke color for bar outline. |
stroke_width | Optional[int] | False | 1 | Width of the bar stroke. |
is_animation_active | Optional[bool] | False | True | Enable animation. |
on_click | Optional[Any] | False | None | Click event handler. |
y_axis
Configure the Y axis (usually numeric).
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
enabled | bool | False | False | Show Y axis if True. |
type_ | str | False | 'number' | Axis type, typically 'number' or 'category'. |
axis_line | bool | False | False | Show axis line. |
min_tick_gap | int | False | 50 | Minimum gap between ticks. |
tick_size | int | False | 10 | Size of ticks. |
tick_line | bool | False | False | Show tick lines. |
custom_attrs | Dict[str, Any] | False | None | Additional props for Y axis. |
x_axis
Configure the X axis (category axis).
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
data_key | str | False | None | Key for the X axis data. |
type_ | str | False | 'category' | Axis type, usually 'category'. |
axis_line | bool | False | True | Show axis line. |
tick_size | int | False | 10 | Size of ticks. |
tick_line | bool | False | True | Show tick lines. |
interval | Union[int, str] | False | None | Tick interval, e.g. 0, 1, or 'preserveStartEnd'. |
custom_attrs | Dict[str, Any] | False | None | Additional props for X axis. |
tooltip
Configure tooltip visibility and style.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
show | bool | False | True | Show tooltip if True. |
grid
Configure Cartesian grid visibility.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
show | bool | False | True | Show grid if True. |
size
Set chart dimensions.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
width | Union[int, str] | True | '100%' | Chart width (e.g., '100%' or int). |
height | int | True | 250 | Chart height in pixels. |
layout
Set chart layout orientation.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
layout | str | False | 'vertical' | Chart layout: 'vertical' or 'horizontal'. |
margin
Set chart margins.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
margin | Dict[str, int] | False | None | Margin around chart (e.g., {'top': 10, 'left': 10}). |
bar_size
Set bar width.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
bar_size | int | False | 25 | Width of bars in pixels. |
bar_gap
Set gap between bars.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
bar_gap | int | False | 4 | Gap between bars in pixels. |
legend
Configure custom legend labels and position.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
labels | Dict[str, str] | True | Mapping of series key to legend label text. | |
position | str | False | 'bottom' | Legend position: 'top' or 'bottom'. |
add
Add extra recharts components manually.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
components | Any | False | None | One or more recharts components. |
Home
Pantry UI