diff --git a/packages/rath-client/package.json b/packages/rath-client/package.json index 39bf2c85..479c6e7f 100644 --- a/packages/rath-client/package.json +++ b/packages/rath-client/package.json @@ -16,7 +16,7 @@ "@fluentui/font-icons-mdl2": "^8.4.13", "@fluentui/react": "^8.94.4", "@fluentui/react-hooks": "^8.6.11", - "@kanaries/graphic-walker": "^0.2.6", + "@kanaries/graphic-walker": "0.2.7", "@kanaries/loa": "^0.0.13", "@kanaries/web-data-loader": "0.1.7", "@material-ui/core": "^5.0.0-beta.5", diff --git a/packages/rath-client/src/lib/stat/index.ts b/packages/rath-client/src/lib/stat/index.ts index a4a0e624..841d59ff 100644 --- a/packages/rath-client/src/lib/stat/index.ts +++ b/packages/rath-client/src/lib/stat/index.ts @@ -1,5 +1,7 @@ +import { shallowCopyArray } from "../../utils/deepcopy"; + export function getQuantiles(values: number[], percents: number[]) { - const sortedValues = [...values].sort((a, b) => a - b); + const sortedValues = shallowCopyArray(values).sort((a, b) => a - b); const percentIndices = percents.map(p => p * values.length) const qts: number[] = []; for (let pi of percentIndices) { diff --git a/packages/rath-client/src/pages/dataSource/metaView/distChart.tsx b/packages/rath-client/src/pages/dataSource/metaView/distChart.tsx index 9dddaf27..e74a3aee 100644 --- a/packages/rath-client/src/pages/dataSource/metaView/distChart.tsx +++ b/packages/rath-client/src/pages/dataSource/metaView/distChart.tsx @@ -4,6 +4,7 @@ import { IAnalyticType, ISemanticType } from 'visual-insights'; import intl from 'react-intl-universal'; import { IRow } from '../../../interfaces'; import { getRange } from '../../../utils'; +import { shallowCopyArray } from '../../../utils/deepcopy'; const DATA_NAME = 'dataSource'; const DEFAULT_BIN_SIZE = 10; @@ -59,7 +60,7 @@ const DistributionChart: React.FC = (props) => { } }) } else if (semanticType === 'nominal') { - adjustData = [...dataSource].sort((a, b) => b['y'] - a['y']).slice(0, maxItemInView) + adjustData = shallowCopyArray(dataSource).sort((a, b) => b['y'] - a['y']).slice(0, maxItemInView) } else if (semanticType === 'quantitative') { adjustData = fl2bins(dataSource, x, y, maxItemInView) } else { diff --git a/packages/rath-client/src/pages/dataSource/profilingView/fullDistViz.tsx b/packages/rath-client/src/pages/dataSource/profilingView/fullDistViz.tsx index 6054d0ee..66e061fc 100644 --- a/packages/rath-client/src/pages/dataSource/profilingView/fullDistViz.tsx +++ b/packages/rath-client/src/pages/dataSource/profilingView/fullDistViz.tsx @@ -3,6 +3,7 @@ import React, { useEffect, useMemo, useRef, useState } from 'react'; import embed, { Result, vega } from 'vega-embed'; import intl from 'react-intl-universal'; import { IRow } from '../../../interfaces'; +import { shallowCopyArray } from '../../../utils/deepcopy'; const DATA_NAME = 'dataSource'; const DEFAULT_BIN_SIZE = 10; function fl2bins(data: IRow[], valueField: string, ctField: string, binSize: number | undefined = DEFAULT_BIN_SIZE) { @@ -57,7 +58,7 @@ const FullDistViz: React.FC = (props) => { } }) } else if (semanticType === 'nominal') { - adjustData = [...dataSource].sort((a, b) => b['y'] - a['y']).slice(0, maxItemInView) + adjustData = shallowCopyArray(dataSource).sort((a, b) => b['y'] - a['y']).slice(0, maxItemInView) } else if (semanticType === 'quantitative') { adjustData = fl2bins(dataSource, x, y, 10) } else { diff --git a/packages/rath-client/src/pages/dataSource/profilingView/metaDetail.tsx b/packages/rath-client/src/pages/dataSource/profilingView/metaDetail.tsx index e44b0d59..39f3a0c1 100644 --- a/packages/rath-client/src/pages/dataSource/profilingView/metaDetail.tsx +++ b/packages/rath-client/src/pages/dataSource/profilingView/metaDetail.tsx @@ -11,12 +11,14 @@ import { IFieldMeta } from '../../../interfaces'; import { computeFieldFeatures } from '../../../lib/meta/fieldMeta'; import { useGlobalStore } from '../../../store'; import FieldFilter from '../../../components/fieldFilter'; +import { getRange } from '../../../utils'; import { ANALYTIC_TYPE_CHOICES, SEMANTIC_TYPE_CHOICES } from '../config'; import DetailTable from './detailTable'; import FullDistViz from './fullDistViz'; import StatTable from './statTable'; import { patchFilterTemporalRange } from './utils'; + const DetailContainer = styled.div` flex-grow: 1; flex-shrink: 1; @@ -74,16 +76,18 @@ const MetaDetail: React.FC = (props) => { const _min = field.features.min; const _max = field.features.max; const step = (_max - _min) / 10; + const [slMin, slMax] = getRange(selection); ans.push({ fid: field.fid, type: 'range', - range: [Math.min(...selection) - step / 2, Math.max(...selection) + step / 2], + range: [slMin - step / 2, slMax + step / 2], }); } else if (field.semanticType === 'temporal') { + const [slMin, slMax] = getRange(selection); ans.push({ fid: field.fid, type: 'range', - range: [Math.min(...selection), Math.max(...selection)], + range: [slMin, slMax], }); } else { ans.push({ diff --git a/packages/rath-client/src/pages/painter/sample.ts b/packages/rath-client/src/pages/painter/sample.ts index 61944cf2..12d9e2b5 100644 --- a/packages/rath-client/src/pages/painter/sample.ts +++ b/packages/rath-client/src/pages/painter/sample.ts @@ -59,7 +59,9 @@ export function viewSampling (data: IRow[], fields: IFieldMeta[], sampleSize: nu } } for (let [, values] of sampleMap.entries()) { - samples.push(...values) + for (let val of values) { + samples.push(val); + } } return samples } \ No newline at end of file diff --git a/packages/rath-client/src/utils/clean.ts b/packages/rath-client/src/utils/clean.ts index a74ed8e4..f3db67b8 100644 --- a/packages/rath-client/src/utils/clean.ts +++ b/packages/rath-client/src/utils/clean.ts @@ -1,9 +1,10 @@ import { Cleaner } from "visual-insights" import { CleanMethod, IRow } from "../interfaces"; +import { shallowCopyArray } from "./deepcopy"; const { dropNull, simpleClean, useMode: replaceByMode } = Cleaner; function unClean(dataSource: IRow[]) { - return [...dataSource]; + return shallowCopyArray(dataSource); } export function cleanData(dataSource: IRow[], dimensions: string[], measures: string[], method: CleanMethod): IRow[] { diff --git a/packages/rath-client/src/utils/deepcopy.ts b/packages/rath-client/src/utils/deepcopy.ts index fe128fd9..8a53f93a 100644 --- a/packages/rath-client/src/utils/deepcopy.ts +++ b/packages/rath-client/src/utils/deepcopy.ts @@ -1,4 +1,11 @@ // todo replace the deepcopy with a safe and faster one. -export default function deepcopy(dataSource: any) { +export default function deepcopy(dataSource: T): T { return JSON.parse(JSON.stringify(dataSource)) +} +export function shallowCopyArray (arr: T[]): T[] { + const ans: T[] = []; + for (let i = 0; i < arr.length; i++) { + ans.push(arr[i]) + } + return ans; } \ No newline at end of file diff --git a/packages/rath-client/src/workers/loa/service.ts b/packages/rath-client/src/workers/loa/service.ts index 9d9a3bfc..91690272 100644 --- a/packages/rath-client/src/workers/loa/service.ts +++ b/packages/rath-client/src/workers/loa/service.ts @@ -28,7 +28,6 @@ function univarService(dataSource: IRow[], fields: IFieldMeta[], props: any) { function patternService (dataSource: IRow[], fields: IFieldMeta[], props: IPattern) { const core = new NextVICore(dataSource, fields); - core.firstPattern(); const ans = core.createHighOrderPatterns(props); return ans } diff --git a/yarn.lock b/yarn.lock index 27af620a..bf70f9b5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1928,14 +1928,13 @@ dependencies: localforage "^1.10.0" -"@kanaries/graphic-walker@^0.2.6": - version "0.2.6" - resolved "https://registry.npmmirror.com/@kanaries/graphic-walker/-/graphic-walker-0.2.6.tgz#9cc2c942432cba11069e75559b9090f344f91df0" - integrity sha512-V6cWGRUEdB/IGgIstXFZqCu5rl7wJ6r0rEOz7ATTO260UN9cjypVcRCpMB95ybGdvkUk0T8jlFbcEonMNufVCQ== +"@kanaries/graphic-walker@0.2.7": + version "0.2.7" + resolved "https://registry.npmmirror.com/@kanaries/graphic-walker/-/graphic-walker-0.2.7.tgz#ef8bf9b391d866dfa41d1c895f389bfc3b1bd961" + integrity sha512-auqe6DCVQGUuI7vg/VZ27w4V0x+x5LQkjLGaFGFLBBSVPOmM/+i4SZCxhAognwElsLBXGPxR3hCBVDqplJbDKg== dependencies: "@heroicons/react" "^2.0.8" "@kanaries/web-data-loader" "0.1.5" - "@types/styled-components" "^5.1.26" autoprefixer "^10.3.5" i18next "^21.9.1" i18next-browser-languagedetector "^6.1.5" @@ -1944,13 +1943,10 @@ mobx-react-lite "^3.2.1" postcss "^8.3.7" re-resizable "^6.9.8" - react "^17.0.2" react-beautiful-dnd "^13.1.1" - react-dom "^17.0.2" react-i18next "^11.18.6" react-json-view "^1.21.3" rxjs "^7.3.0" - styled-components "^5.3.6" tailwindcss "^2.2.15" uuid "^8.3.2" vega "^5.22.1" @@ -2775,7 +2771,7 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== -"@types/react-dom@^17.0.1", "@types/react-dom@^17.x": +"@types/react-dom@^17.0.1": version "17.0.17" resolved "https://registry.npmmirror.com/@types/react-dom/-/react-dom-17.0.17.tgz#2e3743277a793a96a99f1bf87614598289da68a1" integrity sha512-VjnqEmqGnasQKV0CWLevqMTXBYG9GbwuE6x3VetERLh0cq2LTptFE73MrQi2S7GkKXCf2GgwItB/melLnxfnsg== @@ -2813,7 +2809,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^17", "@types/react@^17.0.2", "@types/react@^17.x": +"@types/react@*", "@types/react@^17", "@types/react@^17.0.2": version "17.0.50" resolved "https://registry.npmmirror.com/@types/react/-/react-17.0.50.tgz#39abb4f7098f546cfcd6b51207c90c4295ee81fc" integrity sha512-ZCBHzpDb5skMnc1zFXAXnL3l1FAdi+xZvwxK+PkglMmBrwjpp9nKaWuEvrGnSifCJmBFGxZOOFuwC6KH/s0NuA== @@ -2866,7 +2862,7 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== -"@types/styled-components@^5.1.26", "@types/styled-components@^5.1.7": +"@types/styled-components@^5.1.7": version "5.1.26" resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.26.tgz#5627e6812ee96d755028a98dae61d28e57c233af" integrity sha512-KuKJ9Z6xb93uJiIyxo/+ksS7yLjS1KzG6iv5i78dhVg/X3u5t1H7juRWqVmodIdz6wGVaIApo1u01kmFRdJHVw== @@ -9499,7 +9495,7 @@ react-dev-utils@^12.0.1: strip-ansi "^6.0.1" text-table "^0.2.0" -react-dom@^17.0.1, react-dom@^17.0.2: +react-dom@^17.0.1: version "17.0.2" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== @@ -9683,7 +9679,7 @@ react-transition-group@^4.4.0: loose-envify "^1.4.0" prop-types "^15.6.2" -react@^17.0.1, react@^17.0.2: +react@^17.0.1: version "17.0.2" resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== @@ -10643,7 +10639,7 @@ style-mod@^4.0.0: resolved "https://registry.npmmirror.com/style-mod/-/style-mod-4.0.0.tgz#97e7c2d68b592975f2ca7a63d0dd6fcacfe35a01" integrity sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw== -"styled-components@^3.4.10 || ^5.0.1", styled-components@^5.3.5, styled-components@^5.3.6: +"styled-components@^3.4.10 || ^5.0.1", styled-components@^5.3.5: version "5.3.6" resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.6.tgz#27753c8c27c650bee9358e343fc927966bfd00d1" integrity sha512-hGTZquGAaTqhGWldX7hhfzjnIYBZ0IXQXkCYdvF1Sq3DsUaLx6+NTHC5Jj1ooM2F68sBiVz3lvhfwQs/S3l6qg==