Skip to content

Commit 3796eed

Browse files
Eduardo YapSkCQ
authored andcommitted
feat: Add 'Even X-Axis Spacing' toggle to chart settings
This change introduces a new toggle in the settings dialog of explore-simple-sk, allowing users to space X-axis points evenly, regardless of their numerical value. - Adds an md-switch for 'Even X-Axis Spacing' to the settings dialog template. - Updates plot-google-chart-sk's 'useDiscreteAxis' property when the toggle changes. - Dispatches an 'even-x-axis-spacing-changed' event with the new value and graph_index. - Updates explore-multi-sk and report-page-sk to listen for this event and synchronize the state across all child explore-simple-sk instances. - Adds unit tests for the new toggle and event handling in explore-simple-sk, explore-multi-sk, and report-page-sk. - Updates mock factories in tests to support necessary methods like setUseDiscreteAxis and render. Bug: 418808644 Change-Id: I9073bd5d4409ed288022e9b72dd921b8e256e8eb Reviewed-on: https://skia-review.googlesource.com/c/buildbot/+/1120909 Commit-Queue: Eduardo Yap <[email protected]> Reviewed-by: Tony Seaward <[email protected]>
1 parent 22e703c commit 3796eed

File tree

7 files changed

+277
-13
lines changed

7 files changed

+277
-13
lines changed

perf/modules/explore-multi-sk/explore-multi-sk.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ export class State {
110110
dayRange: number = -1;
111111

112112
dateAxis: boolean = false;
113+
114+
// boolean indicating if the chart should space x-axis points evenly, treating them as categories.
115+
evenXAxisSpacing: boolean = false;
113116
}
114117

115118
export class ExploreMultiSk extends ElementSk {
@@ -733,7 +736,8 @@ export class ExploreMultiSk extends ElementSk {
733736
id="graphContainer"
734737
@x-axis-toggled=${ele.syncXAxisLabel}
735738
@range-changing-in-multi=${ele.syncRange}
736-
@selection-changing-in-multi=${ele.syncChartSelection}></div>
739+
@selection-changing-in-multi=${ele.syncChartSelection}
740+
@even-x-axis-spacing-changed=${ele.syncEvenXAxisSpacing}></div>
737741
<pagination-sk
738742
offset=${ele.state.pageOffset}
739743
page_size=${ele.state.pageSize}
@@ -1339,6 +1343,25 @@ export class ExploreMultiSk extends ElementSk {
13391343
});
13401344
}
13411345

1346+
private syncEvenXAxisSpacing(e: CustomEvent): void {
1347+
const newValue = e.detail.value;
1348+
if (this.state.evenXAxisSpacing === newValue) {
1349+
return;
1350+
}
1351+
this.state.evenXAxisSpacing = newValue;
1352+
this.exploreElements.forEach((graph) => {
1353+
// Skip graph that sent the event.
1354+
if (graph.state.graph_index !== e.detail.graph_index) {
1355+
graph.state.evenXAxisSpacing = newValue;
1356+
graph.setUseDiscreteAxis(newValue);
1357+
graph.render();
1358+
}
1359+
});
1360+
if (this.stateHasChanged) {
1361+
this.stateHasChanged();
1362+
}
1363+
}
1364+
13421365
private addStateToExplore(
13431366
explore: ExploreSimpleSk,
13441367
graphConfig: GraphConfig,
@@ -1375,6 +1398,7 @@ export class ExploreMultiSk extends ElementSk {
13751398
hide_paramset: true,
13761399
graph_index: index,
13771400
doNotQueryData: doNotQueryData,
1401+
evenXAxisSpacing: this.state.evenXAxisSpacing,
13781402
};
13791403
explore.state = newState;
13801404
}

perf/modules/explore-multi-sk/explore-multi-sk_test.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,47 @@ describe('ExploreMultiSk', () => {
570570
});
571571
});
572572

