Skip to content

Commit

Permalink
improve plot selection
Browse files Browse the repository at this point in the history
  • Loading branch information
ritch committed Sep 4, 2024
1 parent 3ab7f5b commit c2f30fa
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 2 deletions.
2 changes: 1 addition & 1 deletion app/packages/app/src/useEvents/useEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const useEvents = (
return {
subscriptions,
handler: useCallback((event: string, payload: string) => {
if (event === "ping") {
if (event === "ping" || event === "") {
return;
}

Expand Down
47 changes: 46 additions & 1 deletion app/packages/core/src/plugins/SchemaIO/components/PlotlyView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,30 @@ import { HeaderView } from ".";
import { getComponentProps } from "../utils";
import { ViewPropsType } from "../utils/types";

type TraceWithIds = {
name?: string;
ids?: string[];
};

function getIdForTrace(
point: Plotly.Point,
trace: TraceWithIds,
options: { is2DArray?: boolean } = {}
) {
const { is2DArray = false } = options;
const { data } = point;
const { x, y, z } = data;
if (trace?.ids) {
if (is2DArray) {
const [xIdx, yIdx] = point.pointIndex;
return trace.ids[yIdx][xIdx];
} else {
return trace.ids[point.pointIndex];
}
}
return null;
}

export default function PlotlyView(props: ViewPropsType) {
const { data, schema, path, relativeLayout } = props;
const { view = {} } = schema;
Expand All @@ -23,10 +47,12 @@ export default function PlotlyView(props: ViewPropsType) {
const data = EventDataMappers[event]?.(e) || {};
let xValue = null;
let yValue = null;
let zValue = null;
let value;
let label;
let id = null;

if (event === "onClick") {
const values = e.points[0];
let selected = [];
let xBinsSize = null;
for (const p of e.points) {
Expand All @@ -49,10 +75,12 @@ export default function PlotlyView(props: ViewPropsType) {
} else if (type === "heatmap") {
xValue = p.x;
yValue = p.y;
zValue = p.z;
} else if (type === "pie") {
value = p.v;
label = p.label;
}
id = getIdForTrace(p, fullData, { is2DArray: type === "heatmap" });
}
if (selected.length === 0) {
selected = null;
Expand All @@ -61,30 +89,44 @@ export default function PlotlyView(props: ViewPropsType) {

const eventHandlerOperator = view[snakeCase(event)];
const defaultParams = {
id,
path: props.path,
relative_path: props.relativePath,
schema: props.schema,
view,
event,
value,
label,
shift_pressed: Boolean(e?.event?.shiftKey),
};

if (eventHandlerOperator) {
let params = {};
if (event === "onClick") {
const eventData = e as Plotly.PlotMouseEvent;
params = {
...defaultParams,
range,
x: xValue,
y: yValue,
z: zValue,
idx: e.points[0].pointIndex,
trace: eventData.points[0].data.name,
trace_idx: eventData.points[0].curveNumber,
value,
label,
};
} else if (event === "onSelected") {
params = {
...defaultParams,
data,
path,
};
} else {
params = {
...defaultParams,
data,
};
}

triggerPanelEvent(panelId, {
Expand Down Expand Up @@ -235,6 +277,7 @@ const EventDataMappers = {
const result = {
...pointdata,
data: metadata,
trace: fullData.name,
};
return result;
},
Expand All @@ -245,6 +288,8 @@ const EventDataMappers = {
const { data, fullData, xaxis, yaxis, ...pointdata } = point;
const { x, y, z, ids, selectedpoints, ...metadata } = data;
selected.push({
trace: fullData.name,
trace_idx: point.curveNumber,
idx: point.pointIndex,
id: Array.isArray(ids) ? ids[point.pointIndex] : null,
x: Array.isArray(x) ? x[point.pointIndex] : null,
Expand Down
41 changes: 41 additions & 0 deletions fiftyone/operators/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -1483,10 +1483,51 @@ class PlotlyView(View):
See https://github.com/plotly/react-plotly.js/#basic-props for
documentation.
Examples::
def render(self, ctx):
panel.plot("my_plot", on_click=self.on_click, on_selected=self.on_selected)
def print_params(self, ctx, params):
for key, value in params.items():
ctx.print(f"{key}: {value}")
def on_click(self, ctx):
# available params
self.print_prams(ctx, {
"id": "id", # the corresponding data.ids[idx]
"idx": 1, # the index of the clicked point
"label": "label", # label (eg. on pie charts)
"shift_pressed": false, # whether the shift key was pressed
"trace": "my_trace", # data[trace_idx].name
"trace_idx": 0,
"value": "my_value", # data[trace_idx].values[idx] (eg. on a pie chart)
"x": 2, # data[trace_idx].x[idx] (the x value on most plot types)
"y": 3, # data[trace_idx].y[idx] (the y value on most plot types)
"z": 4, # data[trace_idx].z[idx] (the z value on 3d plots eg. heatmap)
})
def on_selected(self, ctx):
prin(ctx.params['data'])
# [
# {
# "trace": "trace 0", # data[trace_idx].name
# "trace_idx": 0, # the index of the trace
# "idx": 1, # the index of the selected point
# "id": "one", # the corresponding data.ids[idx]
# "x": 2, # the x value of the selected point
# "y": 15, # the y value of the selected point
# "z": 22 # the z value of the selected point
# }
# ]
Args:
data (None): the chart data
config (None): the chart config
layout (None): the chart layout
on_click (None): event handler for click events
on_selected (None): event handler for selected events
on_double_click (None): event handler for double click events
"""

def __init__(self, **kwargs):
Expand Down

0 comments on commit c2f30fa

Please sign in to comment.