Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added bar overlap property for 2d bar charts #667

Merged
merged 8 commits into from
Aug 11, 2021
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 @@ -102,4 +104,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)
Progi1984 marked this conversation as resolved.
Show resolved Hide resolved

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)
Progi1984 marked this conversation as resolved.
Show resolved Hide resolved

#### 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 |
Progi1984 marked this conversation as resolved.
Show resolved Hide resolved

### 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