Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: streamlit add new component: filter renderer #415

Merged
merged 1 commit into from
Feb 2, 2024
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
124 changes: 68 additions & 56 deletions app/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { IRow, IGWHandler, IViewField } from '@kanaries/graphic-walker/dist/inte
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";

import Options from './components/options';
import { IAppProps, IGraphicRendererProps } from './interfaces';
import { IAppProps } from './interfaces';

import { loadDataSource, postDataService, finishDataService, getDatasFromKernelBySql, getDatasFromKernelByPayload } from './dataSource';

Expand Down Expand Up @@ -154,54 +154,46 @@ const App: React.FC<IAppProps> = observer((props) => {

return (
<React.StrictMode>
<div className={`${isDark ? "dark": ""} bg-background text-foreground`}>
<style>{style}</style>
<Notification />
<UploadSpecModal />
<UploadChartModal gwRef={gwRef} storeRef={storeRef} open={uploadChartModalOpen} setOpen={setUploadChartModalOpen} dark={props.dark} />
<CodeExportModal open={exportOpen} setOpen={setExportOpen} globalStore={storeRef} sourceCode={props["sourceInvokeCode"] || ""} />
<Select onValueChange={modeChange} defaultValue='walker' >
<SelectTrigger className="w-[140px] h-[30px] mb-[20px] text-xs">
<span className='text-muted-foreground'>Mode: </span>
<SelectValue className='' placeholder="Mode" />
</SelectTrigger>
<SelectContent className={isDark ? "dark": ""}>
<SelectItem value="walker">Walker</SelectItem>
<SelectItem value="renderer">Renderer</SelectItem>
</SelectContent>
</Select>
{
mode === "walker" ?
<GraphicWalker
{...props.extraConfig}
dark={props.dark}
themeKey={props.themeKey}
hideDataSourceConfig={props.hideDataSourceConfig}
fieldkeyGuard={props.fieldkeyGuard}
rawFields={props.rawFields}
dataSource={props.useKernelCalc ? undefined : dataSource}
storeRef={storeRef}
ref={gwRef}
toolbar={toolbarConfig}
computation={computationCallback}
enhanceAPI={enhanceAPI}
chart={visSpec.length === 0 ? undefined : visSpec}
experimentalFeatures={{ computedField: props.useKernelCalc }}
defaultConfig={ props.useKernelCalc ? { config: { timezoneDisplayOffset: 0 } } : undefined}
/> :
<GraphicRendererApp
rawFields={props.rawFields}
themeKey={props.themeKey}
dark={props.dark}
dataSource={props.useKernelCalc ? undefined : dataSource as any}
computation={computationCallback}
useKernelCalc={props.useKernelCalc}
charts={visSpec}
/>
}
<InitModal />
<Options {...props} />
</div>
<Notification />
<UploadSpecModal />
<UploadChartModal gwRef={gwRef} storeRef={storeRef} open={uploadChartModalOpen} setOpen={setUploadChartModalOpen} dark={props.dark} />
<CodeExportModal open={exportOpen} setOpen={setExportOpen} globalStore={storeRef} sourceCode={props["sourceInvokeCode"] || ""} />
<Select onValueChange={modeChange} defaultValue='walker' >
<SelectTrigger className="w-[140px] h-[30px] mb-[20px] text-xs">
<span className='text-muted-foreground'>Mode: </span>
<SelectValue className='' placeholder="Mode" />
</SelectTrigger>
<SelectContent className={isDark ? "dark": ""}>
<SelectItem value="walker">Walker</SelectItem>
<SelectItem value="renderer">Renderer</SelectItem>
</SelectContent>
</Select>
{
mode === "walker" ?
<GraphicWalker
{...props.extraConfig}
dark={props.dark}
themeKey={props.themeKey}
hideDataSourceConfig={props.hideDataSourceConfig}
fieldkeyGuard={props.fieldkeyGuard}
rawFields={props.rawFields}
dataSource={props.useKernelCalc ? undefined : dataSource}
storeRef={storeRef}
ref={gwRef}
toolbar={toolbarConfig}
computation={computationCallback}
enhanceAPI={enhanceAPI}
chart={visSpec.length === 0 ? undefined : visSpec}
experimentalFeatures={{ computedField: props.useKernelCalc }}
defaultConfig={ props.useKernelCalc ? { config: { timezoneDisplayOffset: 0 } } : undefined}
/> :
<GraphicRendererApp
{...props}
visSpec={visSpec}
/>
}
<InitModal />
<Options {...props} />
</React.StrictMode>
);
})
Expand All @@ -212,7 +204,6 @@ const PureRednererApp: React.FC<IAppProps> = observer((props) => {

return (
<React.StrictMode>
<style>{style}</style>
<PureRenderer
{...props.extraConfig}
name={spec.name}
Expand Down Expand Up @@ -245,7 +236,7 @@ const initOnJupyter = async(props: IAppProps) => {
const initOnHttpCommunication = async(props: IAppProps) => {
const comm = initHttpCommunication(props.id, props.communicationUrl);
communicationStore.setComm(comm);
if (props.gwMode === "explore" && props.needLoadLastSpec) {
if ((props.gwMode === "explore" || props.gwMode === "filter_renderer") && props.needLoadLastSpec) {
const visSpecResp = await comm.sendMsg("get_latest_vis_spec", {});
props.visSpec = visSpecResp["data"]["visSpec"];
}
Expand All @@ -272,8 +263,27 @@ function GWalker(props: IAppProps, id: string) {
}

preRender(props).then(() => {
let component = <App {...props} />;
switch(props.gwMode) {
case "explore":
component = <App {...props} />;
break;
case "renderer":
component = <PureRednererApp {...props} />;
break;
case "filter_renderer":
component = <GraphicRendererApp {...props} />;
break;
default:
component = <App {...props} />
}
const isDark = currentMediaTheme(props.dark) === "dark";

ReactDOM.render(
props.gwMode === "explore" ? <App {...props} /> : <PureRednererApp {...props} />,
<div className={`${isDark ? "dark": ""} bg-background text-foreground`}>
<style>{style}</style>
{component}
</div>,
document.getElementById(id)
);
})
Expand All @@ -293,18 +303,20 @@ function ChartPreviewApp(props: IChartPreviewProps, id: string) {
);
}

function GraphicRendererApp(props: IGraphicRendererProps) {
function GraphicRendererApp(props: IAppProps) {
const computationCallback = getComputationCallback(props);

return (
<React.StrictMode>
<Tabs defaultValue="0" className="w-full">
<div className="overflow-x-auto max-w-full">
<TabsList>
{props.charts.map((chart, index) => {
{props.visSpec.map((chart, index) => {
return <TabsTrigger key={index} value={index.toString()}>{chart.name}</TabsTrigger>
})}
</TabsList>
</div>
{props.charts.map((chart, index) => {
{props.visSpec.map((chart, index) => {
return <TabsContent key={index} value={index.toString()}>
{
props.useKernelCalc ?
Expand All @@ -313,7 +325,7 @@ function GraphicRendererApp(props: IGraphicRendererProps) {
containerStyle={{ height: "600px", width: "60%" }}
themeKey={props.themeKey}
dark={props.dark}
computation={props.computation!}
computation={computationCallback!}
chart={[chart]}
/> :
<GraphicRenderer
Expand Down
13 changes: 1 addition & 12 deletions app/src/interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export interface IAppProps {
useSaveTool: boolean;
parseDslType: "server" | "client";
communicationUrl: string;
gwMode: "explore" | "renderer";
gwMode: "explore" | "renderer" | "filter_renderer";
needLoadLastSpec: boolean;
extraConfig?: any;
fieldMetas: any;
Expand All @@ -41,14 +41,3 @@ export interface IUserConfig {
[key: string]: any;
privacy: 'events' | 'update-only' | 'offline';
}


export interface IGraphicRendererProps {
themeKey: IThemeKey;
dark: IDarkMode;
dataSource?: IRow[];
rawFields: IMutField[];
charts: any;
useKernelCalc: boolean;
computation?: IComputationFunction;
}
16 changes: 13 additions & 3 deletions pygwalker/api/streamlit.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
from pygwalker._typing import DataFrame
from pygwalker.utils.randoms import rand_str
from pygwalker.services.streamlit_components import render_explore_modal_button
from pygwalker.services.global_var import GlobalVarManager

if TYPE_CHECKING:
from streamlit.delta_generator import DeltaGenerator
Expand Down Expand Up @@ -124,7 +123,7 @@ def _get_html_with_params_str_cache(self, params_str: str) -> str:
def _get_html(
self,
*,
mode: Literal["explore", "renderer"] = "explore",
mode: Literal["explore", "renderer", "filter_renderer"] = "explore",
vis_spec: Optional[List[Dict[str, Any]]] = None,
**kwargs: Dict[str, Any]
) -> str:
Expand Down Expand Up @@ -174,6 +173,16 @@ def set_global_pre_filters(self, pre_filters: List[PreFilter]):
"""It will append new filters to exists charts."""
self.global_pre_filters = pre_filters

def render_filter_renderer(
self,
width: int = 1300,
height: int = 1000,
scrolling: bool = False,
) -> "DeltaGenerator":
"""Render filter renderer UI"""
html = self._get_html(mode="filter_renderer")
return components.html(html, height=height, width=width, scrolling=scrolling)

def render_explore(
self,
width: int = 1300,
Expand Down Expand Up @@ -254,6 +263,7 @@ def get_streamlit_html(
show_cloud_tool: Optional[bool] = None,
debug: bool = False,
kanaries_api_key: str = "",
mode: Literal["explore", "filter_renderer"] = "explore",
**kwargs
) -> str:
"""Get pygwalker html render to streamlit
Expand Down Expand Up @@ -288,4 +298,4 @@ def get_streamlit_html(
**kwargs
)

return renderer._get_html()
return renderer._get_html(mode=mode)