Skip to content

Commit

Permalink
Merge pull request #106 from Kanaries/dev
Browse files Browse the repository at this point in the history
daily update merge
  • Loading branch information
jojocys committed Aug 31, 2022
2 parents 9b36249 + 5dce1eb commit 74ff9bd
Show file tree
Hide file tree
Showing 63 changed files with 1,374 additions and 847 deletions.
5 changes: 5 additions & 0 deletions .clocignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
build
dist
datasets
public
1 change: 1 addition & 0 deletions apps/rath-service/models/dataset.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ import "gorm.io/gorm"

type Dataset struct {
gorm.Model

}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"test": "yarn workspace frontend test",
"ui": "npm run test && npm run build && node start.js",
"devfront": "yarn workspace frontend start",
"devback": "yarn workspace backend dev"
"devback": "yarn workspace backend dev",
"count": "cloc --exclude-dir=$(tr '\n' ',' < .clocignore) ."
},
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion packages/connectors/app/controllers/clickHouseProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export async function CHGeneralProxy (ctx: Context) {
for (let [pk, pv] of url.searchParams.entries()) {
paramsObj[pk] = pv;
}
// fs.appendFileSync('./log.sql', `${paramsObj.query}\n`)
// console.log('query', paramsObj.query)
const res = await axios(`${config.clickhouse.protocol}://${config.clickhouse.host}:${config.clickhouse.port}`, {
method: ctx.request.method as 'post' | 'get',
params: {
Expand Down
5 changes: 4 additions & 1 deletion packages/graphic-walker/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@
"require": "./dist/graphic-walker.umd.js"
}
},
"prettier": {
"tabWidth": 4
},
"types": "./dist/index.d.ts",
"dependencies": {
"@heroicons/react": "^1.0.4",
"@heroicons/react": "^2.0.8",
"@kanaries/web-data-loader": "0.1.5",
"autoprefixer": "^10.3.5",
"mobx": "^6.3.3",
Expand Down
18 changes: 12 additions & 6 deletions packages/graphic-walker/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,22 @@ import { Record, IMutField } from './interfaces';
import VisualSettings from './visualSettings';
import { Container, NestContainer } from './components/container';
import ClickMenu from './components/clickMenu';
import InsightBoard from './InsightBoard/index';
import PosFields from './Fields/posFields';
import AestheticFields from './Fields/AestheticFields';
import DatasetFields from './Fields/datasetFields/index';
import InsightBoard from './insightBoard/index';
import PosFields from './fields/posFields';
import AestheticFields from './fields/aestheticFields';
import DatasetFields from './fields/datasetFields/index';
import ReactiveRenderer from './renderer/index';
import DataSourceSegment from './dataSource/index';
import { useGlobalStore } from './store';
import { preAnalysis, destroyWorker } from './services'
import { observer } from 'mobx-react-lite';
import { LightBulbIcon } from '@heroicons/react/outline'
import { LightBulbIcon } from '@heroicons/react/24/outline'
import { toJS } from 'mobx';
import "tailwindcss/tailwind.css"
import './index.css'
import { Specification } from 'visual-insights';
import PureTabs from './components/tabs/pureTab';
import VisNav from './segments/visNav';

export interface EditorProps {
dataSource?: Record[];
Expand Down Expand Up @@ -68,8 +70,12 @@ const App: React.FC<EditorProps> = props => {
return (
<div className="App">
<DataSourceSegment preWorkDone={insightReady} />
<div className='px-2 mx-2'>
<VisNav />
{/* <PureTabs tabs={[{label: 'a', key: 'a'}, {label: 'b', key: 'b'}]} selectedKey='a' onSelected={() => {}} /> */}
</div>
<Container style={{ marginTop: '0em', borderTop: 'none' }}>
<VisualSettings />
<Container>
<div className="grid grid-cols-12 xl:grid-cols-6">
<div className="col-span-3 xl:col-span-1">
<DatasetFields />
Expand Down
2 changes: 1 addition & 1 deletion packages/graphic-walker/src/components/dataTypeIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { IMutField } from "../interfaces";
import { DocumentTextIcon, HashtagIcon, CalendarIcon } from '@heroicons/react/outline';
import { DocumentTextIcon, HashtagIcon, CalendarIcon } from '@heroicons/react/24/outline';

const DataTypeIcon: React.FC<{dataType: IMutField['semanticType']; analyticType: IMutField['analyticType']}> = props => {
const { dataType, analyticType } = props;
Expand Down
2 changes: 1 addition & 1 deletion packages/graphic-walker/src/components/liteForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export const LiteForm = styled.div`
display: flex;
align-items: center;
.item{
margin: 0em 1em;
margin: 0em 8px;
display: flex;
align-items: center;
>label {
Expand Down
2 changes: 1 addition & 1 deletion packages/graphic-walker/src/components/modal.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import styled from 'styled-components';
import { XCircleIcon } from '@heroicons/react/outline';
import { XCircleIcon } from '@heroicons/react/24/outline';
const Container = styled.div`
width: 880px;
max-height: 800px;
Expand Down
6 changes: 3 additions & 3 deletions packages/graphic-walker/src/components/sizeSetting.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ArrowsExpandIcon, XCircleIcon, XIcon } from "@heroicons/react/outline";
import { ArrowsPointingOutIcon, XMarkIcon } from "@heroicons/react/24/outline";
import React from "react";
import { useState } from "react";

Expand All @@ -13,7 +13,7 @@ const SizeSetting: React.FC<SizeSettingProps> = props => {
const [show, setShow] = useState<boolean>(false);

return <div className="leading-none cursor-pointer">
<ArrowsExpandIcon
<ArrowsPointingOutIcon
onClick={() => {
setShow(v => !v)
}}
Expand All @@ -22,7 +22,7 @@ const SizeSetting: React.FC<SizeSettingProps> = props => {
{
show && <div className="absolute z-auto bg-white p-4 border border-gray-200 shadow">
<div>
<XIcon
<XMarkIcon
className="text-gray-900 absolute right-2 top-2 w-4 cursor-pointer hover:bg-red-100"
onClick={(e) => {
setShow(false);
Expand Down
59 changes: 59 additions & 0 deletions packages/graphic-walker/src/components/tabs/pureTab.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React, { useCallback, useEffect, useState } from "react";

function classNames(...classes: string[]) {
return classes.filter(Boolean).join(' ')
}

export interface ITabOption {
label: string;
key: string;
}
interface PureTabsProps {
tabs: ITabOption[];
selectedKey: string;
onSelected: (selectedKey: string, index: number) => void;
allowEdit?: boolean;
onEditLabel?: (label: string, index: number) => void;
}
export default function PureTabs(props: PureTabsProps) {
const { tabs, selectedKey, onSelected, allowEdit, onEditLabel } = props;
const [editList, setEditList] = useState<boolean[]>([]);
const clearEditStatus = useCallback(() => {
setEditList(new Array(tabs.length).fill(false))
}, [tabs.length])
useEffect(() => {
clearEditStatus
}, [clearEditStatus])
return (
<div className="border-b border-gray-200 overflow-x-auto" onMouseLeave={clearEditStatus}>
<nav className="-mb-px flex border-gray-300 border-l" aria-label="Tabs">
{tabs.map((tab, tabIndex) => (
<span
dangerouslySetInnerHTML={{ __html: tab.label }}
onClick={() => {
onSelected(tab.key, tabIndex)
}}
onDoubleClick={() => {
setEditList(v => {
const nv = [...v];
nv[tabIndex] = true;
return nv
})
}}
contentEditable={editList[tabIndex]}
onInput={(e) => {
onEditLabel && onEditLabel(`${e.currentTarget.textContent}`, tabIndex)
}}
key={tab.key}
className={classNames(
tab.key === selectedKey
? "border-transparent text-black bg-gray-100"
: "text-gray-500 hover:text-gray-700 hover:border-gray-300",
"whitespace-nowrap border-gray-300 py-1 px-2 border-t border-r botder-b text-sm cursor-pointer"
)}
/>
))}
</nav>
</div>
);
}
4 changes: 2 additions & 2 deletions packages/graphic-walker/src/dataSource/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Modal from '../components/modal';
// import DataSourcePanel from './pannel';
import DataSelection from './dataSelection';
import { useGlobalStore } from '../store';
import { CheckCircleIcon, RefreshIcon } from '@heroicons/react/outline';
import { CheckCircleIcon, ArrowPathIcon } from '@heroicons/react/24/outline';

interface DSSegmentProps {
preWorkDone: boolean;
Expand Down Expand Up @@ -45,7 +45,7 @@ const DataSourceSegment: React.FC<DSSegmentProps> = props => {
</Modal>
)}
{ preWorkDone && <CheckCircleIcon className="text-green-500 w-5 inline-block ml-2" /> }
{ !preWorkDone && <RefreshIcon className="text-yellow-500 w-5 inline-block ml-2" />}
{ !preWorkDone && <ArrowPathIcon className="text-yellow-500 w-5 inline-block ml-2" />}
</Container>
}

Expand Down
10 changes: 5 additions & 5 deletions packages/graphic-walker/src/dataSource/utils.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { Record, IMutField } from '../interfaces';
import { IRow, IMutField } from '../interfaces';
import { Insight } from 'visual-insights';

export function transData(dataSource: Record[]): {
dataSource: Record[];
export function transData(dataSource: IRow[]): {
dataSource: IRow[];
fields: IMutField[]
} {
if (dataSource.length === 0) return {
dataSource: [],
fields: []
};
let ans: Record[] = [];
let ans: IRow[] = [];
const keys = Object.keys(dataSource[0]);
// TODO: 冗余设计,单变量统计被进行了多次重复计算。另外对于这种不完整的分析任务,不建议使用VIEngine。
const vie = new Insight.VIEngine();
Expand All @@ -25,7 +25,7 @@ export function transData(dataSource: Record[]): {
vie.univarSelection('percent', 1);
const fields = vie.fields;
for (let record of dataSource) {
const newRecord: Record = {};
const newRecord: IRow = {};
for (let field of fields) {
if (field.dataType === 'number' || field.dataType === 'integer') {
newRecord[field.key] = Number(record[field.key])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const MeaFields: React.FC<Props> = props => {
>
<DataTypeIcon dataType={f.semanticType} analyticType={f.analyticType} /> {f.name}&nbsp;
{
f.fid && !snapshot.isDragging && <select className="float-right" value="" onChange={e => {
f.fid && !snapshot.isDragging && <select className="bg-transparent text-gray-700 float-right focus:outline-none focus:border-gray-500" value="" onChange={e => {
if (e.target.value === 'bin') {
vizStore.createBinField('measures', index)
} else if (e.target.value === 'log10') {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SortAscendingIcon, SortDescendingIcon } from '@heroicons/react/outline';
import { BarsArrowDownIcon, BarsArrowUpIcon } from '@heroicons/react/24/outline';
import { observer } from 'mobx-react-lite';
import React from 'react';
import { DraggableProvided } from 'react-beautiful-dnd';
Expand Down Expand Up @@ -36,8 +36,8 @@ const OBPill: React.FC<PillProps> = props => {
}
</select>
)}
{field.analyticType === 'dimension' && field.sort === 'ascending' && <SortAscendingIcon className='float-right w-3' />}
{field.analyticType === 'dimension' && field.sort === 'descending' && <SortDescendingIcon className='float-right w-3' />}
{field.analyticType === 'dimension' && field.sort === 'ascending' && <BarsArrowUpIcon className='float-right w-3' />}
{field.analyticType === 'dimension' && field.sort === 'descending' && <BarsArrowDownIcon className='float-right w-3' />}
</Pill>
}

Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion packages/graphic-walker/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import App, { EditorProps } from './App';
import { StoreWrapper } from './store/index';
import { FieldsContextWrapper } from './Fields/fieldsContext';
import { FieldsContextWrapper } from './fields/fieldsContext';

export const GraphicWalker: React.FC<EditorProps> = props => {
return <StoreWrapper>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import React, { useEffect, useState, useMemo, useRef } from 'react';
import { Record, IField, Filters, IMeasure } from '../interfaces';
import embed from 'vega-embed';
import { Insight, Utils, UnivariateSummary } from 'visual-insights';
import ReactJson from 'react-json-view';
import { IField, Filters, IMeasure, IRow } from '../interfaces';
import { baseVis, IReasonType } from './std2vegaSpec';
import embed from 'vega-embed';
import { getExplaination, IVisSpace } from '../services';
import RadioGroupButtons from './radioGroupButtons';
import { IExplaination, IMeasureWithStat } from '../insights';
import { mergeMeasures } from './utils';
import ReactJson from 'react-json-view';
import { formatFieldName, mergeMeasures } from './utils'


const collection = Insight.IntentionWorkerCollection.init();

Expand All @@ -24,7 +25,7 @@ interface SubSpace {
}

interface InsightMainBoardProps {
dataSource: Record[];
dataSource: IRow[];
fields: IField[];
filters?: Filters;
viewDs: IField[];
Expand Down Expand Up @@ -83,10 +84,6 @@ const InsightMainBoard: React.FC<InsightMainBoardProps> = props => {
}
}, [fields, viewDs, viewMs, measWithTypes, filters, dimsWithTypes, measWithTypes, dataSource])

const fieldsWithType = useMemo(() => {
return [...dimsWithTypes, ...measWithTypes];
}, [dimsWithTypes, measWithTypes])

useEffect(() => {
const RecSpace = recSpaces[visIndex];
const visSpec = visSpaces[visIndex];
Expand All @@ -109,7 +106,7 @@ const InsightMainBoard: React.FC<InsightMainBoardProps> = props => {
field: m.key,
as: m.key,
})),
fieldsWithType as any,
fields,
RecSpace.type as IReasonType,
true,
true
Expand All @@ -118,15 +115,15 @@ const InsightMainBoard: React.FC<InsightMainBoardProps> = props => {
embed(container.current, _vegaSpec);
}
}
}, [visIndex, recSpaces, visSpaces, fieldsWithType, dataSource])
}, [visIndex, recSpaces, visSpaces, fields, dataSource])

const FilterDesc = useMemo<React.ReactElement[]>(() => {
if (filters) {
const dimValues = Object.keys(filters)
.filter(k => filters[k].length > 0)
.map((k, ki) => {
return <div key={`dim-${ki}`}>
<div className="inline bg-gray-400 p-1 rounded underline text-white">{k}</div>
<div className="inline bg-gray-400 p-1 rounded underline text-white">{formatFieldName(k, fields)}</div>
<div className="inline text-lg ml-1 mr-1">=</div>
<div className="inline bg-blue-600 p-1 rounded text-white">{filters[k]}</div>
</div>
Expand All @@ -139,7 +136,7 @@ const InsightMainBoard: React.FC<InsightMainBoardProps> = props => {
const valueDesc = useMemo<React.ReactElement[]>(() => {
const meaStatus = valueExp.map((mea, mi) =>
<div key={`mea-${mi}`}>
<span className="bg-gray-400 p-1 rounded underline text-white">{mea.key}({mea.op})</span>的取值<span className="bg-red-500 p-1 rounded text-white">{mea.score === 1 ? '大于' : '小于'}预期 </span>
<span className="bg-gray-400 p-1 rounded underline text-white">{formatFieldName(mea.key, fields)}({mea.op})</span>的取值<span className="bg-red-500 p-1 rounded text-white">{mea.score === 1 ? '大于' : '小于'}预期 </span>
</div>
);
return meaStatus
Expand All @@ -157,7 +154,7 @@ const InsightMainBoard: React.FC<InsightMainBoardProps> = props => {
<div className="animate-spin inline-block mr-2 ml-2 w-16 h-16 rounded-full border-t-2 border-l-2 border-blue-500"></div>
)}
<div style={{ display: 'flex' }}>
<div style={{ flexBasis: '200px', flexShrink: 0 }}>
<div style={{ flexBasis: '200px', flexShrink: 0, maxHeight: '800px', overflowY: 'auto' }}>
<RadioGroupButtons
choosenIndex={visIndex}
options={recSpaces.map((s, i) => ({
Expand All @@ -175,8 +172,8 @@ const InsightMainBoard: React.FC<InsightMainBoardProps> = props => {
<div ref={container}></div>
{recSpaces[visIndex] && (
<div>
维度是{recSpaces[visIndex].dimensions.join(', ')}<br />
度量是{recSpaces[visIndex].measures.map((m) => m.key).join(', ')}<br />
维度是{recSpaces[visIndex].dimensions.map(f => formatFieldName(f, fields)).join(', ')}<br />
度量是{recSpaces[visIndex].measures.map((m) => m.key).map(f => formatFieldName(f, fields)).join(', ')}<br />
此时具有
{recSpaces[visIndex].type
? ReasonTypeNames[recSpaces[visIndex].type!]
Expand All @@ -189,7 +186,7 @@ const InsightMainBoard: React.FC<InsightMainBoardProps> = props => {
recSpaces[visIndex].description.intMeasures
.map(
(mea: any) =>
`${mea.key}(${mea.op})}的取值${
`${formatFieldName(mea.key, fields)}(${mea.op})}的取值${
mea.score === 1 ? '大于' : '小于'
}预期`
)
Expand Down

0 comments on commit 74ff9bd

Please sign in to comment.