Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@
"scripts": {
"cs": "./vendor/bin/php-cs-fixer fix --dry-run --diff --config codestyle.php",
"csf": "./vendor/bin/php-cs-fixer fix --diff --config codestyle.php",
"test": "./vendor/bin/phpunit tests --colors always"
"test": "./vendor/bin/phpunit tests --colors=always"
}
}
58 changes: 42 additions & 16 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,23 @@ What's a heatmap? It is a data visualization technique that shows magnitude of a
![./docs/github.png](./docs/github.png)

### Installation
The Heatmap is distributed as Composer library via Packagist. To add it to your project, just run:
```
The Heatmap is distributed as Composer library via [Packagist](https://packagist.org/packages/blumilksoftware/heatmap). To add it to your project, execute the following command:

```bash
composer require blumilksoftware/heatmap
```

### Usage
You can use any set of data you want. By default, dates will be taken from `"created_at"` key of arrays or objects implementing `\ArrayAccess` interface. Builder accepts also objects implementing `\Blumilk\HeatmapBuilder\Contracts\TimeGroupable` contract with mandatory `getTimeGroupableIndicator()` method returning a string with proper date:

```php
$data = [
["created_at" => "2022-11-01 00:00:00", /** (...) */],
["created_at" => "2022-11-03 00:00:00", /** (...) */],
["created_at" => "2022-11-16 00:00:00", /** (...) */],
["created_at" => "2022-11-16 00:00:00", /** (...) */],
["created_at" => "2022-11-18 00:00:00", /** (...) */],
["created_at" => "2022-11-19 00:00:00", /** (...) */],
["created_at" => "2025-11-01 00:00:00", /** (...) */],
["created_at" => "2025-11-03 00:00:00", /** (...) */],
["created_at" => "2025-11-16 00:00:00", /** (...) */],
["created_at" => "2025-11-16 00:00:00", /** (...) */],
["created_at" => "2025-11-18 00:00:00", /** (...) */],
["created_at" => "2025-11-19 00:00:00", /** (...) */],
];
```

Expand All @@ -36,44 +38,68 @@ Method `build()` returns array of tiles that can be serialized into JSON with si
```json
[
{
"label": "2022-11-16",
"label": "2025-11-16",
"count": 2,
"description": ""
},
{
"label": "2022-11-17",
"label": "2025-11-17",
"count": 0,
"description": ""
},
{
"label": "2022-11-18",
"label": "2025-11-18",
"count": 1,
"description": ""
},
{
"label": "2022-11-19",
"label": "2025-11-19",
"count": 1,
"description": ""
},
{
"label": "2022-11-20",
"label": "2025-11-20",
"count": 0,
"description": ""
},
{
"label": "2022-11-21",
"label": "2025-11-21",
"count": 0,
"description": ""
},
{
"label": "2022-11-22",
"label": "2025-11-22",
"count": 0,
"description": ""
},
{
"label": "2022-11-23",
"label": "2025-11-23",
"count": 0,
"description": ""
}
]
```
### Customizing the Heatmap Builder watching period

By default, the `HeatmapBuilder` automatically sets its observation period to the last seven days if no custom period (`$period`) is provided during instantiation. This default behavior ensures a rolling seven-day view from the current day.

If you need to specify a custom period (e.g., the entire month of January), you can achieve this by explicitly passing a `CarbonPeriod` instance to the builder, as shown in the example below:

```php
// Define a custom period for the entire month of January 2025
$period = CarbonPeriod::create(
Carbon::parse('2025-01-01'),
'1 day',
Carbon::parse('2025-01-31')
);

// Instantiate the HeatmapBuilder with the custom period
$builder = new HeatmapBuilder(
now: Carbon::now(),
periodInterval: PeriodInterval::Daily,
period: $period // Include the custom period
);

// Generate the heatmap data
$result = $builder->build($data);
```
52 changes: 24 additions & 28 deletions src/PeriodActions.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,49 +8,45 @@

trait PeriodActions
{
private const UNIT_HOURS = "hours";
private const UNIT_DAYS = "days";
private const UNIT_WEEKS = "weeks";
private const UNIT_MONTH = "month";
private const UNIT_YEAR = "year";
private const UNIT_DECADE = "decade";
private const DEFAULT_TIME_UNIT_DURATION = 1;

public function forLastMonth(): static
{
$start = $this->now->copy()->subMonth();
$end = $this->now->copy();

$this->period = new CarbonPeriod($start, $this->periodInterval->value, $end);

return $this;
return $this->setPeriodFromDuration(self::DEFAULT_TIME_UNIT_DURATION, self::UNIT_MONTH);
}

public function forLastYear(): static
{
$start = $this->now->copy()->subYear();
$end = $this->now->copy();

$this->period = new CarbonPeriod($start, $this->periodInterval->value, $end);

return $this;
return $this->setPeriodFromDuration(self::DEFAULT_TIME_UNIT_DURATION, self::UNIT_YEAR);
}

public function forLastDecade(): static
{
$start = $this->now->copy()->subDecade();
$end = $this->now->copy();

$this->period = new CarbonPeriod($start, $this->periodInterval->value, $end);

return $this;
return $this->setPeriodFromDuration(self::DEFAULT_TIME_UNIT_DURATION, self::UNIT_DECADE);
}

public function forNumberOfTiles(int $number): static
{
$start = $this->now->copy()->sub(
$number,
match ($this->periodInterval) {
PeriodInterval::Hourly => "hours",
PeriodInterval::Daily => "days",
PeriodInterval::Weekly => "weeks",
PeriodInterval::Monthly => "months",
},
);
$end = $this->now->copy();
$unit = match ($this->periodInterval) {
PeriodInterval::Hourly => self::UNIT_HOURS,
PeriodInterval::Daily => self::UNIT_DAYS,
PeriodInterval::Weekly => self::UNIT_WEEKS,
PeriodInterval::Monthly => self::UNIT_MONTH,
};

return $this->setPeriodFromDuration($number, $unit);
}

protected function setPeriodFromDuration(int $duration, string $unit): static
{
$start = $this->now->copy()->sub($duration, $unit);
$end = $this->now->copy();
$this->period = new CarbonPeriod($start, $this->periodInterval->value, $end);

return $this;
Expand Down
Loading