Files
michaelschiemer/src/Application/LiveComponents/Chart/ChartState.php
Michael Schiemer fc3d7e6357 feat(Production): Complete production deployment infrastructure
- Add comprehensive health check system with multiple endpoints
- Add Prometheus metrics endpoint
- Add production logging configurations (5 strategies)
- Add complete deployment documentation suite:
  * QUICKSTART.md - 30-minute deployment guide
  * DEPLOYMENT_CHECKLIST.md - Printable verification checklist
  * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle
  * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference
  * production-logging.md - Logging configuration guide
  * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation
  * README.md - Navigation hub
  * DEPLOYMENT_SUMMARY.md - Executive summary
- Add deployment scripts and automation
- Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment
- Update README with production-ready features

All production infrastructure is now complete and ready for deployment.
2025-10-25 19:18:37 +02:00

265 lines
7.1 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Application\LiveComponents\Chart;
use App\Application\LiveComponents\LiveComponentState;
/**
* Type-safe state for ChartComponent
*
* Provides compile-time type safety for real-time chart visualization.
* All properties are readonly and immutable - transformations return new instances.
*/
final readonly class ChartState implements LiveComponentState
{
public function __construct(
public string $chartType = 'line',
public array $chartData = [],
public string $dataRange = '24h',
public int $lastUpdate = 0,
public bool $autoRefresh = true,
public int $refreshInterval = 5000,
public float $executionTimeMs = 0,
public int $dataPointsCount = 0,
public string $dataSource = 'demo'
) {
}
/**
* Create from ComponentData (Framework → Domain conversion)
*/
public static function fromArray(array $data): self
{
return new self(
chartType: (string) ($data['chart_type'] ?? 'line'),
chartData: ($data['chart_data'] ?? []),
dataRange: (string) ($data['data_range'] ?? '24h'),
lastUpdate: (int) ($data['last_update'] ?? 0),
autoRefresh: (bool) ($data['auto_refresh'] ?? true),
refreshInterval: (int) ($data['refresh_interval'] ?? 5000),
executionTimeMs: (float) ($data['execution_time_ms'] ?? 0),
dataPointsCount: (int) ($data['data_points_count'] ?? 0),
dataSource: (string) ($data['data_source'] ?? 'demo')
);
}
/**
* Create empty state with defaults
*/
public static function empty(): self
{
return new self();
}
/**
* Convert to ComponentData (Domain → Framework conversion)
*/
public function toArray(): array
{
return [
'chart_type' => $this->chartType,
'chart_data' => $this->chartData,
'data_range' => $this->dataRange,
'last_update' => $this->lastUpdate,
'auto_refresh' => $this->autoRefresh,
'refresh_interval' => $this->refreshInterval,
'execution_time_ms' => $this->executionTimeMs,
'data_points_count' => $this->dataPointsCount,
'data_source' => $this->dataSource,
];
}
/**
* Update chart with refreshed data
*/
public function withRefreshedData(array $chartData, float $executionTimeMs): self
{
return new self(
chartType: $this->chartType,
chartData: $chartData,
dataRange: $this->dataRange,
lastUpdate: time(),
autoRefresh: $this->autoRefresh,
refreshInterval: $this->refreshInterval,
executionTimeMs: $executionTimeMs,
dataPointsCount: $this->calculateDataPointsCount($chartData),
dataSource: $this->dataSource
);
}
/**
* Change chart type
*/
public function withChartType(string $chartType, array $chartData): self
{
return new self(
chartType: $chartType,
chartData: $chartData,
dataRange: $this->dataRange,
lastUpdate: time(),
autoRefresh: $this->autoRefresh,
refreshInterval: $this->refreshInterval,
executionTimeMs: 0,
dataPointsCount: $this->calculateDataPointsCount($chartData),
dataSource: $this->dataSource
);
}
/**
* Change data range
*/
public function withDataRange(string $dataRange, array $chartData): self
{
return new self(
chartType: $this->chartType,
chartData: $chartData,
dataRange: $dataRange,
lastUpdate: time(),
autoRefresh: $this->autoRefresh,
refreshInterval: $this->refreshInterval,
executionTimeMs: 0,
dataPointsCount: $this->calculateDataPointsCount($chartData),
dataSource: $this->dataSource
);
}
/**
* Toggle auto-refresh
*/
public function withToggledAutoRefresh(): self
{
return new self(
chartType: $this->chartType,
chartData: $this->chartData,
dataRange: $this->dataRange,
lastUpdate: $this->lastUpdate,
autoRefresh: ! $this->autoRefresh,
refreshInterval: $this->refreshInterval,
executionTimeMs: $this->executionTimeMs,
dataPointsCount: $this->dataPointsCount,
dataSource: $this->dataSource
);
}
/**
* Calculate data points count from chart data
*/
private function calculateDataPointsCount(array $chartData): int
{
if (empty($chartData)) {
return 0;
}
return count($chartData['labels'] ?? []);
}
/**
* Check if has chart data
*/
public function hasChartData(): bool
{
return ! empty($this->chartData);
}
/**
* Get chart data as JSON
*/
public function getChartDataJson(): string
{
return ! empty($this->chartData) ? json_encode($this->chartData) : '{}';
}
/**
* Format last update timestamp
*/
public function getFormattedLastUpdate(): string
{
if ($this->lastUpdate === 0) {
return 'Noch nicht aktualisiert';
}
$diff = time() - $this->lastUpdate;
if ($diff < 60) {
return 'Gerade eben';
}
if ($diff < 3600) {
$minutes = floor($diff / 60);
return "Vor {$minutes} Minute" . ($minutes > 1 ? 'n' : '');
}
if ($diff < 86400) {
$hours = floor($diff / 3600);
return "Vor {$hours} Stunde" . ($hours > 1 ? 'n' : '');
}
return date('d.m.Y H:i', $this->lastUpdate);
}
/**
* Get auto-refresh status text
*/
public function getAutoRefreshText(): string
{
return $this->autoRefresh ? 'Auto-Refresh aktiv' : 'Auto-Refresh pausiert';
}
/**
* Get auto-refresh button text
*/
public function getAutoRefreshButtonText(): string
{
return $this->autoRefresh ? 'Pausieren' : 'Starten';
}
/**
* Get auto-refresh button CSS class
*/
public function getAutoRefreshButtonClass(): string
{
return $this->autoRefresh ? 'btn-warning' : 'btn-success';
}
/**
* Get data points text
*/
public function getDataPointsText(): string
{
if ($this->dataPointsCount === 0) {
return 'Keine Datenpunkte';
}
return $this->dataPointsCount === 1 ? '1 Datenpunkt' : "{$this->dataPointsCount} Datenpunkte";
}
/**
* Check if should show refresh button
*/
public function shouldShowRefreshButton(): bool
{
return ! $this->autoRefresh;
}
/**
* Check if should show performance metrics
*/
public function shouldShowPerformanceMetrics(): bool
{
return $this->executionTimeMs > 0;
}
/**
* Get chart container CSS class
*/
public function getChartContainerClass(): string
{
return 'chart-container chart-type-' . $this->chartType;
}
}