Skip to content

Commit c420048

Browse files
committed
Add setLabelFont to Chart/Layout
Fix #4201. Although that issue can be dealt with without any change to PhpSpreadsheet, it is pretty clear that `setLabelFont` has been accidentally omitted from Chart/Layout. Add it now. Xlsx Chart Writer is changed to use font name from labelFont if latin, eastAsian, or complexScript is uninitialized. Finally, chart label font size is multiplied by 100 in Xlsx Writer, as it is in Excel, but the corresponding division by 100 has been omitted from Xlsx Chart Reader - add that now.
1 parent 8799a04 commit c420048

File tree

5 files changed

+124
-7
lines changed

5 files changed

+124
-7
lines changed

src/PhpSpreadsheet/Chart/Layout.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,13 @@ public function getLabelFont(): ?Font
450450
return $this->labelFont;
451451
}
452452

453+
public function setLabelFont(?Font $labelFont): self
454+
{
455+
$this->labelFont = $labelFont;
456+
457+
return $this;
458+
}
459+
453460
public function getLabelEffects(): ?Properties
454461
{
455462
return $this->labelEffects;

src/PhpSpreadsheet/Reader/Xlsx/Chart.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,6 +1192,9 @@ private function parseFont(SimpleXMLElement $titleDetailPart): ?Font
11921192
}
11931193
$fontArray = [];
11941194
$fontArray['size'] = self::getAttributeInteger($titleDetailPart->pPr->defRPr, 'sz');
1195+
if ($fontArray['size'] !== null && $fontArray['size'] >= 100) {
1196+
$fontArray['size'] /= 100.0;
1197+
}
11951198
$fontArray['bold'] = self::getAttributeBoolean($titleDetailPart->pPr->defRPr, 'b');
11961199
$fontArray['italic'] = self::getAttributeBoolean($titleDetailPart->pPr->defRPr, 'i');
11971200
$fontArray['underscore'] = self::getAttributeString($titleDetailPart->pPr->defRPr, 'u');
@@ -1305,6 +1308,10 @@ private function setChartAttributes(Layout $plotArea, array $plotAttributes): vo
13051308
case 'showLeaderLines':
13061309
$plotArea->setShowLeaderLines($plotAttributeValue);
13071310

1311+
break;
1312+
case 'labelFont':
1313+
$plotArea->setLabelFont($plotAttributeValue);
1314+
13081315
break;
13091316
}
13101317
}

src/PhpSpreadsheet/Style/Font.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@ class Font extends Supervisor
2020

2121
protected ?string $cap = null;
2222

23+
public const DEFAULT_FONT_NAME = 'Calibri';
24+
2325
/**
2426
* Font Name.
2527
*/
26-
protected ?string $name = 'Calibri';
28+
protected ?string $name = self::DEFAULT_FONT_NAME;
2729

