Skip to content

Commit 9aa396b

Browse files
authored
fix(heatmap): adjust pageSize based available chart height (#849)
1 parent 9ebd879 commit 9aa396b

13 files changed

Lines changed: 333 additions & 106 deletions

.playground/playground.tsx

Lines changed: 130 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,133 @@ import React from 'react';
2222
import { Chart, Heatmap, HeatmapConfig, RecursivePartial, ScaleType, Settings } from '../src';
2323
import { HeatmapSpec } from '../src/chart_types/heatmap/specs';
2424
import { BABYNAME_DATA } from '../src/utils/data_samples/babynames';
25-
import { SWIM_LANE_DATA } from '../src/utils/data_samples/test_anomaly_swim_lane';
2625

26+
export const SWIM_LANE_DATA = [
27+
{
28+
laneLabel: 'Overall',
29+
time: 1572825600,
30+
value: 0,
31+
},
32+
{
33+
laneLabel: 'Overall',
34+
time: 1572829200,
35+
value: 0,
36+
},
37+
{
38+
laneLabel: 'Overall',
39+
time: 1572832800,
40+
value: 0,
41+
},
42+
{
43+
laneLabel: 'Overall',
44+
time: 1572836400,
45+
value: 0,
46+
},
47+
{
48+
laneLabel: 'Overall',
49+
time: 1572840000,
50+
value: 0,
51+
},
52+
{
53+
laneLabel: 'Overall',
54+
time: 1572843600,
55+
value: 1.066358,
56+
},
57+
{
58+
laneLabel: 'Overall',
59+
time: 1572847200,
60+
value: 1.813946,
61+
},
62+
{
63+
laneLabel: 'Overall',
64+
time: 1572850800,
65+
value: 0,
66+
},
67+
{
68+
laneLabel: 'Overall',
69+
time: 1572854400,
70+
value: 0.05191579,
71+
},
72+
{
73+
laneLabel: 'Overall',
74+
time: 1572858000,
75+
value: 1.63678,
76+
},
77+
{
78+
laneLabel: 'Overall',
79+
time: 1572861600,
80+
value: 2.031104,
81+
},
82+
{
83+
laneLabel: 'Overall',
84+
time: 1572865200,
85+
value: 0,
86+
},
87+
{
88+
laneLabel: 'Overall',
89+
time: 1572868800,
90+
value: 1.09738,
91+
},
92+
{
93+
laneLabel: 'Overall',
94+
time: 1572872400,
95+
value: 0,
96+
},
97+
{
98+
laneLabel: 'Overall',
99+
time: 1572876000,
100+
value: 0.2232534,
101+
},
102+
{
103+
laneLabel: 'Overall',
104+
time: 1572879600,
105+
value: 19.49729,
106+
},
107+
{
108+
laneLabel: 'Overall',
109+
time: 1572883200,
110+
value: 34.10214,
111+
},
112+
{
113+
laneLabel: 'Overall',
114+
time: 1572886800,
115+
value: 0,
116+
},
117+
{
118+
laneLabel: 'Overall',
119+
time: 1572890400,
120+
value: 55.18972,
121+
},
122+
{
123+
laneLabel: 'Overall',
124+
time: 1572894000,
125+
value: 0.9794427671013135,
126+
},
127+
{
128+
laneLabel: 'Overall',
129+
time: 1572897600,
130+
value: 1.2711643855082817,
131+
},
132+
{
133+
laneLabel: 'Overall',
134+
time: 1572901200,
135+
value: 0.12110509647944609,
136+
},
137+
{
138+
laneLabel: 'Overall',
139+
time: 1572904800,
140+
value: 0.9807310648820486,
141+
},
142+
{
143+
laneLabel: 'Overall',
144+
time: 1572908400,
145+
value: 1.0793822204067567,
146+
},
147+
];
27148
export class Playground extends React.Component<any, { highlightedData?: HeatmapSpec['highlightedData'] }> {
28149
constructor(props: any) {
29150
super(props);
30-
this.state = {
31-
highlightedData: {
32-
x: [1572908400000, 1572910200000],
33-
y: ['i-ca80c01a'],
34-
},
35-
};
151+
this.state = {};
36152
}
37153

38154
onBrushEnd: HeatmapConfig['onBrushEnd'] = (e) => {
@@ -46,8 +162,7 @@ export class Playground extends React.Component<any, { highlightedData?: Heatmap
46162
const heatmapConfig: RecursivePartial<HeatmapConfig> = {
47163
grid: {
48164
cellHeight: {
49-
min: 20,
50-
max: 20, // 'fill',
165+
max: 30,
51166
},
52167
stroke: {
53168
width: 1,
@@ -65,20 +180,16 @@ export class Playground extends React.Component<any, { highlightedData?: Heatmap
65180
strokeWidth: 0,
66181
},
67182
},
68-
brushArea: {
69-
fill: 'red',
70-
},
71183
yAxisLabel: {
72184
name: 'instance',
73185
visible: true,
74-
width: { max: 50 },
75-
padding: 5,
76-
fill: '#6a717d',
77-
},
78-
xAxisLabel: {
79-
fill: '#6a717d',
186+
width: 170,
187+
// eui color subdued
188+
fill: `#6a717d`,
189+
padding: 8,
80190
},
81191
onBrushEnd: this.onBrushEnd,
192+
maxLegendHeight: 20,
82193
};
83194
console.log(
84195
BABYNAME_DATA.filter(([year]) => year > 1950).map((d) => {
@@ -87,7 +198,7 @@ export class Playground extends React.Component<any, { highlightedData?: Heatmap
87198
);
88199
return (
89200
<div>
90-
<div className="chart" style={{ height: '500px', overflow: 'auto' }}>
201+
<div className="chart" style={{ height: '88px', overflow: 'auto' }}>
91202
<Chart>
92203
<Settings
93204
onElementClick={console.log}

api/charts.api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,8 @@ export interface HeatmapConfig {
832832
// (undocumented)
833833
maxColumnWidth: Pixels;
834834
// (undocumented)
835+
maxLegendHeight?: number;
836+
// (undocumented)
835837
maxRowHeight: Pixels;
836838
// Warning: (ae-forgotten-export) The symbol "HeatmapBrushEvent" needs to be exported by the entry point index.d.ts
837839
//
Loading

src/chart_types/heatmap/layout/types/config_types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ export interface Config {
103103
stroke: Color;
104104
};
105105
};
106+
maxLegendHeight?: number;
106107
}
107108

108109
export type HeatmapBrushEvent = {

src/chart_types/heatmap/layout/viewmodel/grid.ts

Lines changed: 0 additions & 37 deletions
This file was deleted.

src/chart_types/heatmap/layout/viewmodel/viewmodel.ts

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import { stringToRGB } from '../../../partition_chart/layout/utils/color_library
3131
import { HeatmapSpec } from '../../specs';
3232
import { HeatmapTable } from '../../state/selectors/compute_chart_dimensions';
3333
import { ColorScaleType } from '../../state/selectors/get_color_scale';
34+
import { GridHeightParams } from '../../state/selectors/get_grid_full_height';
3435
import { Config } from '../types/config_types';
3536
import {
3637
Cell,
@@ -39,7 +40,6 @@ import {
3940
PickHighlightedArea,
4041
ShapeViewModel,
4142
} from '../types/viewmodel_types';
42-
import { getGridCellHeight } from './grid';
4343

4444
export interface HeatmapCellDatum {
4545
x: string | number;
@@ -84,11 +84,11 @@ export function shapeViewModel(
8484
heatmapTable: HeatmapTable,
8585
colorScale: ColorScaleType,
8686
filterRanges: Array<[number, number | null]>,
87+
{ height, pageSize }: GridHeightParams,
8788
): ShapeViewModel {
8889
const gridStrokeWidth = config.grid.stroke.width ?? 1;
8990

90-
const { table, yValues } = heatmapTable;
91-
const { xDomain } = heatmapTable;
91+
const { table, yValues, xDomain } = heatmapTable;
9292

9393
// measure the text width of all rows values to get the grid area width
9494
const boxedYValues = yValues.map<Box & { value: string | number }>((value) => {
@@ -99,26 +99,13 @@ export function shapeViewModel(
9999
};
100100
});
101101

102-
const maxGridAreaWidth = chartDimensions.width;
103-
const maxGridAreaHeight = chartDimensions.height;
104-
105-
// compute the grid cell height
106-
const gridCellHeight = getGridCellHeight(yValues, config);
107-
const maxHeight = gridCellHeight * yValues.length;
108-
109-
// compute the pageSize: how many rows can be fitted into the current panel height
110-
const pageSize: number =
111-
gridCellHeight > 0 && maxHeight > maxGridAreaHeight
112-
? Math.floor(maxGridAreaHeight / gridCellHeight)
113-
: yValues.length;
114-
115102
// compute the scale for the rows positions
116103
const yScale = scaleBand<string | number>()
117104
.domain(yValues)
118-
.range([0, maxHeight]);
105+
.range([0, height]);
119106

120107
const yInvertedScale = scaleQuantize<string | number>()
121-
.domain([0, maxHeight])
108+
.domain([0, height])
122109
.range(yValues);
123110

124111
let xValues = xDomain.domain;
@@ -129,7 +116,7 @@ export function shapeViewModel(
129116
{
130117
type: ScaleType.Time,
131118
domain: xDomain.domain,
132-
range: [0, maxGridAreaWidth],
119+
range: [0, chartDimensions.width],
133120
},
134121
{
135122
ticks: getTicks(chartDimensions.width, config.xAxisLabel),
@@ -152,10 +139,10 @@ export function shapeViewModel(
152139
// compute the scale for the columns positions
153140
const xScale = scaleBand<string | number>()
154141
.domain(xValues)
155-
.range([0, maxGridAreaWidth]);
142+
.range([0, chartDimensions.width]);
156143

157144
const xInvertedScale = scaleQuantize<string | number>()
158-
.domain([0, maxGridAreaWidth])
145+
.domain([0, chartDimensions.width])
159146
.range(xValues);
160147

161148
// compute the cell width (can be smaller then the available size depending on config
@@ -370,22 +357,22 @@ export function shapeViewModel(
370357
const width = endFromScale - startFromScale + (isOutOfRange ? cellWidth : 0);
371358

372359
// resolve Y coordinated making sure the order is correct
373-
const { y: yStart, height } = y.reduce(
360+
const { y: yStart, totalHeight } = y.reduce(
374361
(acc, current, i) => {
375362
if (i === 0) {
376363
acc.y = yScale(current) || 0;
377364
}
378-
acc.height += cellHeight;
365+
acc.totalHeight += cellHeight;
379366
return acc;
380367
},
381-
{ y: 0, height: 0 },
368+
{ y: 0, totalHeight: 0 },
382369
);
383370

384371
return {
385372
x: xStart,
386373
y: yStart,
387374
width,
388-
height,
375+
height: totalHeight,
389376
};
390377
};
391378

src/chart_types/heatmap/renderer/canvas/connected_component.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ import { bindActionCreators, Dispatch } from 'redux';
2323

2424
import { onChartRendered } from '../../../../state/actions/chart';
2525
import { GlobalChartState } from '../../../../state/chart_state';
26-
import { getChartContainerDimensionsSelector } from '../../../../state/selectors/get_chart_container_dimensions';
2726
import { getInternalIsInitializedSelector, InitStatus } from '../../../../state/selectors/get_internal_is_intialized';
2827
import { Dimensions } from '../../../../utils/dimensions';
2928
import { nullShapeViewModel, ShapeViewModel } from '../../layout/types/viewmodel_types';
3029
import { geometries } from '../../state/selectors/geometries';
30+
import { getHeatmapContainerSizeSelector } from '../../state/selectors/get_heatmap_container_size';
3131
import { renderCanvas2d } from './canvas_renderers';
3232

3333
interface ReactiveChartStateProps {
@@ -145,7 +145,7 @@ const mapStateToProps = (state: GlobalChartState): ReactiveChartStateProps => {
145145
return {
146146
initialized: true,
147147
geometries: geometries(state),
148-
chartContainerDimensions: getChartContainerDimensionsSelector(state),
148+
chartContainerDimensions: getHeatmapContainerSizeSelector(state),
149149
};
150150
};
151151

0 commit comments

Comments
 (0)