Skip to content

Commit

Permalink
Merge pull request #667 from mindline-analytics/feat-bar-overlap
Browse files Browse the repository at this point in the history
Added bar overlap property for 2d bar charts
  • Loading branch information
Progi1984 authored Aug 11, 2021
2 parents 3ed8e2b + 0022f5b commit 6a57c84
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 23 deletions.
4 changes: 3 additions & 1 deletion docs/changes/1.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
- PowerPoint2007 Reader : Load images in their initial format (and not by default in PNG) - [@polidog](https://github.com/polidog) GH-553

## Features
- Support for bar overlap in 2D bar charts - [@mindline](https://github.com/mindline-analytics) GH-667
- PowerPoint2007 Writer
- Support for the position of Legend in ODPresentation Writer - [@Progi1984](https://github.com/Progi1984) GH-355
- Support for DoughnutChart - [@Progi1984](https://github.com/Progi1984) GH-355
- ODPresentation Writer
Expand Down Expand Up @@ -104,4 +106,4 @@
* `PhpOffice\PhpPresentation\Writer\PowerPoint2007\LayoutPack\PackDefault`
* Removed class
* `PhpOffice\PhpPresentation\Writer\PowerPoint2007\LayoutPack\TemplateBased`
* Removed class
* Removed class
Binary file added docs/images/chart_bar_overlap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 29 additions & 16 deletions docs/usage/shapes/chart.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ $chartShape = $slide->createChartShape();

You can define how blank values are displayed with the method `setDisplayBlankAs`.

![Slideshow type](/images/libreoffice_chart_displayblankas.png)
![Slideshow type](../../images/libreoffice_chart_displayblankas.png)

Differents types are available:

Expand Down Expand Up @@ -321,16 +321,37 @@ TODO

#### Gap Width

You can define the gap width between bar or columns clusters. It is defined in percent.
You can define the gap width between bar or columns clusters. It is relatively defined as percentage of a bars width.
The default value is 150%. The value must be defined between 0 and 500.

``` php
```php
<?php

$barChart = new Bar();
$barChart->setGapWidthPercent(250);
```

#### Overlap

You can define the bar overlap within bar or column clusters. It is relatively defined as percentage of a bars width.
The default value is `100%` for stacked and `0%` for grouped bar charts. The value must be defined between `-100` and `100`.

When setting the bar grouping type, the default overlap values will be set. Any change to the overlap must be made after setting the bar grouping type through `setBarGrouping`.

```php
$barChart = new Bar();
// will set the overlap to the default value for grouped bars: 0
$barChart->setBarGrouping(Bar::GROUPING_CLUSTERED);

// a positive value will result in an overlapping
$barChart->setOverlapWidthPercent(25);

// a negative value will result in a gap
$barChart->setOverlapWidthPercent(-25);
```

![Bar Overlap](../../images/chart_bar_overlap.png)

#### Stacking

You can stack multiples series in a same chart. After adding multiples series, you can define the bar grouping with `setBarGrouping` method of AbstractTypeBar.
Expand All @@ -349,18 +370,11 @@ $barChart->setBarGrouping(Bar::GROUPING_STACKED);
$barChart->setBarGrouping(Bar::GROUPING_PERCENTSTACKED);
```

- Bar::GROUPING_CLUSTERED

![Bar::GROUPING_CLUSTERED](/images/chart_columns_52x60.png)

- Bar::GROUPING_STACKED

![Bar::GROUPING_STACKED](/images/chart_columnstack_52x60.png)

- Bar::GROUPING_PERCENTSTACKED

![Bar::GROUPING_PERCENTSTACKED](/images/chart_columnpercent_52x60.png)

| | Type | Constant |
| --------------------------------------------------------------------------- | ------------ | ---------------------------- |
| ![Bar::GROUPING_CLUSTERED](../../images/chart_columns_52x60.png) | Grouped Bars | Bar::GROUPING_CLUSTERED |
| ![Bar::GROUPING_STACKED](../../images/chart_columnstack_52x60.png) | Stacked Bars | Bar::GROUPING_STACKED |
| ![Bar::GROUPING_PERCENTSTACKED](../../images/chart_columnpercent_52x60.png) | Grouped Bars | Bar::GROUPING_PERCENTSTACKED |

### Line

Expand Down Expand Up @@ -418,4 +432,3 @@ $chart->setIsSmooth(false);
// Get status of smooth line
$chart->isSmooth();
```

39 changes: 39 additions & 0 deletions src/PhpPresentation/Shape/Chart/Type/AbstractTypeBar.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ class AbstractTypeBar extends AbstractType
*/
protected $gapWidthPercent = 150;

/**
* Overlap within bar or columns clusters. Value between 100 and -100 percent.
* For stacked bar charts, the default overlap will be 100, for grouped bar charts 0.
*
* @var int
*/
protected $overlapWidthPercent = 0;

/**
* Set bar orientation.
*
Expand Down Expand Up @@ -87,6 +95,11 @@ public function getBarDirection()
public function setBarGrouping($value = self::GROUPING_CLUSTERED)
{
$this->barGrouping = $value;
$this->overlapWidthPercent = 0;

if ($value === self::GROUPING_STACKED || $value === self::GROUPING_PERCENTSTACKED) {
$this->overlapWidthPercent = 100;
}

return $this;
}
Expand Down Expand Up @@ -127,6 +140,32 @@ public function setGapWidthPercent($gapWidthPercent)
return $this;
}

/**
* @return int
*/
public function getOverlapWidthPercent(): int
{
return $this->overlapWidthPercent;
}

/**
* @param int $value overlap width percentage
*
* @return self
*/
public function setOverlapWidthPercent(int $value): self
{
if ($value < -100) {
$value = -100;
}
if ($value > 100) {
$value = 100;
}
$this->overlapWidthPercent = $value;

return $this;
}

/**
* Get hash code.
*
Expand Down
7 changes: 1 addition & 6 deletions src/PhpPresentation/Writer/PowerPoint2007/PptCharts.php
Original file line number Diff line number Diff line change
Expand Up @@ -985,13 +985,8 @@ protected function writeTypeBar(XMLWriter $objWriter, Bar $subject, bool $includ
$objWriter->endElement();

// c:overlap
$barGrouping = $subject->getBarGrouping();
$objWriter->startElement('c:overlap');
if (Bar::GROUPING_CLUSTERED === $barGrouping) {
$objWriter->writeAttribute('val', '0');
} elseif (Bar::GROUPING_STACKED === $barGrouping || Bar::GROUPING_PERCENTSTACKED === $barGrouping) {
$objWriter->writeAttribute('val', '100');
}
$objWriter->writeAttribute('val', $subject->getOverlapWidthPercent());
$objWriter->endElement();

// c:axId
Expand Down
26 changes: 26 additions & 0 deletions tests/PhpPresentation/Tests/Shape/Chart/Type/BarTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,32 @@ public function testGapWidthPercent(): void
$this->assertEquals(500, $object->getGapWidthPercent());
}

public function testOverlapWidthPercentDefaults(): void
{
$object = new Bar();
$this->assertEquals(0, $object->getOverlapWidthPercent());

$object->setBarGrouping(Bar::GROUPING_STACKED);
$this->assertEquals(100, $object->getOverlapWidthPercent());
$object->setBarGrouping(Bar::GROUPING_CLUSTERED);
$this->assertEquals(0, $object->getOverlapWidthPercent());
$object->setBarGrouping(Bar::GROUPING_PERCENTSTACKED);
$this->assertEquals(100, $object->getOverlapWidthPercent());
}

public function testOverlapWidthPercent(): void
{
$value = mt_rand(-100, 100);
$object = new Bar();
$this->assertEquals(0, $object->getOverlapWidthPercent());
$this->assertInstanceOf(Bar::class, $object->setOverlapWidthPercent($value));
$this->assertEquals($value, $object->getOverlapWidthPercent());
$this->assertInstanceOf(Bar::class, $object->setOverlapWidthPercent(101));
$this->assertEquals(100, $object->getOverlapWidthPercent());
$this->assertInstanceOf(Bar::class, $object->setOverlapWidthPercent(-101));
$this->assertEquals(-100, $object->getOverlapWidthPercent());
}

public function testHashCode(): void
{
$oSeries = new Series();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,7 @@ public function testTypeBar(): void
$oShape->setResizeProportional(false)->setHeight(550)->setWidth(700)->setOffsetX(120)->setOffsetY(80);
$oBar = new Bar();
$oBar->setGapWidthPercent($valueGapWidthPercent);
$oBar->setOverlapWidthPercent(-10);
$oSeries = new Series('Downloads', $this->seriesData);
$oSeries->getDataPointFill(0)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color(Color::COLOR_BLUE));
$oSeries->getDataPointFill(1)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color(Color::COLOR_DARKBLUE));
Expand All @@ -603,6 +604,8 @@ public function testTypeBar(): void
$this->assertZipXmlElementEquals('ppt/charts/' . $oShape->getIndexedFilename(), $element, $oSeries->getTitle());
$element = '/c:chartSpace/c:chart/c:plotArea/c:barChart/c:gapWidth';
$this->assertZipXmlAttributeEquals('ppt/charts/' . $oShape->getIndexedFilename(), $element, 'val', $valueGapWidthPercent);
$element = '/c:chartSpace/c:chart/c:plotArea/c:barChart/c:overlap';
$this->assertZipXmlAttributeEquals('ppt/charts/' . $oShape->getIndexedFilename(), $element, 'val', $oBar->getOverlapWidthPercent());

$this->assertIsSchemaECMA376Valid();
}
Expand Down

0 comments on commit 6a57c84

Please sign in to comment.