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

Fix for charts with side-by-side grouping (Bar/Area plots) #1883

Open
wants to merge 33 commits into
base: xdmod11.0
Choose a base branch
from

Conversation

aestoltm
Copy link
Contributor

@aestoltm aestoltm commented Jul 15, 2024

Risk: MEDIUM
Notes on Risk: These changes affect Area/Bar plots due to both of these making use of the stacking feature. Minor changes to trace ordering which affects every plot. The change on trace ordering should be lower risk because the zIndex is not being used due to layering being currently disabled.

Severity: MEDIUM/HIGH
Notes on Severity: Depending on the units of the data and if the data sources are from the same realm or not the plot has misplaced traces, due to wrongful stacking (instead of side-by-side). See attached plots.

Description

Side by side bar charts were broken when comparing time-series data from two different realms.

Before Fix:
Screenshot from 2024-07-15 12-05-24
After Fix:
Screenshot from 2024-07-15 12-05-39

Found an additional bug with legend ordering w/ trendline and error bars enabled:
Before:
Screenshot from 2024-07-15 16-19-28
After:
Screenshot from 2024-07-15 16-19-41

Motivation and Context

Fixes time-series grouped (side by side) bar charts.

Tests performed

Tested on dev and tested grouped bar charts with data from the same realm to check for regressions

Checklist:

  • The pull request description is suitable for a Changelog entry
  • The milestone is set correctly on the pull request
  • The appropriate labels have been added to the pull request

@aestoltm aestoltm added bug Bugfixes Category:Metric Explorer Metric Explorer / Usage labels Jul 15, 2024
@aestoltm aestoltm requested a review from aaronweeden July 15, 2024 16:08
@aestoltm aestoltm changed the title Bar chart fix Fix for charts wtih grouping (Bar/Area plots) Jul 15, 2024
@aestoltm aestoltm changed the title Fix for charts wtih grouping (Bar/Area plots) Fix for charts with side-by-side grouping (Bar/Area plots) Jul 15, 2024
@aestoltm aestoltm added this to the 11.0.1 milestone Oct 2, 2024
@aestoltm aestoltm modified the milestones: 11.0.1, 11.0.2 Oct 4, 2024
@aestoltm
Copy link
Contributor Author

aestoltm commented Nov 12, 2024

Comment to explain some of the proposed changes:

Note: The term trace and data series are used interchangeably.

classes/DataWarehouse/Visualization/TimeseriesChart.php: There are two changes made within this file. First, updating the offsetgroup to correctly have different offset values for data series within the same yAxis object. The second change made was to use a counter value to determine the data series position within the plot and legend. Previously, the data series location was dependent on $traceIndex which is a data series index of a $yAxisDataObject. There a few issues with this approach. We want to put supplemental data series behind the primary data series within the data series array passed to Plotly (due to Plotly drawing objects based on the array ordering) therefore, $traceIndex does not work because supplement traces will be placed before the next series' primary trace. Additionally, I discovered that multi axis plots had incorrect ordering due to each yAxis having the same ordering due to different $yAxisDataObject's for each yAxis. Therefore, I decided it would be better to use a counter called $legendRank. This name may not be the most accurate due to it also being used for the data series location within both the plot and the legend. However, this counter increments by 2 each trace independent of which $yAxisDataObject the trace is assoicated with. The reason this counter increments by 2 is to accommodate the error and trendline supplemental data series. The error trace will be behind the primary trace and the trendline is two spots behind the primary trace. You can view that without these proposed changes that multi axis plots have incorrect ordering and the legend ranking when error and trendline series are enabled is incorrect. With the proposed changes, these are corrected. Also if you view the ordering of the data array passed to Plotly in PlotlyChartWrapper.js you can see that the order is how I described above (primary trace in front with supplemental behind) with the addition that null traces are at the beginning of the data array because I chose to put them behind every other trace.

classes/DataWarehouse/Access/Usage.php: I removed the previous code which added a counter within the array_walk. I noticed that because $legendRank is incremented by two we can calculate the trace's rank within the Usage tab by dividing by 2. I also changed how we check if we are looking at a primary trace or supplemental trace by adding a metadata flag as @jpwhite4 suggested.

@@ -894,7 +894,7 @@ public function configure(
// for each of the dataseries on this yAxisObject:
foreach($yAxisObject->series as $data_description_index => $yAxisDataObjectAndDescription)
{
$legendRank += 2;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note there is no trendline series for aggregate charts therefore this was supposed to increment by 1.

@aestoltm aestoltm changed the base branch from main to xdmod11.0 November 22, 2024 19:00
@@ -848,7 +845,7 @@ function ($drillTarget) {
&& $chartSortedByValue
&& $usageGroupBy !== 'none'
) {
$rank = $meDataSeries['legendrank']+1;
$rank = $meDataSeries['legendrank'] / 2;
Copy link
Member

Choose a reason for hiding this comment

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

We've had problems in the past using floats because their representation changes between php and js versions.

Is $rank supposed to be an int? is it guaranteed to be an int?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I need to take another look at this. It doesn't seem to be guaranteed to be an int at the moment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

$rank here is guaranteed to be an int after taking a closer look. This is only run when the series is a part of a timeseries plot and it is based off a variable we control, $legendRank.

During my investigation I noticed I was incrementing the $legendRank off by one. However, it was not noticeable because any series with a "tied" $legendRank would be broken by the fact that one of the traces came later in the data array passed with the plot. Therefore, I reverted the refactor to the Aggregate chart $legendRank I did last week and I put the timeseries $legendRank to increment by 3 (because we have the primary trace and two possible supplemental traces).

… notice on the plot because the next series (and its supplements plots) are placed later in the data array so I believe Plotly was placing them later in the legend for the same reason
@aestoltm aestoltm requested a review from jpwhite4 December 13, 2024 21:02
@@ -97,10 +97,9 @@ XDMoD.utils.createChart = function (chartOptions, extraHandlers) {
// for comparison idea
baseChartOptions.data.sort((trace1, trace2) => {
if (baseChartOptions.layout.barmode !== 'group') {
return Math.sign(trace2.zIndex - trace1.zIndex) || Math.sign(trace2.traceorder - trace1.traceorder);
return Math.sign(trace2.traceorder - trace1.traceorder);
Copy link
Member

Choose a reason for hiding this comment

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

Please change this if to explicitly check for a column bar chart (rather than not == group which will match scatter plots and pie charts too).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This should be addressed.

For the trendline code that contained the ternaries, it seems that having the valid check was unnecessary. Nothing breaks when the log scale and std error bars are enabled with the trendline series. I need to start working on a few refactor PRs for Plotly because I saw a few cases where we can refactor barmode (only need for bar charts shouldn't be default on every chart) and allowing log scale with error bars (haven't found any reason why it shouldn't be allowed, I can look back on the git blame and try to find a reason)

@aestoltm
Copy link
Contributor Author

aestoltm commented Jan 2, 2025

Correcting the order of the trendline with the other series (primary and error) exposes the out-of-order timeseries bug that was introduced in PR #1899 . Therefore, I may need to get PR #1960 to merged first to fix that issue before merging this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Bugfixes Category:Metric Explorer Metric Explorer / Usage
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants