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

refactor visual-insights #17

Merged
merged 6 commits into from
Jan 19, 2020
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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@ yarn-error.log*
.vscode

safety
dist
dist

coverage
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
language: node_js
node_js:
- "12"
- "12"
after_success:
- npm run coveralls
3 changes: 1 addition & 2 deletions packages/frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from "react";
import React from "react";
import { useGlobalState, GlobalStateProvider } from "./state";
import { Pivot, PivotItem } from "office-ui-fabric-react";
import { useComposeState } from "./utils/index";
Expand Down Expand Up @@ -52,7 +52,6 @@ function App() {
pivotKey: pivotList[0].itemKey
}
});

return (
<div>
<div className="header-bar">
Expand Down
21 changes: 15 additions & 6 deletions packages/frontend/src/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@ import {
combineFieldsService,
generateDashBoard,
ViewSpace,
Subspace,
clusterMeasures
} from "./service";
import { GlobalState, StateUpdater } from './state';



type Action<T> = (state: GlobalState, updateState: (updater:StateUpdater<GlobalState>) => void, params: T) => any;
type Action<T> = (select: () => GlobalState, updateState: (updater:StateUpdater<GlobalState>) => void, params: T) => any;


const univariateSummary: Action<{dataSource: DataSource; fields: BIField[]}> = async (state, updateState, params) => {
const univariateSummary: Action<{dataSource: DataSource; fields: BIField[]}> = async (select, updateState, params) => {
const { dataSource, fields } = params;
const state = select();
const dimensions = fields
.filter(field => field.type === "dimension")
.map(field => field.name);
Expand Down Expand Up @@ -117,8 +119,9 @@ interface SubspaceSeachParams {
measures: string[];
operator: OperatorType
}
const subspaceSearch: Action<SubspaceSeachParams> = async (state, updateState, params) => {
const subspaceSearch: Action<SubspaceSeachParams> = async (select, updateState, params) => {
const { groupedData: dataSource, summary, dimensions, measures, operator } = params;
const state = select();
updateState(draft => {
draft.loading.subspaceSearching = true;
});
Expand Down Expand Up @@ -165,8 +168,13 @@ const subspaceSearch: Action<SubspaceSeachParams> = async (state, updateState, p
}
}

const getViewSpaces: Action<any> = async (state, updateState, params) => {
const { cookedDataSource: dataSorce, subspaceList, maxGroupNumber, useServer } = state
interface GetViewSpacesProps {
subspaceList: Subspace[];
maxGroupNumber: number;
useServer: boolean;
}
const getViewSpaces: Action<GetViewSpacesProps> = async (select, updateState, params) => {
const { subspaceList, maxGroupNumber, useServer } = params;
let viewSpaces: ViewSpace[] = [];
try {
viewSpaces = await clusterMeasures(
Expand Down Expand Up @@ -217,7 +225,8 @@ const extractInsights: Action<{dataSource: DataSource; fields: BIField[]}> = asy
}
}

const getDashBoard: Action<{dataSource: DataSource, dimensions: string[], measures: string[]}> = async (state, updateState, params) => {
const getDashBoard: Action<{dataSource: DataSource, dimensions: string[], measures: string[]}> = async (select, updateState, params) => {
const state = select();
const { dataSource, dimensions, measures } = params;
updateState(draft => {
draft.loading.dashBoard = true
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/components/table.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { DetailsList, SelectionMode } from 'office-ui-fabric-react';
import { DataSource, BIField, BIFieldType } from '../global';
import { DataSource, BIField } from '../global';
export interface DataTableProps {
dataSource: DataSource,
fields: BIField[]
Expand Down
36 changes: 8 additions & 28 deletions packages/frontend/src/pages/dashBoard/combinedChart.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useMemo, useEffect, useState } from "react";
import { DashBoard } from "../../service";
import { DataSource, Field, FieldType } from "../../global";
import { DataSource, Field } from "../../global";
import { specification } from "visual-insights";
import { useComposeState } from "../../utils/index";
import { IconButton } from "office-ui-fabric-react";
Expand All @@ -27,28 +27,7 @@ const CombinedChart: React.FC<CombinedChartProps> = props => {
useEffect(() => {
setChartStateList(dashBoard.map(() => false));
}, [dashBoard]);
const filedDomains = useMemo(() => {
const fieldList = dimScores.map(f => f[0]);
let domainDict: {[key: string]: any[]} = {};
let dsLen = dataSource.length;
let fLen = fieldList.length;
for (let i = 0; i < fLen; i++) {
if (dimScores[i][3].type !== 'quantitative') {
continue;
// tmp
}
let fieldName = fieldList[i];
domainDict[fieldName] = [0, 100];
let min = Infinity;
let max = -Infinity;
for (let j = 0; j < dsLen; j++) {
min = Math.min(dataSource[j][fieldName], min)
max = Math.max(dataSource[j][fieldName], max)
}
domainDict[fieldName] = [min, max];
}
return domainDict;
}, [dataSource, dimScores])

const chartSpecList = useMemo(() => {
if (!dashBoard || !dataSource || !dimScores) {
return [];
Expand Down Expand Up @@ -81,7 +60,9 @@ const CombinedChart: React.FC<CombinedChartProps> = props => {
});
}, [dashBoard, dataSource, dimScores]);

const fieldFeatures = dimScores.map(dim => dim[3]);
const fieldFeatures = useMemo(() => {
return dimScores.map(dim => dim[3])
}, [dimScores]);

const specList = useMemo<any[]>(() => {
return chartSpecList.map((spec, index) => {
Expand Down Expand Up @@ -125,7 +106,7 @@ const CombinedChart: React.FC<CombinedChartProps> = props => {
vegaSpec.specIndex = index
return vegaSpec
}) as any;
}, [chartSpecList, filedDomains]);
}, [chartSpecList, fieldFeatures]);

const signalHandler = useMemo(() => {
return dashBoard.map((d, index) => {
Expand All @@ -148,7 +129,7 @@ const CombinedChart: React.FC<CombinedChartProps> = props => {
}
};
});
}, [dashBoard, chartStateList, dimScores, specList]);
}, [dashBoard, chartStateList, setGlobalFilters]);

const vsourceList = useMemo<Array<DataSource>>(() => {
let ans = [];
Expand Down Expand Up @@ -191,8 +172,7 @@ const CombinedChart: React.FC<CombinedChartProps> = props => {
dashBoard,
globalFilters,
dataSource,
chartStateList,
dataSource
chartStateList
]);
return (
<div>
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/pages/dashBoard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useGlobalState } from "../../state";
import CombinedChart from "./combinedChart";

const DashBoardPage: React.FC = props => {
const [state, updateState, dispatch, getters] = useGlobalState();
const [state, , dispatch, getters] = useGlobalState();
const [dashBoardIndex, setDashBoardIndex] = useState(0);
const {
subspaceList,
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/pages/dashBoard/indicatorCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const IndicatorCard: React.FC<IndicatorProps> = props => {
ans = Number(ans.toFixed(2));
}
return numberWithCommas(ans);
}, [dataSource, measures]);
}, [dataSource, measures, operator]);

return (
<Card>
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/pages/dataSource/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useRef, useCallback } from "react";
import React, { useState, useRef } from "react";
import { useGlobalState } from "../../state";
import { FileLoader, useComposeState } from '../../utils/index';
import { ComboBox, PrimaryButton, IconButton, Callout, Stack, CommandBar, ChoiceGroup, IChoiceGroupOption, Slider, Label, Checkbox } from 'office-ui-fabric-react';
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/pages/dataSource/useDataSource.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useMemo } from 'react';
import { useMemo } from 'react';
import { BIField, DataSource, Record } from '../../global';
import { Transform } from '../../utils/index'
import { cleanData, CleanMethod } from './clean';
Expand Down
12 changes: 5 additions & 7 deletions packages/frontend/src/pages/gallery/association/digDimension.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import React, { useMemo } from 'react';
import {
ViewSpace
} from '../../../service';
import { useMemo } from 'react';
import { ViewSpace } from '../../../service';
import { Field, DataSource } from '../../../global';
import { specification } from 'visual-insights';
import { PreferencePanelConfig } from '../../../components/preference';
Expand Down Expand Up @@ -41,7 +39,7 @@ export interface DigDimensionProps {
}

function useDigDimension(props: DigDimensionProps) {
const { viewSpaces, interestedViewSpace, fieldScores, dataSource, visualConfig } = props;
const { viewSpaces, interestedViewSpace, fieldScores, dataSource } = props;
const relatedSpaces = useMemo<ViewSpace[]>(() => {
let ans: ViewSpace[] = []
for (let space of viewSpaces) {
Expand Down Expand Up @@ -69,7 +67,7 @@ function useDigDimension(props: DigDimensionProps) {
}
}
return ans.sort((a, b) => a.relatedScore - b.relatedScore);
}, [relatedSpaces]);
}, [relatedSpaces, interestedViewSpace.measures]);

const viewList = useMemo(() => {
const ans = rankedRelatedSpaces.slice(0, topKRelatedSpace).map(space => {
Expand All @@ -82,7 +80,7 @@ function useDigDimension(props: DigDimensionProps) {
};
})
return ans;
}, [rankedRelatedSpaces, fieldScores])
}, [rankedRelatedSpaces, fieldScores, dataSource])

return viewList
}
Expand Down
6 changes: 3 additions & 3 deletions packages/frontend/src/pages/gallery/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ const Gallery: React.FC<GalleryProps> = props => {
draft.loading.gallery = false;
});
});
}, [subspaceList, dataSource, state.maxGroupNumber]);
}, [subspaceList, dataSource, state.maxGroupNumber, state.useServer, updateState]);

const dimScores = useMemo<[string, number, number, Field][]>(() => {
return [...summary.origin, ...summary.grouped].map(field => {
Expand Down Expand Up @@ -185,12 +185,12 @@ const Gallery: React.FC<GalleryProps> = props => {
console.log(error);
}
}
}, [viewSpaces, currentPage]);
}, [viewSpaces, currentPage, dataSource, dimScores]);
const currentSpace = useMemo<Subspace>(() => {
return subspaceList.find(subspace => {
return subspace.dimensions.join(",") === dataView.dimensions.join(",");
})!;
}, [subspaceList, currentPage, dataView]);
}, [subspaceList, dataView]);
useEffect(() => {
setShowAssociation(false);
}, [currentPage]);
Expand Down
18 changes: 12 additions & 6 deletions packages/frontend/src/pages/gallery/search/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function usePageController (size: number) {
const maxPageNumber = Math.ceil(size / PAGE_SIZE);
const gotoPage = (num: number) => {
let fixPageNum = (num + maxPageNumber) % maxPageNumber;
setCurrentPage(num)
setCurrentPage(fixPageNum)
}

const lastPage = () => {
Expand All @@ -57,13 +57,19 @@ function usePageController (size: number) {
}

const SearchPage: React.FC = props => {
const [state, updateState, dispatch, getters] = useGlobalState();
const [state, , dispatch, getters] = useGlobalState();
const [targetViewSpaces, setTargetViewSpaces] = useState<ViewSpace[]>([]);
const { subspaceList, viewSpaces } = state;
const { subspaceList, viewSpaces, maxGroupNumber, useServer } = state;
const { dimScores } = getters;

useEffect(() => {
dispatch('getViewSpaces', {})
}, [subspaceList])
dispatch('getViewSpaces', {
subspaceList,
maxGroupNumber,
useServer
})
}, [subspaceList, maxGroupNumber, useServer, dispatch])

const fuse = useMemo(() => {
const options: FuseOptions<ViewSpace> = {
keys: [
Expand Down Expand Up @@ -100,7 +106,7 @@ const SearchPage: React.FC = props => {
measures
}
})
}, [state.cookedDataSource, targetViewSpaces, itemRange])
}, [state.cookedDataSource, targetViewSpaces, itemRange, dimScores])