573+
describe('Even X-Axis Spacing Sync', () => {
574+
beforeEach(async () => {
575+
await setupElement();
576+
// Add a couple of graphs for testing sync
577+
element['addEmptyGraph']();
578+
element['addEmptyGraph']();
579+
element['exploreElements'][0].state.graph_index = 0;
580+
element['exploreElements'][1].state.graph_index = 1;
581+
// Add to DOM for event propagation
582+
element['graphDiv']!.appendChild(element['exploreElements'][0]);
583+
element['graphDiv']!.appendChild(element['exploreElements'][1]);
584+
});
585+
586+
it('syncs enableDiscrete state to other graphs', async () => {
587+
const graph1 = element['exploreElements'][0];
588+
const graph2 = element['exploreElements'][1];
589+
590+
const spy1 = sinon.spy(graph1, 'setUseDiscreteAxis');
591+
const spy2 = sinon.spy(graph2, 'setUseDiscreteAxis');
592+
593+
// Simulate event from graph1
594+
const event = new CustomEvent('even-x-axis-spacing-changed', {
595+
detail: { value: true, graph_index: 0 },
596+
bubbles: true,
597+
});
598+
graph1.dispatchEvent(event);
599+
600+
assert.isTrue(element.state.evenXAxisSpacing, 'MultiSk state should be updated');
601+
assert.isTrue(spy1.notCalled, 'Source graph setUseDiscreteAxis should not be called by sync');
602+
assert.isTrue(spy2.calledOnceWith(true), 'Target graph setUseDiscreteAxis should be called');
603+
assert.isTrue(graph2.state.evenXAxisSpacing, 'Target graph state should be updated');
604+
});
605+
606+
it('initializes new graphs with the current enableDiscrete state', () => {
607+
element.state.evenXAxisSpacing = true;
608+
const newGraph = element['addEmptyGraph']()!;
609+
element['addStateToExplore'](newGraph, new GraphConfig(), false);
610+
assert.isTrue(newGraph.state.evenXAxisSpacing);
611+
});
612+
});
613+
573614
describe('Pagination', () => {
574615
beforeEach(async () => {
575616
await setupElement();
@@ -659,6 +700,7 @@ describe('ExploreMultiSk', () => {
659700
horizontal_zoom: false,
660701
graph_index: 0,
661702
doNotQueryData: false,
703+
evenXAxisSpacing: false,
662704
};
663705

664706
element['addStateToExplore'](simpleSk, new GraphConfig(), false);

perf/modules/explore-simple-sk/explore-simple-sk.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,9 @@ export class State {
364364

365365
// boolean indicating if the element should disable querying of data from backend.
366366
doNotQueryData: boolean = false;
367+
368+
// boolean indicating if the chart should space x-axis points evenly, treating them as categories.
369+
evenXAxisSpacing: boolean = false;
367370
}
368371

369372
// TODO(jcgregorio) Move to a 'key' module.
@@ -747,6 +750,17 @@ export class ExploreSimpleSk extends ElementSk implements KeyboardShortcutHandle
747750
Switch Zoom Direction
748751
</label>
749752
</li>
753+
<li>
754+
<label>
755+
<md-switch
756+
form="form"
757+
id="even-x-axis-spacing-switch"
758+
?selected="${ele._state.evenXAxisSpacing}"
759+
@change=${(e: InputEvent) =>
760+
ele.switchEvenXAxisSpacing(e.target as MdSwitch)}></md-switch>
761+
Even X-Axis Spacing
762+
</label>
763+
</li>
750764
</ul>
751765
</div>
752766
</md-dialog>
@@ -758,6 +772,7 @@ export class ExploreSimpleSk extends ElementSk implements KeyboardShortcutHandle
758772
.domain=${ele._state.domain}
759773
${ref(ele.googleChartPlot)}
760774
.highlightAnomalies=${ele._state.highlight_anomalies}
775+
.useDiscreteAxis=${ele._state.evenXAxisSpacing}
761776
@plot-data-select=${ele.onChartSelect}
762777
@plot-data-mouseover=${ele.onChartOver}
763778
@plot-data-mousedown=${ele.onChartMouseDown}
@@ -1578,6 +1593,26 @@ export class ExploreSimpleSk extends ElementSk implements KeyboardShortcutHandle
15781593
this.dispatchEvent(new CustomEvent('switch-zoom', { detail: detail, bubbles: true }));
15791594
}
15801595

1596+
private switchEvenXAxisSpacing(target: MdSwitch | null) {
1597+
if (!target) return;
1598+
this._state.evenXAxisSpacing = target.selected;
1599+
this.setUseDiscreteAxis(this._state.evenXAxisSpacing);
1600+
this.render();
1601+
this.dispatchEvent(
1602+
new CustomEvent('even-x-axis-spacing-changed', {
1603+
detail: { value: this._state.evenXAxisSpacing, graph_index: this._state.graph_index },
1604+
bubbles: true,
1605+
})
1606+
);
1607+
this._stateHasChanged();
1608+
}
1609+
1610+
public setUseDiscreteAxis(value: boolean) {
1611+
if (this.googleChartPlot.value) {
1612+
this.googleChartPlot.value.useDiscreteAxis = value;
1613+
}
1614+
}
1615+
15811616
private closeQueryDialog(): void {
15821617
this.queryDialog!.close();
15831618
this._dialogOn = false;

perf/modules/explore-simple-sk/explore-simple-sk_test.ts

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,3 +1192,82 @@ describe('Keyboard Shortcuts', () => {
11921192
assert.isTrue(tooltip.openExistingBug.calledOnce, 'e key should trigger openExistingBug');
11931193
});
11941194
});
1195+
1196+
describe('Even X-Axis Spacing toggle', () => {
1197+
let explore: ExploreSimpleSk;
1198+
let switchEl: MdSwitch;
1199+
let eventSpy: sinon.SinonSpy;
1200+
let setUseDiscreteAxisSpy: sinon.SinonSpy;
1201+
1202+
beforeEach(async () => {
1203+
fetchMock.get(/.*\/_\/initpage\/.*/, {
1204+
dataframe: { paramset: {} },
1205+
});
1206+
fetchMock.get('/_/login/status', {
1207+
1208+
roles: ['editor'],
1209+
});
1210+
setUseDiscreteAxisSpy = sinon.spy(ExploreSimpleSk.prototype, 'setUseDiscreteAxis');
1211+
explore = setUpElementUnderTest<ExploreSimpleSk>('explore-simple-sk')();
1212+
await waitForRender(explore);
1213+
const settingsDialog = explore.querySelector('#settings-dialog') as MdDialog;
1214+
switchEl = settingsDialog.querySelector('#even-x-axis-spacing-switch') as MdSwitch;
1215+
eventSpy = sinon.spy();
1216+
explore.addEventListener('even-x-axis-spacing-changed', eventSpy);
1217+
});
1218+
1219+
afterEach(() => {
1220+
setUseDiscreteAxisSpy.restore();
1221+
});
1222+
1223+
it('should have the switch element', () => {
1224+
assert.exists(switchEl);
1225+
});
1226+
1227+
it('should be unchecked by default', () => {
1228+
assert.isFalse(switchEl.selected);
1229+
assert.isFalse(explore.state.evenXAxisSpacing);
1230+
});
1231+
1232+
it('should update state and fire event when toggled on', async () => {
1233+
switchEl.selected = true;
1234+
switchEl.dispatchEvent(new Event('change'));
1235+
1236+
await waitForRender(explore);
1237+
1238+
assert.isTrue(explore.state.evenXAxisSpacing);
1239+
assert.isTrue(setUseDiscreteAxisSpy.calledOnceWith(true));
1240+
assert.isTrue(eventSpy.calledOnce);
1241+
1242+
const event = eventSpy.firstCall.args[0];
1243+
1244+
assert.equal(event.type, 'even-x-axis-spacing-changed');
1245+
assert.deepEqual(event.detail, { value: true, graph_index: 0 });
1246+
});
1247+
1248+
it('should update state and fire event when toggled off', async () => {
1249+
// Turn it on first
1250+
1251+
switchEl.selected = true;
1252+
switchEl.dispatchEvent(new Event('change'));
1253+
1254+
await waitForRender(explore);
1255+
1256+
eventSpy.resetHistory();
1257+
1258+
// Turn it off
1259+
switchEl.selected = false;
1260+
switchEl.dispatchEvent(new Event('change'));
1261+
1262+
await waitForRender(explore);
1263+
1264+
assert.isFalse(explore.state.evenXAxisSpacing);
1265+
assert.isTrue(setUseDiscreteAxisSpy.lastCall.calledWith(false));
1266+
assert.isTrue(eventSpy.calledOnce);
1267+
1268+
const event = eventSpy.firstCall.args[0];
1269+
1270+
assert.equal(event.type, 'even-x-axis-spacing-changed');
1271+
assert.deepEqual(event.detail, { value: false, graph_index: 0 });
1272+
});
1273+
});

perf/modules/plot-google-chart-sk/plot-google-chart-sk.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -280,12 +280,6 @@ export class PlotGoogleChartSk extends LitElement {
280280
constructor() {
281281
super();
282282
this.addEventListeners();
283-
// TODO(eduardoyap): Adding this for test purposes. Should be added as a toggle once
284-
// the feature is verified.
285-
const urlParams = new URLSearchParams(window.location.search);
286-
if (urlParams.get('enable_discrete') === 'true') {
287-
this.useDiscreteAxis = true;
288-
}
289283
}
290284

291285
connectedCallback(): void {

perf/modules/report-page-sk/report-page-sk.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ export class ReportPageSk extends ElementSk {
159159
@x-axis-toggled=${ele.syncXAxisLabel}
160160
@range-changing-in-multi=${ele.syncExtendRangeOnSummaryBar}
161161
@selection-changing-in-multi=${ele.syncChartSelection}
162+
@even-x-axis-spacing-changed=${ele.syncEvenXAxisSpacing}
162163
@open-anomaly-chart=${(e: CustomEvent<Anomaly>) =>
163164
ele.anomaliesTable!.openAnomalyChartListener(e)}></div>
164165
`;
@@ -479,6 +480,21 @@ export class ReportPageSk extends ElementSk {
479480
});
480481
}
481482

483+
// This ensures that all charts use the same x-axis type (continuous or discrete).
484+
private syncEvenXAxisSpacing(e: CustomEvent): void {
485+
const newValue = e.detail.value;
486+
const graphs = this.graphDiv!.querySelectorAll('explore-simple-sk');
487+
graphs.forEach((graphNode) => {
488+
const graph = graphNode as ExploreSimpleSk;
489+
// Skip graph that sent the event.
490+
if (graph.state.graph_index !== e.detail.graph_index) {
491+
graph.state.evenXAxisSpacing = newValue;
492+
graph.setUseDiscreteAxis(newValue);
493+
graph.render();
494+
}
495+
});
496+
}
497+
482498
// findRequestedAnomalies returns a list of requested anomaly objects .
483499
// This is for only loading selected untriaged anomaly graphs in the first place.
484500
findRequestedAnomalies(): Anomaly[] {

0 commit comments

Comments
 (0)