Browse Source

feat(ui): Add header value to release comparison chart (#27268)

Matej Minar 3 years ago
parent
commit
e1c80fb45a

+ 13 - 0
static/app/components/charts/styles.tsx

@@ -69,6 +69,19 @@ export const HeaderTitleLegend = styled(HeaderTitle)`
   z-index: 1;
 `;
 
+// Used for rendering total value of a chart right below the HeaderTitleLegend
+export const HeaderValue = styled('div')`
+  display: inline-grid;
+  grid-auto-flow: column;
+  grid-gap: ${space(1)};
+  align-items: baseline;
+  background-color: ${p => p.theme.background};
+  position: absolute;
+  top: 40px;
+  z-index: 1;
+  font-size: ${p => p.theme.headerFontSize};
+`;
+
 export const ChartContainer = styled('div')`
   padding: ${space(2)} ${space(3)};
 `;

+ 15 - 4
static/app/views/releases/detail/overview/releaseComparisonChart/index.tsx

@@ -30,7 +30,7 @@ import {defined, percent} from 'app/utils';
 import {decodeScalar} from 'app/utils/queryString';
 import {getCount, getCrashFreeRate, getCrashFreeSeries} from 'app/utils/sessions';
 import {Color, Theme} from 'app/utils/theme';
-import {displayCrashFreePercent} from 'app/views/releases/utils';
+import {displayCrashFreeDiff, displayCrashFreePercent} from 'app/views/releases/utils';
 
 import {generateReleaseMarkLines, releaseComparisonChartLabels} from '../../utils';
 import {
@@ -126,7 +126,7 @@ function ReleaseComparisonChart({
         ? displayCrashFreePercent(allCrashFreeSessions)
         : null,
       diff: defined(diffCrashFreeSessions)
-        ? `${Math.abs(round(diffCrashFreeSessions, 3))}%`
+        ? displayCrashFreeDiff(diffCrashFreeSessions, releaseCrashFreeSessions)
         : null,
       diffDirection: diffCrashFreeSessions
         ? diffCrashFreeSessions > 0
@@ -148,7 +148,7 @@ function ReleaseComparisonChart({
         ? displayCrashFreePercent(allCrashFreeUsers)
         : null,
       diff: defined(diffCrashFreeUsers)
-        ? `${Math.abs(round(diffCrashFreeUsers, 3))}%`
+        ? displayCrashFreeDiff(diffCrashFreeUsers, releaseCrashFreeUsers)
         : null,
       diffDirection: diffCrashFreeUsers ? (diffCrashFreeUsers > 0 ? 'up' : 'down') : null,
       diffColor: diffCrashFreeUsers
@@ -287,8 +287,9 @@ function ReleaseComparisonChart({
   }
 
   const {series, previousSeries, markLines} = getSeries(activeChart);
+  const chart = charts.find(ch => ch.type === activeChart);
 
-  if (errored) {
+  if (errored || !chart) {
     return (
       <Panel>
         <ErrorPanel>
@@ -310,6 +311,15 @@ function ReleaseComparisonChart({
               previousSeries={previousSeries ?? []}
               chartType={activeChart}
               platform={platform}
+              value={chart.thisRelease}
+              diff={
+                <Change color={defined(chart.diffColor) ? chart.diffColor : undefined}>
+                  {chart.diff}{' '}
+                  {defined(chart.diffDirection) && (
+                    <IconArrow direction={chart.diffDirection} size="xs" />
+                  )}
+                </Change>
+              }
             />
           </TransitionChart>
         </ChartContainer>
@@ -413,6 +423,7 @@ const ChartToggle = styled('label')`
 `;
 
 const Change = styled('div')<{color?: Color}>`
+  font-size: ${p => p.theme.fontSizeLarge};
   ${p => p.color && `color: ${p.theme[p.color]}`}
 `;
 

+ 10 - 3
static/app/views/releases/detail/overview/releaseComparisonChart/sessionsChart.tsx

@@ -3,7 +3,7 @@ import {withTheme} from '@emotion/react';
 
 import AreaChart from 'app/components/charts/areaChart';
 import StackedAreaChart from 'app/components/charts/stackedAreaChart';
-import {HeaderTitleLegend} from 'app/components/charts/styles';
+import {HeaderTitleLegend, HeaderValue} from 'app/components/charts/styles';
 import QuestionTooltip from 'app/components/questionTooltip';
 import {PlatformKey} from 'app/data/platformCategories';
 import {ReleaseComparisonChartType} from 'app/types';
@@ -20,6 +20,8 @@ type Props = {
   previousSeries: Series[];
   chartType: ReleaseComparisonChartType;
   platform: PlatformKey;
+  value: React.ReactNode;
+  diff: React.ReactNode;
 };
 
 class SessionsChart extends React.Component<Props> {
@@ -76,7 +78,7 @@ class SessionsChart extends React.Component<Props> {
   }
 
   render() {
-    const {series, previousSeries, chartType} = this.props;
+    const {series, previousSeries, chartType, value, diff} = this.props;
 
     const Chart = this.getChart();
 
@@ -102,6 +104,10 @@ class SessionsChart extends React.Component<Props> {
           )}
         </HeaderTitleLegend>
 
+        <HeaderValue>
+          {value} {diff}
+        </HeaderValue>
+
         <Chart
           legend={legend}
           series={series}
@@ -111,12 +117,13 @@ class SessionsChart extends React.Component<Props> {
           grid={{
             left: '10px',
             right: '10px',
-            top: '40px',
+            top: '70px',
             bottom: '0px',
           }}
           yAxis={this.configureYAxis()}
           tooltip={{valueFormatter: this.formatTooltipValue}}
           transformSinglePointToBar
+          height={240}
         />
       </React.Fragment>
     );

+ 11 - 0
static/app/views/releases/utils/index.tsx

@@ -48,6 +48,17 @@ export const displayCrashFreePercent = (
   return `${rounded}\u0025`;
 };
 
+export const displayCrashFreeDiff = (
+  diffPercent: number,
+  crashFreePercent?: number | null
+) =>
+  `${Math.abs(
+    round(
+      diffPercent,
+      crashFreePercent && crashFreePercent > CRASH_FREE_DECIMAL_THRESHOLD ? 3 : 0
+    )
+  ).toLocaleString()}\u0025`;
+
 export const getReleaseNewIssuesUrl = (
   orgSlug: string,
   projectId: string | number | null,