2830
/**
2931
* The following 7 are used only for chart titles, I think.

src/PhpSpreadsheet/Writer/Xlsx/Chart.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1912,19 +1912,23 @@ private function writeLabelFont(XMLWriter $objWriter, ?Font $labelFont, ?Propert
19121912
$this->writeEffects($objWriter, $axisText);
19131913
}
19141914
if ($labelFont !== null) {
1915-
if (!empty($labelFont->getLatin())) {
1915+
$defaultFont = ($labelFont->getName() !== Font::DEFAULT_FONT_NAME) ? $labelFont->getName() : '';
1916+
$fontName = $labelFont->getLatin() ?: $defaultFont;
1917+
if (!empty($fontName)) {
19161918
$objWriter->startElement('a:latin');
1917-
$objWriter->writeAttribute('typeface', $labelFont->getLatin());
1919+
$objWriter->writeAttribute('typeface', $fontName);
19181920
$objWriter->endElement();
19191921
}
1920-
if (!empty($labelFont->getEastAsian())) {
1922+
$fontName = $labelFont->getEastAsian() ?: $defaultFont;
1923+
if (!empty($fontName)) {
19211924
$objWriter->startElement('a:eastAsian');
1922-
$objWriter->writeAttribute('typeface', $labelFont->getEastAsian());
1925+
$objWriter->writeAttribute('typeface', $fontName);
19231926
$objWriter->endElement();
19241927
}
1925-
if (!empty($labelFont->getComplexScript())) {
1928+
$fontName = $labelFont->getComplexScript() ?: $defaultFont;
1929+
if (!empty($fontName)) {
19261930
$objWriter->startElement('a:complexScript');
1927-
$objWriter->writeAttribute('typeface', $labelFont->getComplexScript());
1931+
$objWriter->writeAttribute('typeface', $fontName);
19281932
$objWriter->endElement();
19291933
}
19301934
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpOffice\PhpSpreadsheetTests\Chart;
6+
7+
use PhpOffice\PhpSpreadsheet\Chart\Chart;
8+
use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
9+
use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues;
10+
use PhpOffice\PhpSpreadsheet\Chart\Layout;
11+
use PhpOffice\PhpSpreadsheet\Chart\PlotArea;
12+
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
13+
use PhpOffice\PhpSpreadsheet\Spreadsheet;
14+
use PhpOffice\PhpSpreadsheet\Style\Font;
15+
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter;
16+
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
17+
18+
class Issue4201Test extends AbstractFunctional
19+
{
20+
public function readCharts(XlsxReader $reader): void
21+
{
22+
$reader->setIncludeCharts(true);
23+
}
24+
25+
public function writeCharts(XlsxWriter $writer): void
26+
{
27+
$writer->setIncludeCharts(true);
28+
}
29+
30+
public function testLabelFont(): void
31+
{
32+
$spreadsheet = new Spreadsheet();
33+
$worksheet = $spreadsheet->getActiveSheet();
34+
35+
// Sample data for pie chart
36+
$data = [
37+
['Category', 'Value'],
38+
['Category A', 40],
39+
['Category B', 30],
40+
['Category C', 20],
41+
['Category D', 10],
42+
];
43+
$worksheet->fromArray($data, null, 'A1');
44+
$worksheet->getColumnDimension('A')->setAutoSize(true);
45+
46+
// Create data series for the pie chart
47+
$categories = [new DataSeriesValues('String', 'Worksheet!$A$2:$A$5', null, 4)];
48+
$values = [new DataSeriesValues('Number', 'Worksheet!$B$2:$B$5', null, 4)];
49+
50+
// Set layout for data labels
51+
$font = new Font();
52+
$font->setName('Times New Roman');
53+
$font->setSize(8);
54+
$layout = new Layout();
55+
$layout->setShowVal(true); // Display values
56+
$layout->setShowCatName(true); // Display category names
57+
$layout->setLabelFont($font);
58+
59+
$series = new DataSeries(
60+
DataSeries::TYPE_PIECHART, // Chart type: Pie chart
61+
null,
62+
range(0, count($values) - 1),
63+
[],
64+
$categories,
65+
$values
66+
);
67+
68+
$plotArea = new PlotArea($layout, [$series]);
69+
$chart = new Chart('Pie Chart', null, null, $plotArea);
70+
$chart->setTopLeftPosition('A7');
71+
$chart->setBottomRightPosition('H20');
72+
$worksheet->addChart($chart);
73+
74+
/** @var callable */
75+
$callableReader = [$this, 'readCharts'];
76+
/** @var callable */
77+
$callableWriter = [$this, 'writeCharts'];
78+
$reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx', $callableReader, $callableWriter);
79+
$spreadsheet->disconnectWorksheets();
80+
81+
$sheet = $reloadedSpreadsheet->getActiveSheet();
82+
$charts = $sheet->getChartCollection();
83+
self::assertCount(1, $charts);
84+
$chart2 = $charts[0];
85+
self::assertNotNull($chart2);
86+
$plotArea2 = $chart2->getPlotArea();
87+
self::assertNotNull($plotArea2);
88+
$layout2 = $plotArea2->getLayout();
89+
self::assertNotNull($layout2);
90+
$font2 = $layout2->getLabelFont();
91+
self::assertNotNull($font2);
92+
self::assertSame('Times New Roman', $font2->getLatin());
93+
self::assertSame(8.0, $font2->getSize());
94+
95+
$reloadedSpreadsheet->disconnectWorksheets();
96+
}
97+
}

0 commit comments

Comments
 (0)