Skip to content

Commit

Permalink
feat: add range, domain for channels & color scheme selection (#171)
Browse files Browse the repository at this point in the history
* fix: modal height

* feat: color palette

* fix: didnot fetch data in sometimes

* feat: range scale
  • Loading branch information
islxyqwe authored Sep 27, 2023
1 parent af4697d commit b4b0c2e
Show file tree
Hide file tree
Showing 15 changed files with 575 additions and 252 deletions.
3 changes: 0 additions & 3 deletions packages/graphic-walker/src/components/dataTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,6 @@ const DataTable: React.FC<DataTableProps> = (props) => {
const taskIdRef = useRef(0);

useEffect(() => {
if (statLoading) {
return;
}
setDataLoading(true);
const taskId = ++taskIdRef.current;
dataReadRawServer(computationFunction, size, pageIndex).then(data => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ function classNames(...classes: string[]) {
}

export interface IDropdownSelectOption {
label: string;
label: React.ReactNode;
value: string;
disabled?: boolean;
}
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
Expand Up @@ -23,7 +23,7 @@ const Container = styled.div`
@media (min-width: 1100px) {
width: 880px;
}
max-height: 800px;
max-height: calc(min(800px, 90vh));
overflow: auto;
> div.container {
padding: 0.5em 1em 1em 1em;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,14 @@ export const ColorSchemes = [
value: ['#fbb4ae', '#b3cde3', '#ccebc5', '#decbe4', '#fed9a6', '#ffffcc', '#e5d8bd', '#fddaec', '#f2f2f2'],
},
];

export const extractRGBA = (rgba?: string) => {
if (!rgba) {
return { r: 0, g: 0, b: 0, a: 0 };
}

const arr = rgba.match(/\d+/g) || [];
const [r = 0, g = 0, b = 0, a = 0] = arr.map(Number);
return { r, g, b, a };
};

197 changes: 129 additions & 68 deletions packages/graphic-walker/src/components/visualConfig/index.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,69 @@
import React, { useEffect, useState, useRef, useCallback } from 'react';
import React, { useEffect, useState, useMemo, useCallback } from 'react';
import { observer } from 'mobx-react-lite';
import { runInAction, toJS } from 'mobx';
import { useTranslation } from 'react-i18next';
import { SketchPicker } from 'react-color';

import { useGlobalStore } from '../../store';
import { GLOBAL_CONFIG } from '../../config';
import { IVisualConfig } from '../../interfaces';
import { IConfigScale, IVisualConfig } from '../../interfaces';
import PrimaryButton from '../button/primary';
import DefaultButton from '../button/default';

import Modal from '../modal';
import Toggle from '../toggle';
import DropdownSelect from '../dropdownSelect';
import { ColorSchemes, extractRGBA } from './colorScheme';
import { RangeScale } from './range-scale';

const DEFAULT_COLOR_SCHEME = [
'#5B8FF9',
'#FF6900',
'#FCB900',
'#7BDCB5',
'#00D084',
'#8ED1FC',
'#0693E3',
'#ABB8C3',
'#EB144C',
'#F78DA7',
'#9900EF',
]
const DEFAULT_COLOR_SCHEME = ['#5B8FF9', '#FF6900', '#FCB900', '#7BDCB5', '#00D084', '#8ED1FC', '#0693E3', '#ABB8C3', '#EB144C', '#F78DA7', '#9900EF'];

function useScale(minRange: number, maxRange: number, defaultMinRange?: number, defaultMaxRange?: number) {
const [enableMinDomain, setEnableMinDomain] = useState(false);
const [enableMaxDomain, setEnableMaxDomain] = useState(false);
const [enableRange, setEnableRange] = useState(false);
const [domainMin, setDomainMin] = useState(0);
const [domainMax, setDomainMax] = useState(100);
const [rangeMin, setRangeMin] = useState(defaultMinRange ?? minRange);
const [rangeMax, setRangeMax] = useState(defaultMaxRange ?? maxRange);
const setValue = useCallback((value: IConfigScale) => {
setEnableMaxDomain(value.domainMax !== undefined);
setEnableMinDomain(value.domainMin !== undefined);
setEnableRange(value.rangeMax !== undefined || value.rangeMin !== undefined);
setDomainMin(value.domainMin ?? 0);
setDomainMax(value.domainMax ?? 100);
setRangeMax(value.rangeMax ?? defaultMaxRange ?? maxRange);
setRangeMin(value.rangeMin ?? defaultMinRange ?? minRange);
}, []);

const value = useMemo(
() => ({
...(enableMaxDomain ? { domainMax } : {}),
...(enableMinDomain ? { domainMin } : {}),
...(enableRange ? { rangeMax, rangeMin } : {}),
}),
[enableMaxDomain && domainMax, enableMinDomain && domainMin, enableRange && rangeMax, enableRange && rangeMin]
);

return {
value,
setValue,
enableMaxDomain,
enableMinDomain,
enableRange,
rangeMax,
rangeMin,
domainMax,
domainMin,
setEnableMinDomain,
setEnableMaxDomain,
setEnableRange,
setDomainMin,
setDomainMax,
setRangeMin,
setRangeMax,
};
}

const VisualConfigPanel: React.FC = (props) => {
const { commonStore, vizStore } = useGlobalStore();
Expand Down Expand Up @@ -57,16 +95,9 @@ const VisualConfigPanel: React.FC = (props) => {
const [background, setBackground] = useState<string | undefined>(visualConfig.background);
const [defaultColor, setDefaultColor] = useState({ r: 91, g: 143, b: 249, a: 1 });
const [displayColorPicker, setDisplayColorPicker] = useState(false);

const extractRGBA = useCallback((rgba?: string) => {
if (!rgba) {
return { r: 0, g: 0, b: 0, a: 0 };
}

const arr = rgba.match(/\d+/g) || [];
const [r = 0, g = 0, b = 0, a = 0] = arr.map(Number);
return { r, g, b, a };
}, []);
const [colorPalette, setColorPalette] = useState('');
const opacityValue = useScale(0, 1, 0.3, 0.8);
const sizeValue = useScale(0, 100);

useEffect(() => {
setZeroScale(visualConfig.zeroScale);
Expand All @@ -79,6 +110,9 @@ const VisualConfigPanel: React.FC = (props) => {
timeFormat: visualConfig.format.timeFormat,
normalizedNumberFormat: visualConfig.format.normalizedNumberFormat,
});
setColorPalette(visualConfig.colorPalette ?? '');
opacityValue.setValue(visualConfig.scale?.opacity ?? {});
sizeValue.setValue(visualConfig.scale?.size ?? {});
}, [showVisualConfigPanel]);

return (
Expand All @@ -93,53 +127,78 @@ const VisualConfigPanel: React.FC = (props) => {
setDisplayColorPicker(false);
}}
>
<div className="mb-2">
<h2 className="text-lg mb-4">Scheme</h2>
<div className="flex">
<p className="w-28">Primary Color</p>
<div
onClick={(e) => {
e.stopPropagation();
e.preventDefault();
}}
>
<div
className="w-8 h-5 border-2"
style={{ backgroundColor: `rgba(${defaultColor.r},${defaultColor.g},${defaultColor.b},${defaultColor.a})` }}
onClick={(e) => {
e.stopPropagation();
e.preventDefault();
setDisplayColorPicker(true);
}}
></div>
<div className="absolute left-32 top-22 index-40">
{displayColorPicker && (
<SketchPicker
presetColors={DEFAULT_COLOR_SCHEME}
color={defaultColor}
onChange={(color, event) => {
setDefaultColor({
...color.rgb,
a: color.rgb.a ?? 1,
});
{coordSystem === 'generic' && (
<>
<div className="mb-2">
<h2 className="text-lg mb-4">{t('config.scheme')}</h2>
<div className="flex space-x-6">
<div>
<label className="block text-xs font-medium leading-6">{t('config.primary_color')}</label>
<div
onClick={(e) => {
e.stopPropagation();
e.preventDefault();
}}
>
<div
className="w-8 h-5 border-2"
style={{ backgroundColor: `rgba(${defaultColor.r},${defaultColor.g},${defaultColor.b},${defaultColor.a})` }}
onClick={(e) => {
e.stopPropagation();
e.preventDefault();
setDisplayColorPicker(true);
}}
></div>
<div className="absolute left-32 top-22 index-40">
{displayColorPicker && (
<SketchPicker
presetColors={DEFAULT_COLOR_SCHEME}
color={defaultColor}
onChange={(color, event) => {
setDefaultColor({
...color.rgb,
a: color.rgb.a ?? 1,
});
}}
/>
)}
</div>
</div>
</div>
<div>
<label className="block text-xs font-medium leading-6">{t('config.color_palette')}</label>
<DropdownSelect
buttonClassName="w-48"
selectedKey={colorPalette}
onSelect={setColorPalette}
options={ColorSchemes.map((scheme) => ({
value: scheme.name,
label: (
<>
<div key={scheme.name} className="flex flex-col justify-start items-center">
<div className="font-light">{scheme.name}</div>
<div className="flex w-full">
{scheme.value.map((c, index) => {
return (
<div key={index} className="w-4 h-4 flex-shrink" style={{ backgroundColor: `${c}` }}></div>
);
})}
</div>
</div>
</>
),
}))}
/>
)}
</div>
</div>
<label className="block text-xs font-medium leading-6">{t('config.opacity')}</label>
<RangeScale {...opacityValue} text="opacity" maxRange={1} minRange={0} />
<label className="block text-xs font-medium leading-6">{t('config.size')}</label>
<RangeScale {...sizeValue} text="size" maxRange={100} minRange={0} />
</div>
</div>

{/* {ColorSchemes.map((scheme) => {
return (
<div key={scheme.name} className="flex justify-start items-center">
<div className="font-light mx-2 w-24 ">{scheme.name}</div>
{scheme.value.map((c, index) => {
return <div key={index} className="w-4 h-4" style={{ backgroundColor: `${c}` }}></div>;
})}
</div>
);
})} */}
</div>
<hr className="my-4" />
</>
)}
<h2 className="text-lg mb-4">{t('config.format')}</h2>
<p className="text-xs">
{t(`config.formatGuidesDocs`)}:{' '}
Expand Down Expand Up @@ -252,7 +311,9 @@ const VisualConfigPanel: React.FC = (props) => {
vizStore.setVisualConfig('background', background);
vizStore.setVisualConfig('resolve', resolve);
vizStore.setVisualConfig('primaryColor', `rgba(${defaultColor.r},${defaultColor.g},${defaultColor.b},${defaultColor.a})`);
vizStore.setVisualConfig('colorPalette', colorPalette);
vizStore.setVisualConfig('useSvg', svg);
vizStore.setVisualConfig('scale', { opacity: opacityValue.value, size: sizeValue.value });
commonStore.setShowVisualConfigPanel(false);
});
}}
Expand Down
Loading

1 comment on commit b4b0c2e

@vercel
Copy link

@vercel vercel bot commented on b4b0c2e Sep 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.