return (
<div>
Expand Down
8 changes: 4 additions & 4 deletions packages/frontend/src/pages/notebook/cluster.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect, useMemo, useRef } from 'react';
import { kruskalMST } from 'visual-insights';
import { Cluster } from 'visual-insights';
import { useGlobalState } from '../../state';
import embed from 'vega-embed';
// cluster should be used for small graph because the number of measure is limited.
Expand Down Expand Up @@ -31,7 +31,7 @@ interface TreeData {
}
const ClusterBoard: React.FC<ClusterBoardProps> = (props) => {
const { adjMatrix, measures, onFocusGroup } = props;
const [state, updateState] = useGlobalState();
const [state, ] = useGlobalState();
const chart = useRef<HTMLDivElement>(null);
// const groups = useMemo<string[][]>(() => {
// return clusterMeasures({
Expand All @@ -44,7 +44,7 @@ const ClusterBoard: React.FC<ClusterBoardProps> = (props) => {
* todo:
* maxGroupNumber = the measures length / max visual channel for measure.
*/
let { edgesInMST, groups } = kruskalMST(adjMatrix, state.maxGroupNumber);
let { edgesInMST, groups } = Cluster.kruskalWithFullMST(adjMatrix, state.maxGroupNumber);
return { edgesInMST, groups }
}, [adjMatrix, state.maxGroupNumber])
const treeData = useMemo<TreeData>(() => {
Expand Down Expand Up @@ -231,7 +231,7 @@ const ClusterBoard: React.FC<ClusterBoardProps> = (props) => {
})
})
}
}, [treeData, measures])
}, [treeData, measures, clusterResult.groups, onFocusGroup])
return <div ref={chart}>
</div>
}
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/pages/notebook/distributionChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const DistributionChart: React.FC<DistributionChartProps> = (props) => {
actions: false
})
}
}, [x, y, dataSource])
}, [x, y, dataSource, fieldType])
return <div ref={chart}></div>
}

Expand Down
3 changes: 1 addition & 2 deletions packages/frontend/src/pages/notebook/fieldAnalysis.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useMemo } from 'react';
import { DetailsList, SelectionMode, IColumn, Icon, HoverCard, IExpandingCardProps } from 'office-ui-fabric-react';
import chroma, { Color } from 'chroma-js';
import chroma from 'chroma-js';
import { FieldSummary } from '../../service';
import DistributionChart from './distributionChart';
import { FieldType, Record } from '../../global';
Expand Down Expand Up @@ -130,7 +130,6 @@ const FieldAnalsis: React.FC<FieldAnalsisProps> = (props) => {
case 'entropy':
case 'maxEntropy':
bgColor = getValueColor(item[column.key], entropyRange);
let fontColor = contrastColor(bgColor)
let bgColorStr = `rgb(${bgColor.join(',')})`
let fontColorStr = `rgb(${contrastColor(bgColor).join(',')})`
return (
Expand Down