From 095adc57548150e81ab9fc2afbcb7444bbcd8e73 Mon Sep 17 00:00:00 2001 From: islxyqwe Date: Thu, 24 Aug 2023 16:20:57 +0800 Subject: [PATCH 01/51] fix: graph didn't disappear when changing tab (#157) --- packages/graphic-walker/src/renderer/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/graphic-walker/src/renderer/index.tsx b/packages/graphic-walker/src/renderer/index.tsx index baf296f4c..26e2ae234 100644 --- a/packages/graphic-walker/src/renderer/index.tsx +++ b/packages/graphic-walker/src/renderer/index.tsx @@ -76,7 +76,7 @@ const Renderer = forwardRef(function (props, r setViewConfig(latestFromRef.current.visualConfig); }); } - }, [waiting, vizStore]); + }, [waiting, data, vizStore]); useChartIndexControl({ count: visList.length, From 0e71f14ebdca62440e47243250a34ff516c9eb15 Mon Sep 17 00:00:00 2001 From: observedobserver <270001151@qq.com> Date: Thu, 24 Aug 2023 17:08:11 +0800 Subject: [PATCH 02/51] publish: 0.4.4 --- packages/desktop/package.json | 2 +- packages/graphic-walker/package.json | 2 +- packages/graphic-walker/src/components/loadingLayer.tsx | 6 +++++- packages/graphic-walker/src/components/spinner.tsx | 5 +++-- packages/vanilla-graphic-walker/package.json | 2 +- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/desktop/package.json b/packages/desktop/package.json index 02ea68f0b..445ff6499 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -10,7 +10,7 @@ "tauri": "tauri" }, "dependencies": { - "@kanaries/graphic-walker": "0.4.3", + "@kanaries/graphic-walker": "0.4.4", "@tauri-apps/api": "^1.1.0", "react": "^17.x", "react-dom": "^17.x" diff --git a/packages/graphic-walker/package.json b/packages/graphic-walker/package.json index 30b8b19b8..d7e91434e 100644 --- a/packages/graphic-walker/package.json +++ b/packages/graphic-walker/package.json @@ -1,6 +1,6 @@ { "name": "@kanaries/graphic-walker", - "version": "0.4.3", + "version": "0.4.4", "scripts": { "dev:front_end": "vite --host", "dev": "npm run dev:front_end", diff --git a/packages/graphic-walker/src/components/loadingLayer.tsx b/packages/graphic-walker/src/components/loadingLayer.tsx index 2e14a9d8f..dddb04e5f 100644 --- a/packages/graphic-walker/src/components/loadingLayer.tsx +++ b/packages/graphic-walker/src/components/loadingLayer.tsx @@ -1,7 +1,11 @@ import React from 'react'; +import Spinner from './spinner'; export default function LoadingLayer () { return
- Loading... + + + Loading... +
} \ No newline at end of file diff --git a/packages/graphic-walker/src/components/spinner.tsx b/packages/graphic-walker/src/components/spinner.tsx index 1bef081b1..95e71938a 100644 --- a/packages/graphic-walker/src/components/spinner.tsx +++ b/packages/graphic-walker/src/components/spinner.tsx @@ -1,8 +1,9 @@ import React from 'react'; -export default function Spinner() { +export default function Spinner(props: { className?: string }) { + const className = props.className || 'text-white'; return ( - + Date: Fri, 25 Aug 2023 10:36:59 +0800 Subject: [PATCH 03/51] feat: add geourl to fetch geojson from remote (#158) * feat: remote-geojson * fix: config panel * fix: add loading for load button --- packages/graphic-walker/src/App.tsx | 2 +- .../src/components/button/base.ts | 1 + .../src/components/button/default.tsx | 3 +- .../leafletRenderer/ChoroplethRenderer.tsx | 8 +- .../leafletRenderer/geoConfigPanel.tsx | 100 +++++++++--------- .../src/components/leafletRenderer/index.tsx | 3 +- .../src/fields/datasetFields/meaFields.tsx | 3 +- packages/graphic-walker/src/hooks/service.ts | 30 ++++++ packages/graphic-walker/src/interfaces.ts | 6 ++ .../src/store/visualSpecStore.ts | 31 ++++-- 10 files changed, 123 insertions(+), 64 deletions(-) create mode 100644 packages/graphic-walker/src/hooks/service.ts diff --git a/packages/graphic-walker/src/App.tsx b/packages/graphic-walker/src/App.tsx index c80ea4585..bec2ab9df 100644 --- a/packages/graphic-walker/src/App.tsx +++ b/packages/graphic-walker/src/App.tsx @@ -185,7 +185,7 @@ const App = observer(function App(props) { - + {commonStore.showGeoJSONConfigPanel && }
diff --git a/packages/graphic-walker/src/components/button/base.ts b/packages/graphic-walker/src/components/button/base.ts index aca515b8f..381820335 100644 --- a/packages/graphic-walker/src/components/button/base.ts +++ b/packages/graphic-walker/src/components/button/base.ts @@ -5,4 +5,5 @@ export interface ButtonBaseProps { text: string; disabled?: boolean; className?: string; + icon?: JSX.Element; } \ No newline at end of file diff --git a/packages/graphic-walker/src/components/button/default.tsx b/packages/graphic-walker/src/components/button/default.tsx index 00bfd857b..e65b3d555 100644 --- a/packages/graphic-walker/src/components/button/default.tsx +++ b/packages/graphic-walker/src/components/button/default.tsx @@ -2,7 +2,7 @@ import React from "react"; import { ButtonBaseProps } from "./base"; const DefaultButton: React.FC = (props) => { - const { text, onClick, disabled, className } = props; + const { text, onClick, disabled, className, icon } = props; let btnClassName = "inline-flex items-center rounded border border-gray-300 bg-white dark:bg-zinc-900 px-2.5 py-1.5 text-xs font-medium text-gray-700 dark:text-gray-200 shadow-sm hover:bg-gray-50 dark:hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 disabled:opacity-50" if (className) { btnClassName = btnClassName + " " + className; @@ -14,6 +14,7 @@ const DefaultButton: React.FC = (props) => { disabled={disabled} > {text} + {icon} ); }; diff --git a/packages/graphic-walker/src/components/leafletRenderer/ChoroplethRenderer.tsx b/packages/graphic-walker/src/components/leafletRenderer/ChoroplethRenderer.tsx index 3157c71fd..ed36580be 100644 --- a/packages/graphic-walker/src/components/leafletRenderer/ChoroplethRenderer.tsx +++ b/packages/graphic-walker/src/components/leafletRenderer/ChoroplethRenderer.tsx @@ -1,13 +1,14 @@ import React, { Fragment, forwardRef, useEffect, useImperativeHandle, useMemo, useRef } from "react"; import { CircleMarker, MapContainer, Polygon, Marker, TileLayer, Tooltip } from "react-leaflet"; import { type Map, divIcon } from "leaflet"; -import type { DeepReadonly, IRow, IViewField, VegaGlobalConfig } from "../../interfaces"; +import type { DeepReadonly, IGeoUrl, IRow, IViewField, VegaGlobalConfig } from "../../interfaces"; import type { FeatureCollection, Geometry } from "geojson"; import { getMeaAggKey } from "../../utils"; import { useColorScale, useOpacityScale } from "./encodings"; import { isValidLatLng } from "./POIRenderer"; import { TooltipContent } from "./tooltip"; import { useAppRootContext } from "../appRoot"; +import { useGeoJSON } from "../../hooks/service"; export interface IChoroplethRendererProps { @@ -15,6 +16,7 @@ export interface IChoroplethRendererProps { data: IRow[]; allFields: DeepReadonly; features: FeatureCollection | undefined; + featuresUrl?: IGeoUrl; geoKey: string; defaultAggregated: boolean; geoId: DeepReadonly; @@ -88,10 +90,12 @@ const resolveCenter = (coordinates: [lat: number, lng: number][]): [lng: number, }; const ChoroplethRenderer = forwardRef(function ChoroplethRenderer (props, ref) { - const { name, data, allFields, features, geoKey, defaultAggregated, geoId, color, opacity, text, details, vegaConfig, scaleIncludeUnmatchedChoropleth } = props; + const { name, data, allFields, features: localFeatures, featuresUrl, geoKey, defaultAggregated, geoId, color, opacity, text, details, vegaConfig, scaleIncludeUnmatchedChoropleth } = props; useImperativeHandle(ref, () => ({})); + const features = useGeoJSON(localFeatures, featuresUrl) + const geoIndices = useMemo(() => { if (geoId) { return data.map(row => row[geoId.fid]); diff --git a/packages/graphic-walker/src/components/leafletRenderer/geoConfigPanel.tsx b/packages/graphic-walker/src/components/leafletRenderer/geoConfigPanel.tsx index 57ea6c5c0..faf26b34f 100644 --- a/packages/graphic-walker/src/components/leafletRenderer/geoConfigPanel.tsx +++ b/packages/graphic-walker/src/components/leafletRenderer/geoConfigPanel.tsx @@ -1,27 +1,29 @@ import { observer } from 'mobx-react-lite'; import React, { useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { runInAction } from 'mobx'; +import Spinner from '../spinner'; import { useGlobalStore } from '../../store'; import Modal from '../modal'; import PrimaryButton from '../button/primary'; import DefaultButton from '../button/default'; -import type { Topology } from '../../interfaces'; +import type { IGeoUrl, Topology } from '../../interfaces'; const GeoConfigPanel: React.FC = (props) => { const { commonStore, vizStore } = useGlobalStore(); const { showGeoJSONConfigPanel } = commonStore; const { visualConfig } = vizStore; - const { geoKey, geojson } = visualConfig; + const { geoKey, geojson, geoUrl } = visualConfig; const { t: tGlobal } = useTranslation('translation'); const { t } = useTranslation('translation', { keyPrefix: 'main.tabpanel.settings' }); - const [dataMode, setDataMode] = useState<'GeoJSON' | 'TopoJSON'>('GeoJSON'); + const [dataMode, setDataMode] = useState<'GeoJSON' | 'TopoJSON'>(geoUrl?.type ?? 'GeoJSON'); const [featureId, setFeatureId] = useState(''); - const [url, setUrl] = useState(''); + const [url, setUrl] = useState(geoUrl?.url ?? ''); const [geoJSON, setGeoJSON] = useState(''); const [topoJSON, setTopoJSON] = useState(''); const [topoJSONKey, setTopoJSONKey] = useState(''); + const [loadedUrl, setLoadedUrl] = useState(geoUrl); + const [loading, setLoading] = useState(false); const defaultTopoJSONKey = useMemo(() => { try { @@ -40,13 +42,37 @@ const GeoConfigPanel: React.FC = (props) => { setGeoJSON(geojson ? JSON.stringify(geojson, null, 2) : ''); }, [geojson]); + const handleSubmit = () => { + try { + const json = JSON.parse(dataMode === 'GeoJSON' ? geoJSON : topoJSON); + if (dataMode === 'TopoJSON') { + vizStore.setGeographicData( + { + type: 'TopoJSON', + data: json, + objectKey: topoJSONKey || defaultTopoJSONKey, + }, + featureId, + loadedUrl?.type === 'TopoJSON' ? loadedUrl : undefined + ); + } else { + vizStore.setGeographicData( + { + type: 'GeoJSON', + data: json, + }, + featureId, + loadedUrl?.type === 'GeoJSON' ? loadedUrl : undefined + ); + } + commonStore.setShowGeoJSONConfigPanel(false); + } catch (err) { + console.error(err); + } + }; + return ( - { - commonStore.setShowGeoJSONConfigPanel(false); - }} - > + commonStore.setShowGeoJSONConfigPanel(false)}>

{t('geography')}

@@ -57,9 +83,7 @@ const GeoConfigPanel: React.FC = (props) => { type="text" className="block w-full rounded-md border-0 py-1 px-2 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-1 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6" value={featureId} - onChange={(e) => { - setFeatureId(e.target.value); - }} + onChange={(e) => setFeatureId(e.target.value)} />
@@ -112,14 +136,20 @@ const GeoConfigPanel: React.FC = (props) => { : undefined} onClick={() => { if (url) { + setLoading(true); fetch(url) .then((res) => res.json()) .then((json) => { - (dataMode === 'GeoJSON' ? setGeoJSON : setTopoJSON)( - JSON.stringify(json, null, 2) - ); + (dataMode === 'GeoJSON' ? setGeoJSON : setTopoJSON)(JSON.stringify(json, null, 2)); + setLoadedUrl({ type: dataMode, url }); + setLoading(false); + }) + .catch(() => { + setLoading(false); }); } }} @@ -131,13 +161,14 @@ const GeoConfigPanel: React.FC = (props) => { placeholder={t('geography_settings.jsonInputPlaceholder', { format: dataMode.toLowerCase() })} onChange={(e) => { (dataMode === 'GeoJSON' ? setGeoJSON : setTopoJSON)(e.target.value); + if (loadedUrl?.type === dataMode) { + setLoadedUrl(undefined); + } }} /> {dataMode === 'TopoJSON' && (
- + {
- { - try { - const json = JSON.parse(dataMode === 'GeoJSON' ? geoJSON : topoJSON); - if (dataMode === 'TopoJSON') { - runInAction(() => { - vizStore.setGeographicData({ - type: 'TopoJSON', - data: json, - objectKey: topoJSONKey || defaultTopoJSONKey, - }, featureId); - }); - } else { - runInAction(() => { - vizStore.setGeographicData({ - type: 'GeoJSON', - data: json, - }, featureId); - }); - } - commonStore.setShowGeoJSONConfigPanel(false); - } catch (err) { - console.error(err); - } - }} - /> + (function LeafletRenderer (props, ref) { const { name, draggableFieldState, data, visualConfig, vegaConfig = {} } = props; const { latitude: [lat], longitude: [lng], geoId: [geoId], dimensions, measures, size: [size], color: [color], opacity: [opacity], text: [text], details } = draggableFieldState; - const { defaultAggregated, geoms: [markType], geojson, geoKey = '', scaleIncludeUnmatchedChoropleth = false } = visualConfig; + const { defaultAggregated, geoms: [markType], geojson, geoKey = '', geoUrl, scaleIncludeUnmatchedChoropleth = false } = visualConfig; const allFields = useMemo(() => [...dimensions, ...measures], [dimensions, measures]); const latField = useMemo(() => allFields.find((f) => f.geoRole === 'latitude'), [allFields]); const lngField = useMemo(() => allFields.find((f) => f.geoRole === 'longitude'), [allFields]); @@ -50,6 +50,7 @@ const LeafletRenderer = forwardRef(f data={data} allFields={allFields} features={geojson} + featuresUrl={geoUrl} geoKey={geoKey} defaultAggregated={defaultAggregated} geoId={geoId} diff --git a/packages/graphic-walker/src/fields/datasetFields/meaFields.tsx b/packages/graphic-walker/src/fields/datasetFields/meaFields.tsx index 451e61909..75ccef596 100644 --- a/packages/graphic-walker/src/fields/datasetFields/meaFields.tsx +++ b/packages/graphic-walker/src/fields/datasetFields/meaFields.tsx @@ -5,6 +5,7 @@ import { useGlobalStore } from "../../store"; import DataTypeIcon from "../../components/dataTypeIcon"; import { FieldPill } from "./fieldPill"; import DropdownContext, { IDropdownContextOption } from "../../components/dropdownContext"; +import { COUNT_FIELD_ID } from "../../constants"; interface Props { provided: DroppableProvided; @@ -50,7 +51,7 @@ const MeaFields: React.FC = (props) => { return (
{ fieldActionHandler(v, opIndex, index); diff --git a/packages/graphic-walker/src/hooks/service.ts b/packages/graphic-walker/src/hooks/service.ts new file mode 100644 index 000000000..feff903f1 --- /dev/null +++ b/packages/graphic-walker/src/hooks/service.ts @@ -0,0 +1,30 @@ +import { IGeoUrl } from '../interfaces'; +import { useState, useEffect, useRef } from 'react'; +import { feature } from 'topojson-client'; +import type { FeatureCollection } from "geojson"; + +const GeoJSONDict: Record = {}; +export function useGeoJSON(geojson?: FeatureCollection, url?: IGeoUrl) { + const key = url ? `${url.type}(${url.url})` : ''; + const data = (geojson || GeoJSONDict[key] || url) as IGeoUrl | FeatureCollection; + const [_, setLastFetched] = useState(0); + const lastFetchedRef = useRef(0); + useEffect(() => { + if (data === url && url) { + const timestamp = Date.now(); + lastFetchedRef.current = timestamp; + fetch(url.url) + .then((res) => res.json()) + .then((json) => { + if (timestamp !== lastFetchedRef.current) return; + if (url.type === 'GeoJSON') { + data[key] = json; + } else { + data[key] = feature(json, Object.keys(json.objects)[0]); + } + setLastFetched(timestamp); + }); + } + }, [data]); + return data === url ? undefined : data as FeatureCollection; +} diff --git a/packages/graphic-walker/src/interfaces.ts b/packages/graphic-walker/src/interfaces.ts index 7bd4cbd4c..7ddc6b4b3 100644 --- a/packages/graphic-walker/src/interfaces.ts +++ b/packages/graphic-walker/src/interfaces.ts @@ -253,9 +253,15 @@ export interface IVisualConfig { }; geojson?: FeatureCollection; geoKey?: string; + geoUrl?: IGeoUrl; limit: number; } +export interface IGeoUrl { + type: 'GeoJSON' | 'TopoJSON', + url: string, +} + export interface IVisSpec { readonly visId: string; readonly name?: string; diff --git a/packages/graphic-walker/src/store/visualSpecStore.ts b/packages/graphic-walker/src/store/visualSpecStore.ts index c0ad4fdf7..d98e39f0f 100644 --- a/packages/graphic-walker/src/store/visualSpecStore.ts +++ b/packages/graphic-walker/src/store/visualSpecStore.ts @@ -1,7 +1,7 @@ import { IReactionDisposer, makeAutoObservable, observable, computed, reaction, toJS } from 'mobx'; import produce from 'immer'; import { feature } from 'topojson-client'; -import type { FeatureCollection } from "geojson"; +import type { FeatureCollection } from 'geojson'; import { DataSet, DraggableFieldState, @@ -16,6 +16,7 @@ import { IVisualConfig, Specification, IComputationFunction, + IGeoUrl, } from '../interfaces'; import { CHANNEL_LIMIT, GEMO_TYPES, MetaFieldKeys } from '../config'; import { VisSpecWithHistory } from '../models/visSpecHistory'; @@ -103,10 +104,14 @@ function isDraggableStateEmpty(state: DeepReadonly): boolea return Object.values(state).every((value) => value.length === 0); } -function withTimeout(f: (...args: T) => Promise, timeout: number){ - return (...args: T) => Promise.race([f(...args), new Promise((_, reject) => { - setTimeout(() => reject(new Error('timeout')), timeout) - })]) +function withTimeout(f: (...args: T) => Promise, timeout: number) { + return (...args: T) => + Promise.race([ + f(...args), + new Promise((_, reject) => { + setTimeout(() => reject(new Error('timeout')), timeout); + }), + ]); } export class VizSpecStore { @@ -383,8 +388,8 @@ export class VizSpecStore { return ((config as unknown as { [k: string]: boolean })[configKey] = Boolean(value)); } case configKey === 'geoms' && Array.isArray(value): - case configKey === "showTableSummary": - case configKey === "coordSystem": + case configKey === 'showTableSummary': + case configKey === 'coordSystem': case configKey === 'size' && typeof value === 'object': case configKey === 'sorted': case configKey === 'zeroScale': @@ -817,9 +822,10 @@ export class VizSpecStore { const content = parseGWContent(raw); this.importStoInfo(content); } - - public setGeographicData(data: IGeographicData, geoKey: string) { - const geoJSON = data.type === 'GeoJSON' ? data.data : feature(data.data, data.objectKey || Object.keys(data.data.objects)[0]) as unknown as FeatureCollection; + + public setGeographicData(data: IGeographicData, geoKey: string, geoUrl?: IGeoUrl) { + const geoJSON = + data.type === 'GeoJSON' ? data.data : (feature(data.data, data.objectKey || Object.keys(data.data.objects)[0]) as unknown as FeatureCollection); if (!('features' in geoJSON)) { console.error('Invalid GeoJSON: GeoJSON must be a FeatureCollection, but got', geoJSON); return; @@ -827,6 +833,7 @@ export class VizSpecStore { this.useMutable(({ config }) => { config.geojson = geoJSON; config.geoKey = geoKey; + config.geoUrl = geoUrl; }); } public updateGeoKey(key: string) { @@ -856,6 +863,10 @@ export class VizSpecStore { ...visSpec.encodings, filters: updatedFilters, }, + config: { + ...visSpec.config, + geojson: visSpec.config.geoUrl ? undefined : visSpec.config.geojson + } }; }); return updatedVisList; From 7f887c2b0dbb7a3b6bb5a81796d6ab9f247c18a6 Mon Sep 17 00:00:00 2001 From: observedobserver <270001151@qq.com> Date: Fri, 25 Aug 2023 10:44:06 +0800 Subject: [PATCH 04/51] release: 0.4.5 --- packages/desktop/package.json | 2 +- packages/graphic-walker/package.json | 2 +- packages/vanilla-graphic-walker/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/desktop/package.json b/packages/desktop/package.json index 445ff6499..e00e15a64 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -10,7 +10,7 @@ "tauri": "tauri" }, "dependencies": { - "@kanaries/graphic-walker": "0.4.4", + "@kanaries/graphic-walker": "0.4.5", "@tauri-apps/api": "^1.1.0", "react": "^17.x", "react-dom": "^17.x" diff --git a/packages/graphic-walker/package.json b/packages/graphic-walker/package.json index d7e91434e..519889246 100644 --- a/packages/graphic-walker/package.json +++ b/packages/graphic-walker/package.json @@ -1,6 +1,6 @@ { "name": "@kanaries/graphic-walker", - "version": "0.4.4", + "version": "0.4.5", "scripts": { "dev:front_end": "vite --host", "dev": "npm run dev:front_end", diff --git a/packages/vanilla-graphic-walker/package.json b/packages/vanilla-graphic-walker/package.json index 380c58965..8efbf3332 100644 --- a/packages/vanilla-graphic-walker/package.json +++ b/packages/vanilla-graphic-walker/package.json @@ -13,6 +13,6 @@ "vite": "^4.3.9" }, "dependencies": { - "@kanaries/graphic-walker": "0.4.4" + "@kanaries/graphic-walker": "0.4.5" } } From 9b0c873a08678bd92c39d30471b1210b62fcfa0c Mon Sep 17 00:00:00 2001 From: islxyqwe Date: Fri, 25 Aug 2023 11:52:07 +0800 Subject: [PATCH 05/51] fix: useGeoJSON (#159) * fix: useGeoJSON * fix: remove console --- packages/graphic-walker/src/hooks/service.ts | 4 ++-- packages/graphic-walker/src/renderer/pureRenderer.tsx | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/graphic-walker/src/hooks/service.ts b/packages/graphic-walker/src/hooks/service.ts index feff903f1..78c43abc4 100644 --- a/packages/graphic-walker/src/hooks/service.ts +++ b/packages/graphic-walker/src/hooks/service.ts @@ -18,9 +18,9 @@ export function useGeoJSON(geojson?: FeatureCollection, url?: IGeoUrl) { .then((json) => { if (timestamp !== lastFetchedRef.current) return; if (url.type === 'GeoJSON') { - data[key] = json; + GeoJSONDict[key] = json; } else { - data[key] = feature(json, Object.keys(json.objects)[0]); + GeoJSONDict[key] = feature(json, Object.keys(json.objects)[0]) as unknown as FeatureCollection; } setLastFetched(timestamp); }); diff --git a/packages/graphic-walker/src/renderer/pureRenderer.tsx b/packages/graphic-walker/src/renderer/pureRenderer.tsx index 912eae649..11e24a35f 100644 --- a/packages/graphic-walker/src/renderer/pureRenderer.tsx +++ b/packages/graphic-walker/src/renderer/pureRenderer.tsx @@ -86,7 +86,6 @@ const PureRenderer = forwardRef(function limit: limit ?? -1, computationFunction: computation, }); - console.log(computation) // Dependencies that should not trigger effect individually const latestFromRef = useRef({ data }); latestFromRef.current = { data }; From 90c946d66a979eca53361c66d9687ba1c8907aaa Mon Sep 17 00:00:00 2001 From: observedobserver <270001151@qq.com> Date: Fri, 25 Aug 2023 12:25:18 +0800 Subject: [PATCH 06/51] feat: support customize Theme --- packages/graphic-walker/src/App.tsx | 4 +++- packages/graphic-walker/src/renderer/index.tsx | 4 +++- packages/graphic-walker/src/renderer/pureRenderer.tsx | 1 + packages/graphic-walker/src/renderer/specRenderer.tsx | 10 ++++++++-- packages/graphic-walker/src/utils/useTheme.ts | 8 ++++++++ 5 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 packages/graphic-walker/src/utils/useTheme.ts diff --git a/packages/graphic-walker/src/App.tsx b/packages/graphic-walker/src/App.tsx index bec2ab9df..a2826acd5 100644 --- a/packages/graphic-walker/src/App.tsx +++ b/packages/graphic-walker/src/App.tsx @@ -38,6 +38,7 @@ export interface IGWProps { fieldKeyGuard?: boolean; /** @default "vega" */ themeKey?: IThemeKey; + themeConfig?: any; dark?: IDarkMode; storeRef?: React.MutableRefObject; computation?: IComputationFunction; @@ -67,6 +68,7 @@ const App = observer(function App(props) { hideDataSourceConfig, fieldKeyGuard = true, themeKey = 'vega', + themeConfig, dark = 'media', computation, toolbar, @@ -209,7 +211,7 @@ const App = observer(function App(props) { // }} > {datasets.length > 0 && ( - + )} {/* {vizEmbededMenu.show && ( diff --git a/packages/graphic-walker/src/renderer/index.tsx b/packages/graphic-walker/src/renderer/index.tsx index 26e2ae234..a5f2b2711 100644 --- a/packages/graphic-walker/src/renderer/index.tsx +++ b/packages/graphic-walker/src/renderer/index.tsx @@ -15,6 +15,7 @@ import { initVisualConfig } from '../utils/save'; interface RendererProps { themeKey?: IThemeKey; + themeConfig?: any; dark?: IDarkMode; computationFunction: IComputationFunction; } @@ -23,7 +24,7 @@ interface RendererProps { * Depending on global store. */ const Renderer = forwardRef(function (props, ref) { - const { themeKey, dark, computationFunction } = props; + const { themeKey, dark, computationFunction, themeConfig } = props; const { vizStore, commonStore } = useGlobalStore(); const { allFields, @@ -131,6 +132,7 @@ const Renderer = forwardRef(function (props, r data={viewData} ref={ref} themeKey={themeKey} + themeConfig={themeConfig} dark={dark} locale={i18n.language} draggableFieldState={encodings} diff --git a/packages/graphic-walker/src/renderer/pureRenderer.tsx b/packages/graphic-walker/src/renderer/pureRenderer.tsx index 11e24a35f..31aac4c5e 100644 --- a/packages/graphic-walker/src/renderer/pureRenderer.tsx +++ b/packages/graphic-walker/src/renderer/pureRenderer.tsx @@ -23,6 +23,7 @@ type IPureRendererProps = | { name?: string; themeKey?: IThemeKey; + themeConfig?: any; dark?: IDarkMode; visualState: DraggableFieldState; visualConfig: IVisualConfig; diff --git a/packages/graphic-walker/src/renderer/specRenderer.tsx b/packages/graphic-walker/src/renderer/specRenderer.tsx index b0313c963..c0b02619e 100644 --- a/packages/graphic-walker/src/renderer/specRenderer.tsx +++ b/packages/graphic-walker/src/renderer/specRenderer.tsx @@ -9,6 +9,7 @@ import { DeepReadonly, DraggableFieldState, IDarkMode, IRow, IThemeKey, IVisualC import LoadingLayer from '../components/loadingLayer'; import { useCurrentMediaTheme } from '../utils/media'; import { builtInThemes } from '../vis/theme'; +import { useTheme } from '../utils/useTheme'; interface SpecRendererProps { name?: string; @@ -22,13 +23,14 @@ interface SpecRendererProps { onChartResize?: ((width: number, height: number) => void) | undefined; locale?: string; computationFunction: IComputationFunction; + themeConfig?: any; } /** * Sans-store renderer of GraphicWalker. * This is a pure component, which means it will not depend on any global state. */ const SpecRenderer = forwardRef(function ( - { name, themeKey, dark, data, loading, draggableFieldState, visualConfig, onGeomClick, onChartResize, locale, computationFunction }, + { name, themeKey, dark, data, loading, draggableFieldState, visualConfig, onGeomClick, onChartResize, locale, computationFunction, themeConfig: customizedThemeConfig }, ref ) { // const { draggableFieldState, visualConfig } = vizStore; @@ -58,7 +60,11 @@ const SpecRenderer = forwardRef(function ( const enableResize = size.mode === 'fixed' && !hasFacet && Boolean(onChartResize); const mediaTheme = useCurrentMediaTheme(dark); - const themeConfig = builtInThemes[themeKey ?? 'vega']?.[mediaTheme]; + const themeConfig = useTheme({ + themeKey, + mediaTheme, + themeConfig: customizedThemeConfig + }) const vegaConfig = useMemo(() => { const config: VegaGlobalConfig = { diff --git a/packages/graphic-walker/src/utils/useTheme.ts b/packages/graphic-walker/src/utils/useTheme.ts new file mode 100644 index 000000000..12d664562 --- /dev/null +++ b/packages/graphic-walker/src/utils/useTheme.ts @@ -0,0 +1,8 @@ +import { IThemeKey } from "../interfaces"; +import { builtInThemes } from "../vis/theme"; + +export function useTheme (props: { themeKey?: IThemeKey; themeConfig?: any; mediaTheme: 'dark' | 'light' }) { + const { themeConfig, themeKey, mediaTheme } = props; + const config = (themeConfig ?? builtInThemes[themeKey ?? 'vega'])?.[mediaTheme]; + return config +} \ No newline at end of file From 9a50f53b8f87ebcf91effa77dae90c8c414dded2 Mon Sep 17 00:00:00 2001 From: observedobserver <270001151@qq.com> Date: Fri, 25 Aug 2023 13:50:34 +0800 Subject: [PATCH 07/51] release: 0.4.6 --- packages/desktop/package.json | 2 +- packages/graphic-walker/package.json | 2 +- packages/vanilla-graphic-walker/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/desktop/package.json b/packages/desktop/package.json index e00e15a64..1066d1dae 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -10,7 +10,7 @@ "tauri": "tauri" }, "dependencies": { - "@kanaries/graphic-walker": "0.4.5", + "@kanaries/graphic-walker": "0.4.6", "@tauri-apps/api": "^1.1.0", "react": "^17.x", "react-dom": "^17.x" diff --git a/packages/graphic-walker/package.json b/packages/graphic-walker/package.json index 519889246..5143c8daf 100644 --- a/packages/graphic-walker/package.json +++ b/packages/graphic-walker/package.json @@ -1,6 +1,6 @@ { "name": "@kanaries/graphic-walker", - "version": "0.4.5", + "version": "0.4.6", "scripts": { "dev:front_end": "vite --host", "dev": "npm run dev:front_end", diff --git a/packages/vanilla-graphic-walker/package.json b/packages/vanilla-graphic-walker/package.json index 8efbf3332..f3649a88a 100644 --- a/packages/vanilla-graphic-walker/package.json +++ b/packages/vanilla-graphic-walker/package.json @@ -13,6 +13,6 @@ "vite": "^4.3.9" }, "dependencies": { - "@kanaries/graphic-walker": "0.4.5" + "@kanaries/graphic-walker": "0.4.6" } } From 68cbf389526adfbe41cfd872e0cb375d8ad4e872 Mon Sep 17 00:00:00 2001 From: islxyqwe Date: Fri, 25 Aug 2023 15:23:08 +0800 Subject: [PATCH 08/51] fix: leaflet pure renderer (#160) --- .../src/renderer/pureRenderer.tsx | 31 ++++++------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/packages/graphic-walker/src/renderer/pureRenderer.tsx b/packages/graphic-walker/src/renderer/pureRenderer.tsx index 31aac4c5e..5f094a227 100644 --- a/packages/graphic-walker/src/renderer/pureRenderer.tsx +++ b/packages/graphic-walker/src/renderer/pureRenderer.tsx @@ -3,17 +3,9 @@ import { unstable_batchedUpdates } from 'react-dom'; import { toJS } from 'mobx'; import { observer } from 'mobx-react-lite'; import { ShadowDom } from '../shadow-dom'; -import LeafletRenderer from '../components/leafletRenderer'; +import LeafletRenderer, { LEAFLET_DEFAULT_HEIGHT, LEAFLET_DEFAULT_WIDTH } from '../components/leafletRenderer'; import { withAppRoot } from '../components/appRoot'; -import type { - IDarkMode, - IViewField, - IRow, - IThemeKey, - DraggableFieldState, - IVisualConfig, - IComputationFunction, -} from '../interfaces'; +import type { IDarkMode, IViewField, IRow, IThemeKey, DraggableFieldState, IVisualConfig, IComputationFunction } from '../interfaces'; import type { IReactVegaHandler } from '../vis/react-vega'; import SpecRenderer from './specRenderer'; import { useRenderer } from './hooks'; @@ -32,11 +24,11 @@ type IPureRendererProps = locale?: string; } & ( | { - type: 'remote', + type: 'remote'; computation: IComputationFunction; } | { - type?: 'local' + type?: 'local'; rawData: IRow[]; } ); @@ -52,7 +44,7 @@ const PureRenderer = forwardRef(function return props.computation; } return getComputation(props.rawData); - }, [props.type, props.type === 'remote' ? props.computation: props.rawData]) + }, [props.type, props.type === 'remote' ? props.computation : props.rawData]); const defaultAggregated = visualConfig?.defaultAggregated ?? false; const [viewData, setViewData] = useState([]); @@ -103,15 +95,12 @@ const PureRenderer = forwardRef(function const isSpatial = coordSystem === 'geographic'; return ( - -
+ +
{isSpatial && ( - +
+ +
)} {isSpatial || ( Date: Fri, 25 Aug 2023 16:07:29 +0800 Subject: [PATCH 09/51] fix: remove width style (#161) --- packages/graphic-walker/src/renderer/pureRenderer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/graphic-walker/src/renderer/pureRenderer.tsx b/packages/graphic-walker/src/renderer/pureRenderer.tsx index 5f094a227..63f929dbc 100644 --- a/packages/graphic-walker/src/renderer/pureRenderer.tsx +++ b/packages/graphic-walker/src/renderer/pureRenderer.tsx @@ -98,7 +98,7 @@ const PureRenderer = forwardRef(function
{isSpatial && ( -
+
)} From 16acbe23dfc06102673e5e27084341df22090db7 Mon Sep 17 00:00:00 2001 From: islxyqwe Date: Fri, 25 Aug 2023 17:58:35 +0800 Subject: [PATCH 10/51] fix: remove width style (#162) From 3fb9f3993a1ba1ce093572c81545099b5c958ae9 Mon Sep 17 00:00:00 2001 From: observedobserver <270001151@qq.com> Date: Fri, 25 Aug 2023 18:01:06 +0800 Subject: [PATCH 11/51] release: 0.4.8 --- packages/desktop/package.json | 2 +- packages/graphic-walker/package.json | 2 +- packages/vanilla-graphic-walker/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/desktop/package.json b/packages/desktop/package.json index 1066d1dae..36120d339 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -10,7 +10,7 @@ "tauri": "tauri" }, "dependencies": { - "@kanaries/graphic-walker": "0.4.6", + "@kanaries/graphic-walker": "0.4.8", "@tauri-apps/api": "^1.1.0", "react": "^17.x", "react-dom": "^17.x" diff --git a/packages/graphic-walker/package.json b/packages/graphic-walker/package.json index 5143c8daf..383aa5e7a 100644 --- a/packages/graphic-walker/package.json +++ b/packages/graphic-walker/package.json @@ -1,6 +1,6 @@ { "name": "@kanaries/graphic-walker", - "version": "0.4.6", + "version": "0.4.8", "scripts": { "dev:front_end": "vite --host", "dev": "npm run dev:front_end", diff --git a/packages/vanilla-graphic-walker/package.json b/packages/vanilla-graphic-walker/package.json index f3649a88a..61fa8347a 100644 --- a/packages/vanilla-graphic-walker/package.json +++ b/packages/vanilla-graphic-walker/package.json @@ -13,6 +13,6 @@ "vite": "^4.3.9" }, "dependencies": { - "@kanaries/graphic-walker": "0.4.6" + "@kanaries/graphic-walker": "0.4.8" } } From 1cc4e1b349268b251ba677c0f9a2fa2e6b06efc9 Mon Sep 17 00:00:00 2001 From: islxyqwe Date: Fri, 25 Aug 2023 18:16:45 +0800 Subject: [PATCH 12/51] fix: pass themeConfig in pure renderer --- packages/graphic-walker/src/renderer/pureRenderer.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/graphic-walker/src/renderer/pureRenderer.tsx b/packages/graphic-walker/src/renderer/pureRenderer.tsx index 63f929dbc..75680ab54 100644 --- a/packages/graphic-walker/src/renderer/pureRenderer.tsx +++ b/packages/graphic-walker/src/renderer/pureRenderer.tsx @@ -38,7 +38,7 @@ type IPureRendererProps = * This is a pure component, which means it will not depend on any global state. */ const PureRenderer = forwardRef(function PureRenderer(props, ref) { - const { name, themeKey, dark, visualState, visualConfig, type, locale, sort, limit } = props; + const { name, themeKey, dark, visualState, visualConfig, type, locale, sort, limit, themeConfig } = props; const computation = useMemo(() => { if (props.type === 'remote') { return props.computation; @@ -104,6 +104,7 @@ const PureRenderer = forwardRef(function )} {isSpatial || ( Date: Fri, 25 Aug 2023 18:35:32 +0800 Subject: [PATCH 13/51] release: 0.4.9 --- packages/desktop/package.json | 2 +- packages/graphic-walker/package.json | 2 +- packages/vanilla-graphic-walker/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/desktop/package.json b/packages/desktop/package.json index 36120d339..184ed39cd 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -10,7 +10,7 @@ "tauri": "tauri" }, "dependencies": { - "@kanaries/graphic-walker": "0.4.8", + "@kanaries/graphic-walker": "0.4.9", "@tauri-apps/api": "^1.1.0", "react": "^17.x", "react-dom": "^17.x" diff --git a/packages/graphic-walker/package.json b/packages/graphic-walker/package.json index 383aa5e7a..f678a7189 100644 --- a/packages/graphic-walker/package.json +++ b/packages/graphic-walker/package.json @@ -1,6 +1,6 @@ { "name": "@kanaries/graphic-walker", - "version": "0.4.8", + "version": "0.4.9", "scripts": { "dev:front_end": "vite --host", "dev": "npm run dev:front_end", diff --git a/packages/vanilla-graphic-walker/package.json b/packages/vanilla-graphic-walker/package.json index 61fa8347a..e5a18485c 100644 --- a/packages/vanilla-graphic-walker/package.json +++ b/packages/vanilla-graphic-walker/package.json @@ -13,6 +13,6 @@ "vite": "^4.3.9" }, "dependencies": { - "@kanaries/graphic-walker": "0.4.8" + "@kanaries/graphic-walker": "0.4.9" } } From c7538912758a60c547f65b4d84c1cabc7c331f7b Mon Sep 17 00:00:00 2001 From: islxyqwe Date: Tue, 29 Aug 2023 16:35:20 +0800 Subject: [PATCH 14/51] fix: filter display for boolean --- packages/graphic-walker/src/fields/filterField/tabs.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/graphic-walker/src/fields/filterField/tabs.tsx b/packages/graphic-walker/src/fields/filterField/tabs.tsx index f172fe54f..89f774930 100644 --- a/packages/graphic-walker/src/fields/filterField/tabs.tsx +++ b/packages/graphic-walker/src/fields/filterField/tabs.tsx @@ -353,7 +353,7 @@ export const FilterOneOfRule: React.FC = ob htmlFor={id} title={String(value)} > - {value} + {`${value}`}