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

Update JpGraphRendererBase.php - check existing of PlotLabel #4074

Merged
merged 8 commits into from
Jun 30, 2024

Conversation

yfinkel
Copy link
Contributor

@yfinkel yfinkel commented Jun 26, 2024

I've got
Uncaught PHP Exception Symfony\Component\ErrorHandler\Error\FatalError: "Error: Uncaught Error: Call to a member function getDataValue() on bool in .../vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Renderer/JpGraphRendererBase.php:337

I found that it's necessary to check existing of PlotLabel before using its method getDataValue().

This is:

  • [x ] a bugfix
  • a new feature
  • refactoring
  • additional unit tests

Checklist:

  • Changes are covered by unit tests
    • Changes are covered by existing unit tests
    • New unit tests have been added
  • [ x] Code style is respected
  • [x ] Commit message explains why the change is made (see https://github.com/erlang/otp/wiki/Writing-good-commit-messages)
  • CHANGELOG.md contains a short summary of the change and a link to the pull request if applicable
  • Documentation is updated as necessary

Why this change is needed?

Provide an explanation of why this change is needed, with links to any Issues (if appropriate).
If this is a bugfix or a new feature, and there are no existing Issues, then please also create an issue that will make it easier to track progress with this PR.

I've got
Uncaught PHP Exception Symfony\Component\ErrorHandler\Error\FatalError: "Error: Uncaught Error: Call to a member function getDataValue() on bool in .../vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Renderer/JpGraphRendererBase.php:337

I found that it's necessary to check existing of PlotLabel before using its method getDataValue().
I'v got that:

Uncaught PHP Exception Symfony\Component\ErrorHandler\Error\FatalError: "Error: Uncaught Error: Call to a member function getDataValue() on bool in .../vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Renderer/JpGraphRendererBase.php:337

I've found that it's necessary to check existing of PlotLabel before using its method getDataValue().
$dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($index)->getDataValue();
if ($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($index)) {
$dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($index)->getDataValue();
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think seriesPlot->SetLegend($dataLabel) needs to be inside the if statement, otherwise dataLabel will not be defined.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, please add a unit test to demonstrate that there was a problem before your fix and you've fixed it.

@yfinkel
Copy link
Contributor Author

yfinkel commented Jun 26, 2024 via email

@oleibman
Copy link
Collaborator

oleibman commented Jun 27, 2024

Without an example, I am not completely unwilling to proceed, but I am a little reluctant. However, reworking your change will make me a little less reluctant.

There are 4 places in JpGraphRendererBase where dataLabel is set.

  • renderPlotLine, around line 337.
  • renderPlotBar, around line 411. This already tests for the situation you are trying to defend against, and I know that that situation is exercised in our unit test code.
  • renderPlotScatter, around line 495.
  • renderPlotRadar, around line 527.

If you were to make the code from renderPlotBar into a subroutine, and change each of these 4 instances to call the new subroutine instead of assigning a value to dataLabel directly, we would have some assurance that the other 3 are using code which is already tested. If you can confirm that the works in your case, I could proceed. As a bonus, we won't have to deal with the same situation for Radar and Scatter when someone comes across a similar situation with those in future. Something like (untested):

private function assignDataLabel(DataSeries $groupId, int $index): mixed
{
    if (!$this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($index)) {
        $dataLabel = '';
    } else {
        $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($index)->getDataValue();
    }

    return $dataLabel;
}

@yfinkel
Copy link
Contributor Author

yfinkel commented Jun 28, 2024

Well, I updated the code. The function name is getDataLabel(). It works well in my project. I will reappear only after a month, so do what you want with it. It's enough for me that it works for me.

@oleibman oleibman added this pull request to the merge queue Jun 30, 2024
Merged via the queue into PHPOffice:master with commit aae4992 Jun 30, 2024
13 checks passed
@oleibman
Copy link
Collaborator

Thank you for your contribution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

2 participants