Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v24.14.1
v24.20.0
883 changes: 281 additions & 602 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"e2e": "playwright test",
"e2e:codegen": "playwright codegen http://localhost:4000",
"e2e:headed": "playwright test --project=chromium --debug --ignore-snapshots",
"e2e:ui": "npm run e2e -- --project=chromium --ui",
"e2e:update-snapshots": "playwright test --update-snapshots=changed",
"e2e:docker": "./tests/docker-scripts/run.sh web-ui-tests",
"e2e:update-ci-snapshots": "./tests/docker-scripts/run.sh web-ui-update-snapshots",
Expand Down Expand Up @@ -94,12 +95,10 @@
"@types/memoizee": "^0.4.5",
"@types/node": "^24.8.0",
"@types/papaparse": "5.3.2",
"@types/plotly.js": "^3.0.8",
"@types/pouchdb-browser": "^6.1.3",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react-is": "^18.3.1",
"@types/react-plotly.js": "^2.6.0",
"@types/react-router-dom": "^5.1.2",
"@types/react-transition-group": "^4.4.0",
"@types/react-virtualized-auto-sizer": "^1.0.1",
Expand Down
6 changes: 3 additions & 3 deletions packages/app-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"module": "dist/index.js",
"types": "dist/index.d.ts",
"engines": {
"node": ">=16"
"node": ">=22"
},
"scripts": {
"build": "cross-env NODE_ENV=production run-p build:*",
Expand Down Expand Up @@ -54,8 +54,8 @@
"lodash.throttle": "^4.1.1"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0",
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0",
"react-redux": "^7.x",
"redux": "^4.x"
},
Expand Down
11 changes: 5 additions & 6 deletions packages/chart/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"source": "src/index.js",
"types": "dist/index.d.ts",
"engines": {
"node": ">=16"
"node": ">=22"
Comment thread
mofojed marked this conversation as resolved.
},
"exports": {
".": "./dist/index.js",
Expand All @@ -39,17 +39,16 @@
"lodash": "^4.17.21",
"memoize-one": "^5.1.1",
"memoizee": "^0.4.15",
"plotly.js": "3.1.0",
"react-plotly.js": "^2.6.0"
"plotly.js": "4.1.1",
"react-plotly.js": "^4.1.0"
Comment thread
Copilot marked this conversation as resolved.
},
"peerDependencies": {
"react": ">=16.8.0"
"react": "^18.0.0 || ^19.0.0"
Comment thread
mofojed marked this conversation as resolved.
Comment thread
mofojed marked this conversation as resolved.
},
"devDependencies": {
"@deephaven/jsapi-shim": "file:../jsapi-shim",
"@deephaven/mocks": "file:../mocks",
"@deephaven/test-utils": "file:../test-utils",
"@types/plotly.js": "^3.0.0"
"@deephaven/test-utils": "file:../test-utils"
},
"files": [
"dist"
Expand Down
32 changes: 13 additions & 19 deletions packages/chart/src/Chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,18 @@ import {
type Config as PlotlyConfig,
type Layout,
type Icon,
type Data,
type PlotData,
type ModeBarButtonAny,
type PlotMouseEvent,
type PlotSelectionEvent,
type ClickAnnotationEvent,
type LegendClickEvent,
} from 'plotly.js';
import type { PlotParams } from 'react-plotly.js';
import type { Figure } from 'react-plotly.js';
import { mergeRefs } from '@deephaven/react-hooks';
import { bindAllMethods } from '@deephaven/utils';
import createPlotlyComponent from './plotly/createPlotlyComponent';
import Plotly from './plotly/Plotly';
import { type PlotData } from './plotly/plotlyTypes';
import ChartModel from './ChartModel';
import ChartErrorOverlay from './ChartErrorOverlay';
import { type ChartTheme } from './ChartTheme';
Expand Down Expand Up @@ -101,7 +100,7 @@ interface ChartContainerProps extends Partial<Omit<ChartProps, 'theme'>> {
}

interface ChartState {
data: Partial<Data>[] | null;
data: Partial<PlotData>[] | null;
/** An error specific to downsampling */
downsamplingError: unknown;
isDownsampleFinished: boolean;
Expand Down Expand Up @@ -267,9 +266,9 @@ class Chart extends Component<ChartProps, ChartState> {

currentSeries: number;

PlotComponent: React.ComponentType<PlotParams>;
PlotComponent: ReturnType<typeof createPlotlyComponent>;

plot: RefObject<typeof this.PlotComponent>;
plot: RefObject<HTMLDivElement>;

plotWrapper: RefObject<HTMLDivElement>;

Expand Down Expand Up @@ -304,7 +303,7 @@ class Chart extends Component<ChartProps, ChartState> {
isDownsampleFinished: boolean,
isDownsampleInProgress: boolean,
isDownsamplingDisabled: boolean,
data: Partial<Data>[],
data: Partial<PlotData>[],
error: unknown,
hasSelectionCallbacks: boolean
): Partial<PlotlyConfig> => {
Expand Down Expand Up @@ -505,7 +504,7 @@ class Chart extends Component<ChartProps, ChartState> {
layout.datarevision += 1;
}
return {
data: detail as Partial<Data>[] | null,
data: detail as Partial<PlotData>[] | null,
layout,
revision: revision + 1,
};
Expand Down Expand Up @@ -595,11 +594,11 @@ class Chart extends Component<ChartProps, ChartState> {
}
}

handlePlotUpdate(figure: Readonly<{ layout: Partial<Layout> }>): void {
handlePlotUpdate(figure: Readonly<Figure>): void {
// User could have modified zoom/pan here, update the model dimensions
// We don't need to update the datarevision, as we don't have any data changes
// until an update comes back from the server anyway
const { layout } = figure;
const layout = figure.layout as Partial<Layout>;
const ranges = ChartUtils.getLayoutRanges(layout);

const isRangesChanged = !deepEqual(ranges, this.ranges);
Expand Down Expand Up @@ -680,7 +679,7 @@ class Chart extends Component<ChartProps, ChartState> {
const { data } = this.state;
const { onSettingsChanged } = this.props;
if (data != null) {
const hiddenSeries = (data as Partial<PlotData>[]).reduce(
const hiddenSeries = data.reduce(
(acc: string[], { name, visible }) =>
name != null && visible === 'legendonly' ? [...acc, name] : acc,
[]
Expand Down Expand Up @@ -806,12 +805,9 @@ class Chart extends Component<ChartProps, ChartState> {
) {
// Call relayout to resize avoiding the debouncing plotly does
// https://github.com/plotly/plotly.js/issues/2769#issuecomment-402099552
PlotlyProp.relayout(
(this.plot.current as unknown as { el: HTMLElement }).el,
{
autosize: true,
}
).catch((e: unknown) => {
PlotlyProp.relayout(this.plot.current, {
autosize: true,
}).catch((e: unknown) => {
log.debug('Unable to resize, promise rejected', e);
});
}
Expand Down Expand Up @@ -885,8 +881,6 @@ class Chart extends Component<ChartProps, ChartState> {
<div className="h-100 w-100 chart-wrapper" ref={this.plotWrapperMerged}>
{isPlotShown && (
<PlotComponent
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
ref={this.plot}
data={data}
layout={layout}
Expand Down
5 changes: 3 additions & 2 deletions packages/chart/src/ChartModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@

import type { dh as DhType } from '@deephaven/jsapi-types';
import { type Formatter } from '@deephaven/jsapi-utils';
import type { Layout, Data } from 'plotly.js';
import type { Layout } from 'plotly.js';
import { type FilterColumnMap, type FilterMap } from './ChartUtils';
import { type PlotData } from './plotly/plotlyTypes';

export type ChartEvent = DhType.Event<unknown>;

Expand Down Expand Up @@ -73,7 +74,7 @@ class ChartModel {

title?: string;

getData(): Partial<Data>[] {
getData(): Partial<PlotData>[] {
return [];
}

Expand Down
46 changes: 27 additions & 19 deletions packages/chart/src/ChartUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ import type { dh as DhType } from '@deephaven/jsapi-types';
import { set } from 'lodash';
import type {
Layout,
PlotData,
PlotType,
Axis as PlotlyAxis,
ErrorBar,
LayoutAxis,
AxisType as PlotlyAxisType,
MarkerSymbol,
PolarLayout,
Scene,
Template,
Delta,
} from 'plotly.js';
import { assertNotNull, bindAllMethods, type Range } from '@deephaven/utils';
import { type ChartTheme } from './ChartTheme';
import { type PlotData } from './plotly/plotlyTypes';

export type FilterColumnMap = Map<
string,
Expand Down Expand Up @@ -94,7 +94,7 @@ interface Rangebreaks {
pattern?: 'day of week' | 'hour' | '';
values?: string[];
}
interface RangebreakAxisFormat extends PlotlyAxis {
interface RangebreakAxisFormat extends Omit<LayoutAxis, 'rangebreaks'> {
rangebreaks: Rangebreaks[];
}

Expand Down Expand Up @@ -133,9 +133,9 @@ function isDateTimeColumnFormatter(
function isRangedPlotlyAxis(value: unknown): value is { range: Range[] } {
return (
value != null &&
(value as PlotlyAxis).range != null &&
((value as PlotlyAxis).autorange === false ||
(value as PlotlyAxis).autorange === undefined)
(value as LayoutAxis).range != null &&
((value as LayoutAxis).autorange === false ||
(value as LayoutAxis).autorange === undefined)
);
}

Expand Down Expand Up @@ -290,10 +290,10 @@ class ChartUtils {
axisFormat: Partial<LayoutAxis> | null,
axis: DhType.plot.Axis,
isDateType: boolean
): Partial<PlotlyAxis> | null {
): Partial<LayoutAxis> | null {
const { gapBetweenMajorTicks } = axis;
if (gapBetweenMajorTicks != null && gapBetweenMajorTicks > 0) {
const updatedFormat: Partial<PlotlyAxis> = axisFormat || {};
const updatedFormat: Partial<LayoutAxis> = axisFormat || {};
let tickSpacing = gapBetweenMajorTicks;
if (isDateType) {
// Need to convert from nanoseconds to milliseconds
Expand Down Expand Up @@ -480,7 +480,7 @@ class ChartUtils {
const value = layout[key];
if (isRangedPlotlyAxis(value)) {
// Only want to add the range if it's not autoranged
ranges[key] = [...(value as PlotlyAxis).range];
ranges[key] = [...value.range];
}
}

Expand Down Expand Up @@ -649,7 +649,7 @@ class ChartUtils {
getAxisFormats(
figure: DhType.plot.Figure,
formatter: Formatter
): Map<LayoutAxisKey, Partial<PlotlyAxis>> {
): Map<LayoutAxisKey, Partial<LayoutAxis>> {
const axisFormats = new Map();
const nullFormat = { tickformat: null, ticksuffix: null };

Expand Down Expand Up @@ -1263,7 +1263,7 @@ class ChartUtils {
getPlotlyAxisFormat(
source: DhType.plot.SeriesDataSource,
formatter: Formatter | null = null
): Partial<PlotlyAxis> | null {
): Partial<LayoutAxis> | null {
const { dh } = this;
const { axis, columnType } = source;
const { formatPattern } = axis;
Expand Down Expand Up @@ -2109,10 +2109,10 @@ class ChartUtils {
delta: {
decreasing: {
color: indicator_decreasing,
} as Delta['increasing'],
},
increasing: {
color: indicator_increasing,
} as Delta['decreasing'],
},
},
gauge: { bar: { color: indicator_gauge } },
},
Expand Down Expand Up @@ -2173,15 +2173,23 @@ class ChartUtils {
margin: { ...ChartUtils.DEFAULT_MARGIN },
xaxis: this.makeLayoutAxis(dh.plot.AxisType.X, theme),
yaxis: this.makeLayoutAxis(dh.plot.AxisType.Y, theme),
// plotly types polar and scene axes separately from cartesian axes, but we
// share the same defaults; attributes that don't apply are ignored
polar: {
angularaxis: this.makeLayoutAxis(dh.plot.AxisType.SHAPE, theme),
radialaxis: this.makeLayoutAxis(dh.plot.AxisType.SHAPE, theme),
angularaxis: this.makeLayoutAxis(
dh.plot.AxisType.SHAPE,
theme
) as PolarLayout['angularaxis'],
radialaxis: this.makeLayoutAxis(
dh.plot.AxisType.SHAPE,
theme
) as PolarLayout['radialaxis'],
bgcolor: theme.plot_bgcolor,
},
scene: {
xaxis: this.makeLayoutAxis(dh.plot.AxisType.X, theme),
yaxis: this.makeLayoutAxis(dh.plot.AxisType.Y, theme),
zaxis: this.makeLayoutAxis(null, theme),
xaxis: this.makeLayoutAxis(dh.plot.AxisType.X, theme) as Scene['xaxis'],
yaxis: this.makeLayoutAxis(dh.plot.AxisType.Y, theme) as Scene['yaxis'],
zaxis: this.makeLayoutAxis(null, theme) as Scene['zaxis'],
},
geo: {
showcoastlines: true,
Expand Down
16 changes: 5 additions & 11 deletions packages/chart/src/FigureChartModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,7 @@ import { debounce, set } from 'lodash';
import type { dh as DhType } from '@deephaven/jsapi-types';
import Log from '@deephaven/log';
import { type Range } from '@deephaven/utils';
import type {
Annotations,
Layout,
Data,
PlotData,
XAxisName,
YAxisName,
} from 'plotly.js';
import type { Annotation, Layout, XAxisName, YAxisName } from 'plotly.js';
import {
TableUtils,
type DateTimeColumnFormatter,
Expand All @@ -28,6 +21,7 @@ import ChartUtils, {
type FilterColumnMap,
type FilterMap,
} from './ChartUtils';
import { type PlotData } from './plotly/plotlyTypes';

const log = Log.module('FigureChartModel');

Expand Down Expand Up @@ -93,7 +87,7 @@ class FigureChartModel extends ChartModel {

settings: Partial<ChartModelSettings>;

data: Partial<Data>[];
data: Partial<PlotData>[];

layout: Partial<Layout>;

Expand Down Expand Up @@ -174,7 +168,7 @@ class FigureChartModel extends ChartModel {
const yAxisIndex =
(axisTypeMap.get(yAxis.type)?.findIndex(a => a === yAxis) ?? 0) + 1;

const annotation: Partial<Annotations> = {
const annotation: Partial<Annotation> = {
align: 'center',
x: 0.5,
y: 1,
Expand Down Expand Up @@ -770,7 +764,7 @@ class FigureChartModel extends ChartModel {
}
}

getData(): Partial<Data>[] {
getData(): Partial<PlotData>[] {
return this.data;
}

Expand Down
Loading
Loading