Core
Grafy
Čárové, plošné a sloupcové grafy — odkud jsou data, co se kreslí v prohlížeči a z čeho je každá série složená.
Čistě CSS sloupce: vertikální finance, vertikální systémové metriky s mřížkou a horizontální postup.
Na této stránce
- ChartWidget
- Základní použití
- Typy chartů
- Dynamická data s closurami
- Filtr v rozbalovací nabídce
- ChartWidget API
- Konvenční widgety
- Chart.js options
- BarChartWidget
- Finanční sloupce
- Systémové metriky (vertikální, s mřížkovými čárami)
- Systémové metriky (horizontální)
- Jak se resolvuje výška výplně
- Bezpečné barvy
- Validace
- BarChartWidget API
- ChartItem
- ChartItem API
- Související
Grafový widget je dotaz a tvar: data se skládají na serveru, kreslí se v
prohlížeči a hranice mezi tím rozhoduje o tom, co stojí obnovení. BarChartWidget
je ten, který nepotřebuje žádný JavaScript — a proto je to samostatná třída, ne
volba.
ChartWidget
Chart widget s integrací Chart.js. Podporuje line, bar, pie a doughnut charty.
use NyonCode\WireCore\Widgets\ChartWidget;
Vyžaduje Chart.js. Widget vykreslí
<canvas>a inicializuje ho přes Alpine. Zahrňte Chart.js na stránku — přes CDN nebo váš bundle — nebo canvas zůstane prázdný a zaloguje se varování v konzoli. Stylování datasetů (borderColor,fill,tension, …) se předává rovnou do Chart.js.Vlastní Alpine controller widgetu od vás nepotřebuje nic: dodává se jako bundle balíčku a widget si ho vyzvedne, když se vykresluje. Grafy jsou těžký, volitelný asset, takže záměrně není v sadě
@wireStackScriptsnačítané vždy.
Základní použití
ChartWidget::make() ->heading('Revenue Over Time') ->type('line') ->labels(['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']) ->datasets([ [ 'label' => 'Revenue', 'data' => [1200, 1900, 3000, 5000, 2300, 3200], 'borderColor' => '#3B82F6', ], ])
Typy chartů
->type('line') // line chart (výchozí)->type('bar') // bar chart->type('pie') // pie chart->type('doughnut') // doughnut chart
Dynamická data s closurami
Datasety a popisky přijímají closury. Aktivní hodnota filtru se předá jako argument:
ChartWidget::make() ->heading('Sales') ->type('bar') ->filter(['2025' => '2025', '2026' => '2026'], '2026') ->labels(fn (?string $filter) => match($filter) { '2025' => ['Q1', 'Q2', 'Q3', 'Q4'], '2026' => ['Q1', 'Q2'], default => [], }) ->datasets(fn (?string $filter) => [ ['label' => 'Sales', 'data' => $filter === '2025' ? [100, 200, 150, 300] : [180, 250]], ])
Filtr v rozbalovací nabídce
->filter(array $options, ?string $default = null)
Přidá rozbalovací nabídku na widget. Vybraný klíč se předá closurám na datasety a popisky — na serveru, protože tam ty closury žijí.
ChartWidget::make() ->heading('Revenue') ->filter([ 'week' => 'This Week', 'month' => 'This Month', 'year' => 'This Year', ], 'month')
Změna výběru zavolá na hostiteli filterWidget(), ten closury znovu vyřeší a
odpoví jen markupem tohoto widgetu. Obal grafu nese aktivní klíč ve svém
wire:key, takže morph element nahradí, místo aby ho záplatoval — Alpine
nikdy znovu nevyhodnotí x-data na elementu, který už inicializoval, takže
záplatovaný atribut by nikdo nepřečetl a Chart.js by dál kreslil starou sérii.
Nahrazení starý graf zbourá přes destroy() v controlleru a nad novými daty
postaví nový.
Tohle je novinka 2.0. Filtr se dřív řešil v prohlížeči: Alpine
updateChart()přiřadilthis.labelsathis.datasetszpátky na graf, se kterým byl sestaven, takže změna výběru překreslila identický graf a closury nikdy neběžely s ničím jiným než se svou výchozí hodnotou.
filter() už není vlastnost grafu — je na základní třídě widgetu, takže seznam
nebo progress nástěnka berou stejnou mapu voleb. Viz
Filtry.
ChartWidget API
->type(string $type) // 'line', 'bar', 'pie', 'doughnut'->getType(): string->datasets(array|Closure $datasets) // formát datasetu Chart.js->getDatasets(): array->labels(array|Closure $labels) // labely osy x->getLabels(): array->options(array $options) // Chart.js options sloučené přes výchozí typu->getOptions(): array
filter(), activeFilter() a jejich gettery sdílí každý widget a jsou
zdokumentované na základní třídě widgetu.
Konvenční widgety
Deklarativní presety nad ChartWidget, takže dashboard vyjadřuje záměr místo ->type(...):
use NyonCode\WireCore\Widgets\DoughnutChartWidget;use NyonCode\WireCore\Widgets\LineChartWidget;use NyonCode\WireCore\Widgets\PieChartWidget; LineChartWidget::make()->heading('Revenue')->labels([...])->datasets([...]);PieChartWidget::make()->heading('By Category')->labels([...])->datasets([...]);DoughnutChartWidget::make()->heading('By Status')->labels([...])->datasets([...]);
PieChartWidget a DoughnutChartWidget ukazují Chart.js legendu ve výchozím stavu (pozice nahoře) — výseče koláče na ni spoléhají. Vše ostatní odpovídá ChartWidget.
Chart.js options
Přepište jakoukoli Chart.js option pomocí options(); pole se sloučí přes výchozí typu (responsive: true, maintainAspectRatio: false, plus pie/doughnut legenda), takže specifikujete jen to, co se mění:
LineChartWidget::make() ->datasets([...]) ->options([ 'scales' => ['y' => ['beginAtZero' => true]], 'plugins' => ['legend' => ['display' => false]], ])
BarChartWidget
Bez závislostí bar chart vykreslený zcela Tailwind utility třídami — bez Chart.js, bez <canvas>, bez JavaScriptu. Použijte ho pro kompaktní, tiskově přívětivé dashboardy. Je to odlišný widget od ChartWidget; oba mohou žít na stejném dashboardu.
use NyonCode\WireCore\Widgets\BarChartWidget;use NyonCode\WireCore\Widgets\ChartItem;
Widget má tři vizuální režimy, vybrané z type() + variant():
type() |
variant() |
Vzhled |
|---|---|---|
vertical |
finance |
Vertikální sloupce: formátovaná hodnota nahoře, světlá max-height dráha, MM / YYYY popisek dole |
vertical |
system / default |
Vertikální sloupce na 0–100% dráze s hlavičkou ikona + popisek + procento a volitelnými mřížkovými čárami |
horizontal |
system / default |
Horizontální progress bary: popisek vlevo, hodnota vpravo |
Finanční sloupce
BarChartWidget::make() ->heading('Přehled tržeb') ->type('vertical') ->variant('finance') ->items([ ChartItem::make('01 / 2024')->value(125000)->formattedValue('125 000 Kč')->color('blue')->percentage(70), ChartItem::make('02 / 2024')->value(98500)->formattedValue('98 500 Kč')->color('green')->percentage(55), ])
Systémové metriky (vertikální, s mřížkovými čárami)
BarChartWidget::make() ->heading('Přehled systému') ->type('vertical') ->variant('system') ->showGrid() // 0% / 25% / 50% / 75% / 100% vodicí čáry ->showMenu() // "⋯" prvek options v hlavičce karty ->maxValue(100) // procentní režim (0–100 dráha) ->verticalLabels() // popisek každého sloupce otočený svisle vedle něj (vejdou se dlouhé názvy) ->items([ ChartItem::make('CPU')->value(72)->formattedValue('72 %')->icon('cpu-chip')->color('blue')->percentage(72), ChartItem::make('RAM')->value(54)->formattedValue('54 %')->icon('circle-stack')->color('green')->percentage(54), ChartItem::make('Disk')->value(81)->formattedValue('81 %')->icon('server')->color('orange')->percentage(81), ChartItem::make('GPU')->value(36)->formattedValue('36 %')->icon('bolt')->color('purple')->percentage(36), ])
Systémové metriky (horizontální)
Stejné položky, přepněte type('horizontal'):
BarChartWidget::make() ->type('horizontal') ->variant('system') ->maxValue(100) ->items([ /* ChartItem… */ ])
Jak se resolvuje výška výplně
Procento výplně každého sloupce (percentageFor(ChartItem)) se resolvuje v tomto pořadí:
- Explicitní
->percentage(0–100)u jednotlivých položek vyhrává. - Jinak se hodnota škáluje proti widget
->maxValue(). - Jinak (procentní režim bez stropu) se hodnota automaticky škáluje proti největší položce.
Výsledek se vždy ořízne na 0–100. Velikost výplně je jediný dynamický styl, předaný jako CSS proměnná a konzumovaný Tailwind arbitrary hodnotami:
<div class="… h-[var(--value)]" style="--value: 72%"></div>
Bezpečné barvy
Hodnoty color() mapují přes pevný allow-list (HasColor::getGradientFillClasses() / getFillTextClasses()) — řetězce dodané vlastníkem nemohou nikdy injektovat libovolné třídy. Podporované chart odstíny:
| klíč | fill gradient | akcentový text |
|---|---|---|
blue |
from-blue-500 to-blue-600 |
text-blue-600 |
green |
from-green-500 to-green-600 |
text-green-600 |
orange |
from-orange-500 to-orange-600 |
text-orange-600 |
purple |
from-purple-500 to-purple-600 |
text-purple-600 |
gray |
from-slate-400 to-slate-500 |
text-slate-600 |
(Brand alias primary a širší slovník palety — red, amber, cyan, pink, … — jsou přijímány také.)
Validace
->type('diagonal'); // vyhodí InvalidArgumentException (povoleno: vertical, horizontal)->variant('pie'); // vyhodí InvalidArgumentException (povoleno: finance, system, default)ChartItem::make('CPU')->percentage(120); // vyhodí InvalidArgumentException (0–100)
BarChartWidget API
->type(string $type) // 'vertical' | 'horizontal' (validováno)->getType(): string->variant(string $variant) // 'finance' | 'system' | 'default' (validováno)->getVariant(): string->items(array|Closure $items) // array<ChartItem>, nebo fn (?string $filter): array — validováno tak i tak->getItems(): array->showGrid(bool $show = true) // mřížkové čáry (system vertical)->shouldShowGrid(): bool->showMenu(bool $show = true) // prvek options v hlavičce karty->shouldShowMenu(): bool->maxValue(int|float|null $max) // absolutní strop; null = procentní režim->getMaxValue(): ?float->height(int $px) // výška vertikálního plotu (výchozí 240)->getHeight(): int->verticalLabels(bool $on = true) // popisek každého sloupce svisle vedle něj (vertikální grafy; dlouhé názvy)->hasVerticalLabels(): bool->rounded(string $scale) // radius karty: 'lg' | 'xl' | '2xl' (výchozí) | '3xl' | …->getRounded(): string->percentageFor(ChartItem $item): float // resolvovaná 0–100 výplň->fillClassesFor(ChartItem $item): string // bezpečné gradient třídy->textClassesFor(ChartItem $item): string // bezpečné akcentové text třídy
ChartItem
Jeden sloupec v BarChartWidget.
use NyonCode\WireCore\Widgets\ChartItem;
ChartItem API
ChartItem::make(string $label)->value(int|float $value) // surová numerická hodnota->getValue(): float->formattedValue(?string $formatted) // zobrazovací řetězec, např. '125 000 Kč' / '72 %'->getFormattedValue(): string // spadne na surovou hodnotu->color(string|Color|null $color) // bezpečný klíč barvy (výchozí 'primary')->getColor(): string->percentage(int|float $percentage) // explicitní 0–100 výplň (validováno)->getPercentage(): ?float->hasPercentage(): bool->icon(string|Icon|null $icon) // název ikony (system/horizontal varianty)->getIcon(): ?string->getLabel(): string->extraAttributes(array $attrs)
Související
- Widgety — polling, autorizace a sdílené API
- Statistiky — číslo tam, kde by graf byl moc
- Barvy — kde se řeší barva série
- JavaScriptové assety — co graf položí na stránku