Skip to content

Commit

Permalink
[Feat] Add scatter plot with fitted lines
Browse files Browse the repository at this point in the history
  • Loading branch information
lixun910 committed Jan 1, 2025
1 parent e8fa98c commit e2ec224
Show file tree
Hide file tree
Showing 27 changed files with 1,609 additions and 123 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module.exports = {
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module',
project: ['./tsconfig.json', './packages/*/tsconfig.json'],
project: ['./tsconfig.json', './packages/*/tsconfig.json', './storybook/tsconfig.json'],
tsconfigRootDir: __dirname,
},
plugins: ['@typescript-eslint', 'react', 'prettier'],
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"@langchain/google-genai": "^0.1.6",
"@langchain/ollama": "^0.1.4",
"@langchain/openai": "^0.3.16",
"react": "^18.2.0"
"react": "^18.3.1"
},
"files": [
"dist",
Expand Down
10 changes: 5 additions & 5 deletions packages/echarts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,21 @@
],
"dependencies": {
"echarts-for-react": "^3.0.2",
"jstat": "^1.9.6",
"next-themes": "^0.4.4",
"re-resizable": "^6.10.3",
"react-virtualized-auto-sizer": "^1.0.24"
"react-virtualized-auto-sizer": "^1.0.24",
"simple-statistics": "^7.8.7"
},
"devDependencies": {
"@openassistant/core": "^0.0.1",
"echarts": "^5.5.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tailwindcss": "^3.4.17"
},
"peerDependencies": {
"echarts": "^5.5.1",
"react": "^18 || ^19",
"react-dom": "^18 || ^19"
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"publishConfig": {
"access": "public"
Expand Down
44 changes: 44 additions & 0 deletions packages/echarts/src/common/resizable-container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Resizable } from "re-resizable";

export function ResizablePlotContainer({
children,
}: {
children: JSX.Element;
}) {
return (
<div className="w-full mt-4 mb-8">
<Resizable
defaultSize={{
width: '100%',
height: 280,
}}
minHeight={280}
maxHeight={600}
enable={{ bottom: true, bottomRight: true, right: false }}
handleComponent={{
bottomRight: (
<div className="group absolute bottom-0 right-0 h-6 w-6 cursor-se-resize">
<div className="flex h-full w-full items-center justify-center transition-colors hover:bg-gray-100/10">
<svg
width="12"
height="12"
viewBox="0 0 12 12"
className="text-gray-300 group-hover:text-gray-400"
>
<path
d="M11 6V11H6"
stroke="currentColor"
strokeWidth="2"
fill="none"
/>
</svg>
</div>
</div>
),
}}
>
{children}
</Resizable>
</div>
);
}
11 changes: 11 additions & 0 deletions packages/echarts/src/common/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* Formats a number to a more human-readable format, using compact notation
* @param value The number to format
* @returns The formatted number
*/
export const numericFormatter = (value: number): string => {
return Intl.NumberFormat('en-US', {
notation: 'compact',
maximumFractionDigits: 1,
}).format(value);
};
59 changes: 3 additions & 56 deletions packages/echarts/src/histogram-plot.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useMemo, useRef, useState } from 'react';
import { CustomFunctionCall } from '@openassistant/core';
import { EChartsOption } from 'echarts';
import { Resizable } from 're-resizable';
import ReactEChartsCore from 'echarts-for-react';
import AutoSizer from 'react-virtualized-auto-sizer';
import {
Expand All @@ -20,6 +19,8 @@ import { TopLevelFormatterParams } from 'echarts/types/dist/shared';
import { ECHARTS_DARK_THEME } from './echarts-theme';
import { HistogramOuputData } from './histogram';
import './index.css';
import { ResizablePlotContainer } from './common/resizable-container';
import { numericFormatter } from './common/utils';

echartsUse([
BarChart,
Expand All @@ -32,49 +33,6 @@ echartsUse([

echartsRegisterTheme('dark', ECHARTS_DARK_THEME);

export function ResizablePlotContainer({
children,
}: {
children: JSX.Element;
}) {
return (
<div className="w-full mt-4 mb-8">
<Resizable
defaultSize={{
width: '100%',
height: 280,
}}
minHeight={280}
maxHeight={600}
enable={{ bottom: true, bottomRight: true, right: false }}
handleComponent={{
bottomRight: (
<div className="group absolute bottom-0 right-0 h-6 w-6 cursor-se-resize">
<div className="flex h-full w-full items-center justify-center transition-colors hover:bg-gray-100/10">
<svg
width="12"
height="12"
viewBox="0 0 12 12"
className="text-gray-300 group-hover:text-gray-400"
>
<path
d="M11 6V11H6"
stroke="currentColor"
strokeWidth="2"
fill="none"
/>
</svg>
</div>
</div>
),
}}
>
{children}
</Resizable>
</div>
);
}

export function histogramCallbackMessage(
props: CustomFunctionCall
): JSX.Element | null {
Expand All @@ -89,6 +47,7 @@ export function HistogramComponent({
output,
}: CustomFunctionCall): JSX.Element | null {
const data = output.data as HistogramOuputData | undefined;

// get chart option by calling getChartOption only once
const option = useMemo(() => {
try {
Expand Down Expand Up @@ -191,18 +150,6 @@ export function HistogramComponent({
);
}

/**
* Formats a number to a more human-readable format, using compact notation
* @param value The number to format
* @returns The formatted number
*/
export const numericFormatter = (value: number): string => {
return Intl.NumberFormat('en-US', {
notation: 'compact',
maximumFractionDigits: 1,
}).format(value);
};

export type HistogramDataProps = {
bin: number;
binStart: number;
Expand Down
35 changes: 30 additions & 5 deletions packages/echarts/src/histogram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ import { histogramCallbackMessage, HistogramDataProps } from './histogram-plot';
* @param variableName - The name of the variable.
* @returns The values of the variable.
*/
export type GetValues = (datasetName: string, variableName: string) => number[];
type GetValues = (datasetName: string, variableName: string) => number[];

/**
* The callback function can be used to sync the selections of the histogram plot with the original dataset.
* @param datasetName - The name of the dataset.
* @param selectedIndices - The indices of the selected bars in the histogram plot.
*/
export type OnSelectedCallback = (
type OnSelectedCallback = (
datasetName: string,
selectedIndices: number[]
) => void;
Expand All @@ -29,6 +29,7 @@ export type OnSelectedCallback = (
* The context of the histogram function.
* @param getValues - Get the values of a variable from the dataset. See {@link GetValues} for more details.
* @param onSelected - The callback function can be used to sync the selections of the histogram plot with the original dataset. See {@link OnSelectedCallback} for more details.
* @param theme - The theme of the histogram plot. The possible values are 'light' and 'dark'.
*/
export type HistogramFunctionContext = {
getValues: GetValues;
Expand All @@ -40,7 +41,7 @@ type ValueOf<T> = T[keyof T];
type HistogramFunctionContextValues = ValueOf<HistogramFunctionContext>;

/**
* Define the histogram function. This function can assist user to create a histogram plot using the values of a variable in the dataset.
* Define the histogram function for tool calling. This function can assist user to create a histogram plot using the values of a variable in the dataset.
* The values should be retrieved using the getValues() callback function.
*
* User can select the bars in the histogram plot, and the selections can be synced back to the original dataset using the onSelected() callback.
Expand Down Expand Up @@ -103,6 +104,13 @@ type HistogramOutputResult =
details: string;
};

/**
* Type guard of HistogramFunctionArgs
*/
function isHistogramFunctionArgs(data: unknown): data is HistogramFunctionArgs {
return typeof data === 'object' && data !== null && 'datasetName' in data && 'variableName' in data;
}

function histogramCallbackFunction({
functionName,
functionArgs,
Expand All @@ -111,8 +119,18 @@ function histogramCallbackFunction({
HistogramOutputResult,
HistogramOuputData
> {
const { datasetName, variableName, numberOfBins } =
functionArgs as HistogramFunctionArgs;
if (!isHistogramFunctionArgs(functionArgs)) {
return {
type: 'error',
name: functionName,
result: {
success: false,
details: 'Invalid histogram function arguments.',
},
};
}

const { datasetName, variableName, numberOfBins } = functionArgs;

if (!datasetName || !variableName) {
return {
Expand Down Expand Up @@ -178,6 +196,13 @@ function histogramCallbackFunction({
}
}

/**
* Create histogram bins.
*
* @param values - The values of the variable.
* @param numberOfBins - The number of bins to create.
* @returns The histogram bins.
*/
function createHistogramBins(
values: number[],
numberOfBins: number = 5
Expand Down
2 changes: 2 additions & 0 deletions packages/echarts/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export * from './histogram';
export * from './histogram-plot';
export * from './scatterplot';
export * from './common/resizable-container';
Loading

0 comments on commit e2ec224

Please sign in to comment.