Skip to content
Snippets Groups Projects
Commit eb0b60f9 authored by Behrisch, M. (Michael)'s avatar Behrisch, M. (Michael)
Browse files

fix: :sparkles: adds multiple attributes per node to dotplotvis

Once more than one attribute will be pulled into the querypanel
the dotplot vis needs to show also multiple (coordinated) dotplots
parent d72639c2
No related branches found
No related tags found
1 merge request!34feat: :sparkles: adds vega dotplot for 0D queries
Pipeline #126249 failed
......@@ -15,182 +15,374 @@ export const DotPlotsVis = React.memo((props: DotPlotsVisProps) => {
const dispatch = useAppDispatch();
const theme = useTheme();
let [oneRowPoints, setOneRowPoints] = useState([]);
let [minMax, setMinMax] = useState([]);
let [attributeName, setAttributeName] = useState('');
const [dotPlotSpec, setDotPlotSpec] = useState<any>([]);
// let [oneRowPoints, setOneRowPoints] = useState<number[]>([]);
// let [minMax, setMinMax] = useState<number[]>([]);
// let [attributeName, setAttributeName] = useState<string>('');
// let [spec, setSpec] = useState({});
let spec = {
$schema: 'https://vega.github.io/schema/vega/v5.json',
description:
'A dot plot example depicting the distribution of animal sleep times.',
width: 500,
padding: 5,
autosize: 'pad',
signals: [
{
name: 'step',
value: (minMax[1] - minMax[0]) / 40, // default 40 bins
bind: {
input: 'range',
min: (minMax[1] - minMax[0]) / 100, // 4 bins - 100 bins
max: (minMax[1] - minMax[0]) / 10, // max 100 bins
step: 1,
},
},
// {
// name: 'offset',
// value: 'zero',
// bind: { input: 'radio', options: ['zero', 'center'] },
// },
// {
// name: 'smooth',
// value: true,
// bind: { input: 'checkbox' },
// },
{ name: 'size', update: "scale('x', step) - scale('x', 0)" },
{ name: 'area', update: 'size * size' },
{ name: 'ddh', update: '(span(ddext) + 1) * size' },
{ name: 'hdh', update: '(span(hdext) + 1) * size' },
{ name: 'height', update: 'max(ddh, hdh)' },
],
data: [
{
name: 'points',
values: oneRowPoints,
transform: [
{
type: 'dotbin',
field: 'data',
// smooth: { signal: 'smooth' },
smooth: 'true',
step: { signal: 'step' },
},
{
type: 'stack',
groupby: ['bin'],
// offset: { signal: 'offset' },
offset: 'zero',
as: ['d0', 'd1'],
},
{
type: 'extent',
field: 'd1',
signal: 'ddext',
},
{
type: 'extent',
field: 'data',
signal: 'ext',
},
{
type: 'bin',
field: 'data',
step: { signal: 'step' },
extent: { signal: 'ext' },
},
{
type: 'stack',
// offset: { signal: 'offset' },
offset: 'zero',
// let spec = {
// $schema: 'https://vega.github.io/schema/vega/v5.json',
// description:
// 'A dot plot example depicting the distribution of animal sleep times.',
// width: 500,
// padding: 5,
// autosize: 'pad',
groupby: ['bin0'],
},
{
type: 'extent',
field: 'y0',
signal: 'hdext',
},
],
},
],
scales: [
{
name: 'x',
domain: [minMax[0], minMax[1]],
range: 'width',
},
{
name: 'ddy',
domain: { signal: '[0, ddh / size]' },
range: { signal: '[height, height - ddh]' },
},
{
name: 'hdy',
domain: { signal: '[0, hdh / size]' },
range: { signal: '[height, height - hdh]' },
},
],
marks: [
{
type: 'group',
encode: {
update: {
width: { signal: 'width' },
height: { signal: 'height' },
},
},
axes: [
{
scale: 'x',
orient: 'bottom',
tickCount: 5,
title: 'Histogram (' + attributeName + ')',
},
],
marks: [
{
type: 'symbol',
from: { data: 'points' },
encode: {
update: {
x: { scale: 'x', signal: '(datum.bin0 + datum.bin1) / 2' },
y: { scale: 'hdy', signal: 'datum.y0 + 0.5' },
size: { signal: 'area' },
// fill: { value: 'steelblue' },
fill: { value: theme.palette.primary.light },
},
enter: {
tooltip: {
signal:
"{'Value range': format(datum.bin0, '0.1f') + ' - ' + format(datum.bin1, '0.1f')}",
},
},
hover: { fill: { value: theme.palette.primary.dark } },
},
},
],
},
],
};
// signals: [
// {
// name: 'step',
// value: (minMax[1] - minMax[0]) / 40, // default 40 bins
// bind: {
// input: 'range',
// min: (minMax[1] - minMax[0]) / 100, // 4 bins - 100 bins
// max: (minMax[1] - minMax[0]) / 10, // max 100 bins
// step: 1,
// },
// },
// // {
// // name: 'offset',
// // value: 'zero',
// // bind: { input: 'radio', options: ['zero', 'center'] },
// // },
// // {
// // name: 'smooth',
// // value: true,
// // bind: { input: 'checkbox' },
// // },
// { name: 'size', update: "scale('x', step) - scale('x', 0)" },
// { name: 'area', update: 'size * size' },
// { name: 'ddh', update: '(span(ddext) + 1) * size' },
// { name: 'hdh', update: '(span(hdext) + 1) * size' },
// { name: 'height', update: 'max(ddh, hdh)' },
// ],
// data: [
// {
// name: 'points',
// values: oneRowPoints,
// transform: [
// {
// type: 'dotbin',
// field: 'data',
// // smooth: { signal: 'smooth' },
// smooth: 'true',
// step: { signal: 'step' },
// },
// {
// type: 'stack',
// groupby: ['bin'],
// // offset: { signal: 'offset' },
// offset: 'zero',
// as: ['d0', 'd1'],
// },
// {
// type: 'extent',
// field: 'd1',
// signal: 'ddext',
// },
// {
// type: 'extent',
// field: 'data',
// signal: 'ext',
// },
// {
// type: 'bin',
// field: 'data',
// step: { signal: 'step' },
// extent: { signal: 'ext' },
// },
// {
// type: 'stack',
// // offset: { signal: 'offset' },
// offset: 'zero',
// groupby: ['bin0'],
// },
// {
// type: 'extent',
// field: 'y0',
// signal: 'hdext',
// },
// ],
// },
// ],
// scales: [
// {
// name: 'x',
// domain: [minMax[0], minMax[1]],
// range: 'width',
// },
// {
// name: 'ddy',
// domain: { signal: '[0, ddh / size]' },
// range: { signal: '[height, height - ddh]' },
// },
// {
// name: 'hdy',
// domain: { signal: '[0, hdh / size]' },
// range: { signal: '[height, height - hdh]' },
// },
// ],
// marks: [
// {
// type: 'group',
// encode: {
// update: {
// width: { signal: 'width' },
// height: { signal: 'height' },
// },
// },
// axes: [
// {
// scale: 'x',
// orient: 'bottom',
// tickCount: 5,
// tickRound: true,
// tickOpacity: 0.5,
// tickCap: 'round',
// tickExtra: true,
// // tickWidth: 2,
// // TODO: adapt the tick according to theme/new design https://vega.github.io/vega/docs/axes/
// labelColor: theme.palette.text.secondary,
// // labelFont: theme.typography.body2.fontFamily,
// // labelFontSize: theme.typography.body2.fontSize,
// // labelFontWeight: theme.typography.body2.fontWeight,
// // labelFontStyle: theme.typography.body2.fontStyle,
// title: 'Histogram (' + attributeName + ')',
// },
// ],
// marks: [
// {
// type: 'symbol',
// from: { data: 'points' },
// encode: {
// update: {
// x: { scale: 'x', signal: '(datum.bin0 + datum.bin1) / 2' },
// y: { scale: 'hdy', signal: 'datum.y0 + 0.5' },
// size: { signal: 'area' },
// // fill: { value: 'steelblue' },
// fill: { value: theme.palette.primary.light },
// },
// enter: {
// tooltip: {
// signal:
// "{'Value range': format(datum.bin0, '0.1f') + ' - ' + format(datum.bin1, '0.1f')}",
// },
// },
// hover: { fill: { value: theme.palette.primary.dark } },
// },
// },
// ],
// },
// ],
// };
useEffect(() => {
console.log('update dotplotvis useEffect', graphQueryResult);
if (graphQueryResult) {
const rowPoints: number[] = [];
for (let i = 0; i < graphQueryResult.nodes.length; i++) {
// const attributes = graphQueryResult.nodes[i].attributes
const value = graphQueryResult.nodes[i].attributes.attribute0;
rowPoints.push(value);
}
console.log(
'update dotplotvis useEffect',
graphQueryResult,
graphQueryResult.nodes[0].attributes
);
if (graphQueryResult && graphQueryResult.nodes.length > 0) {
const node = graphQueryResult.nodes[0];
const attributes = node.attributes;
for (const [key, value] of Object.entries(attributes)) {
// console.log(`${key}: ${value}`);
setMinMax([Math.min(...rowPoints), Math.max(...rowPoints)]);
setOneRowPoints(rowPoints);
setAttributeName('attribute0'); //fake for simple version. needs to be determined from query result
if (typeof value == 'number') {
// console.log('number', value, key);
const rowPoints: number[] = [];
for (let i = 0; i < graphQueryResult.nodes.length; i++) {
const value = graphQueryResult.nodes[i].attributes[key];
rowPoints.push(value);
}
const dotPlotSpec = generateNewDotPlotSpec(rowPoints, key);
setDotPlotSpec((oldArray: any) => [...oldArray, dotPlotSpec]);
} else {
console.log('attribute is not number: TBD', key);
}
}
}
}, [graphQueryResult]);
useEffect(() => {
return () => {
setDotPlotSpec([]);
console.log('unloaded dotplotvis');
};
}, []);
function generateNewDotPlotSpec(rowPoints: number[], attributeName: string) {
const minMax = [Math.min(...rowPoints), Math.max(...rowPoints)];
return {
$schema: 'https://vega.github.io/schema/vega/v5.json',
description:
'A dot plot example depicting the distribution of animal sleep times.',
width: 500,
padding: 5,
autosize: 'pad',
signals: [
{
name: 'step',
value: (minMax[1] - minMax[0]) / 40, // default 40 bins
bind: {
input: 'range',
min: (minMax[1] - minMax[0]) / 100, // 4 bins - 100 bins
max: (minMax[1] - minMax[0]) / 10, // max 100 bins
step: 1,
},
},
// {
// name: 'offset',
// value: 'zero',
// bind: { input: 'radio', options: ['zero', 'center'] },
// },
// {
// name: 'smooth',
// value: true,
// bind: { input: 'checkbox' },
// },
{ name: 'size', update: "scale('x', step) - scale('x', 0)" },
{ name: 'area', update: 'size * size' },
{ name: 'ddh', update: '(span(ddext) + 1) * size' },
{ name: 'hdh', update: '(span(hdext) + 1) * size' },
{ name: 'height', update: 'max(ddh, hdh)' },
],
data: [
{
name: 'points',
values: rowPoints,
transform: [
{
type: 'dotbin',
field: 'data',
// smooth: { signal: 'smooth' },
smooth: 'true',
step: { signal: 'step' },
},
{
type: 'stack',
groupby: ['bin'],
// offset: { signal: 'offset' },
offset: 'zero',
as: ['d0', 'd1'],
},
{
type: 'extent',
field: 'd1',
signal: 'ddext',
},
{
type: 'extent',
field: 'data',
signal: 'ext',
},
{
type: 'bin',
field: 'data',
step: { signal: 'step' },
extent: { signal: 'ext' },
},
{
type: 'stack',
// offset: { signal: 'offset' },
offset: 'zero',
groupby: ['bin0'],
},
{
type: 'extent',
field: 'y0',
signal: 'hdext',
},
],
},
],
scales: [
{
name: 'x',
domain: [minMax[0], minMax[1]],
range: 'width',
},
{
name: 'ddy',
domain: { signal: '[0, ddh / size]' },
range: { signal: '[height, height - ddh]' },
},
{
name: 'hdy',
domain: { signal: '[0, hdh / size]' },
range: { signal: '[height, height - hdh]' },
},
],
marks: [
{
type: 'group',
encode: {
update: {
width: { signal: 'width' },
height: { signal: 'height' },
},
},
axes: [
{
scale: 'x',
orient: 'bottom',
tickCount: 5,
tickRound: true,
tickOpacity: 0.5,
tickCap: 'round',
tickExtra: true,
// tickWidth: 2,
// TODO: adapt the tick according to theme/new design https://vega.github.io/vega/docs/axes/
labelColor: theme.palette.text.secondary,
// labelFont: theme.typography.body2.fontFamily,
// labelFontSize: theme.typography.body2.fontSize,
// labelFontWeight: theme.typography.body2.fontWeight,
// labelFontStyle: theme.typography.body2.fontStyle,
title: 'Histogram (' + attributeName + ')',
},
],
marks: [
{
type: 'symbol',
from: { data: 'points' },
encode: {
update: {
x: { scale: 'x', signal: '(datum.bin0 + datum.bin1) / 2' },
y: { scale: 'hdy', signal: 'datum.y0 + 0.5' },
size: { signal: 'area' },
// fill: { value: 'steelblue' },
fill: { value: theme.palette.primary.light },
},
enter: {
tooltip: {
signal:
"{'Value range': format(datum.bin0, '0.1f') + ' - ' + format(datum.bin1, '0.1f')}",
},
},
hover: { fill: { value: theme.palette.primary.dark } },
},
},
],
},
],
};
}
const loading = props.loading;
return (
......@@ -204,7 +396,10 @@ export const DotPlotsVis = React.memo((props: DotPlotsVisProps) => {
}}
>
<h1>DotPlotsVis</h1>
<Vega spec={spec} />
{/* <Vega spec={spec} /> */}
{dotPlotSpec.map((spec: any, i: number) => (
<Vega key={i} spec={spec} />
))}
<div id="vis"></div>
</div>
</div>
......@@ -230,4 +425,4 @@ export const DotPlotsVis = React.memo((props: DotPlotsVisProps) => {
);
});
DotPlotsVis.displayName = 'RawJSONVis';
DotPlotsVis.displayName = 'DotPlotVis';
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment