Skip to content

Commit

Permalink
Release 14.4.3 (#673)
Browse files Browse the repository at this point in the history
## What's Changed
* fix: `@use` lineupengine vars to allow overriding them by @puehringer
in #671
* fix: add back `showLabelLimit` option to scatter visualization by
@oltionchampari in #670


**Full Changelog**:
v14.4.2...v14.4.3
  • Loading branch information
puehringer authored Jan 9, 2025
2 parents 21f22f9 + f2caf62 commit dcced5d
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 33 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "visyn_core",
"description": "Core repository for datavisyn applications.",
"version": "14.4.2",
"version": "14.4.3",
"author": {
"name": "datavisyn GmbH",
"email": "contact@datavisyn.io",
Expand Down
7 changes: 5 additions & 2 deletions src/scss/vendors/_lineup.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
// With https://github.com/lineupjs/lineupengine/releases/tag/v2.5.3, they changed from @import to @use, forcing us to use the variables before being able to override them.
@use 'lineupengine/src/styles/vars' as *;

// TODO: Without this, we get "Can't resolve './node_modules/lineupengine/src/styles/lineupengine/src/assets/loading.svg' in '.../workspaces/<repo>'"
// Why do I need to do this? Probably because lineupjs defines $engine_assets and it is resolving it relatively?
$engine_assets: '../assets';
$engine_loading_image: url('#{$engine_assets}/loading.svg') !default;
$engine_loading_static_image: url('#{$engine_assets}/loading_s.svg') !default;
$engine_loading_image: url('#{$engine_assets}/loading.svg');
$engine_loading_static_image: url('#{$engine_assets}/loading_s.svg');

$lu_assets: '../assets' !default;
$lu_use_font_awesome: true !default;
Expand Down
4 changes: 2 additions & 2 deletions src/vis/scatter/ScatterVis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { VIS_NEUTRAL_COLOR } from '../general/constants';
import { EColumnTypes, ENumericalColorScaleType, EScatterSelectSettings, ICommonVisProps } from '../interfaces';
import { BrushOptionButtons } from '../sidebar/BrushOptionButtons';
import { fitRegressionLine } from './Regression';
import { ERegressionLineType, IInternalScatterConfig, IRegressionResult } from './interfaces';
import { ERegressionLineType, IRegressionResult, IScatterConfig } from './interfaces';
import { useData } from './useData';
import { useDataPreparation } from './useDataPreparation';
import { useLayout } from './useLayout';
Expand Down Expand Up @@ -71,7 +71,7 @@ export function ScatterVis({
scrollZoom,
uniquePlotId,
showDownloadScreenshot,
}: ICommonVisProps<IInternalScatterConfig>) {
}: ICommonVisProps<IScatterConfig>) {
const id = React.useMemo(() => uniquePlotId || uniqueId('ScatterVis'), [uniquePlotId]);

const [shiftPressed, setShiftPressed] = React.useState(false);
Expand Down
6 changes: 3 additions & 3 deletions src/vis/scatter/ScatterVisSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { ColorSelect } from './ColorSelect';
import { LabelingOptions } from './LabelingOptions';
import { OpacitySlider } from './OpacitySlider';
import { RegressionLineOptions } from './Regression';
import { ELabelingOptions, IInternalScatterConfig, IRegressionLineOptions } from './interfaces';
import { ELabelingOptions, IRegressionLineOptions, IScatterConfig } from './interfaces';

const defaultConfig = {
facets: {
Expand Down Expand Up @@ -40,7 +40,7 @@ const defaultConfig = {
},
};

export function ScatterVisSidebar({ config, optionsConfig, columns, filterCallback, setConfig, selectedList }: ICommonVisSideBarProps<IInternalScatterConfig>) {
export function ScatterVisSidebar({ config, optionsConfig, columns, filterCallback, setConfig, selectedList }: ICommonVisSideBarProps<IScatterConfig>) {
const mergedOptionsConfig = useMemo(() => {
return merge({}, defaultConfig, optionsConfig);
}, [optionsConfig]);
Expand Down Expand Up @@ -113,7 +113,7 @@ export function ScatterVisSidebar({ config, optionsConfig, columns, filterCallba
}
}}
currentSelected={config.showLabels}
labelLimit={config.selectedPointsCount > config.showLabelLimit ? config.showLabelLimit : 0}
labelLimit={selectedList?.length && config.showLabelLimit && selectedList?.length > config.showLabelLimit ? config.showLabelLimit : 0}
/>
)
: null}
Expand Down
10 changes: 0 additions & 10 deletions src/vis/scatter/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,6 @@ export interface IScatterConfig extends BaseVisConfig {
yAxisScale?: 'linear' | 'log';
}

/**
* @internal
*/
export interface IInternalScatterConfig extends IScatterConfig {
/**
* Internal property used to show a message if show labels mode is `Selected`
*/
selectedPointsCount?: number;
}

export function isScatterConfig(s: BaseVisConfig): s is IScatterConfig {
return s.type === ESupportedPlotlyVis.SCATTER;
}
Expand Down
32 changes: 19 additions & 13 deletions src/vis/scatter/useData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as React from 'react';
import isEmpty from 'lodash/isEmpty';
import { PlotlyTypes } from '../../plotly';
import { DEFAULT_COLOR, VIS_NEUTRAL_COLOR } from '../general/constants';
import { ELabelingOptions, IInternalScatterConfig } from './interfaces';
import { ELabelingOptions, IScatterConfig } from './interfaces';
import { FetchColumnDataResult } from './utils';
import { getLabelOrUnknown } from '../general/utils';
import { columnNameWithDescription, truncateText } from '../general/layoutUtils';
Expand Down Expand Up @@ -54,20 +54,24 @@ export function useData({
status: string;
value: FetchColumnDataResult | undefined;
scatter?: ReturnType<typeof useDataPreparation>['scatter'];
config: IInternalScatterConfig;
config: IScatterConfig;
facet?: ReturnType<typeof useDataPreparation>['facet'];
splom?: ReturnType<typeof useDataPreparation>['splom'];
subplots?: ReturnType<typeof useDataPreparation>['subplots'];
selectedList: string[];
shapeScale: (val: string) => string;
mappingFunction?: (val: string | number | null | undefined) => string;
}) {
const selectedSet = React.useMemo(() => new Set(selectedList), [selectedList]);

return React.useMemo<PlotlyTypes.Data[]>(() => {
if (status !== 'success' || !value) {
return [];
}
const fullOpacityOrAlpha = selectedList.length > 0 ? 1 : config.alphaSliderVal;
const fullOpacityOrAlpha = selectedSet.size > 0 ? 1 : config.alphaSliderVal;

if (subplots) {
const visibleLabelsSet = config.showLabelLimit ? new Set(selectedList.slice(0, config.showLabelLimit)) : selectedSet;
const plots = subplots.xyPairs.map((pair) => {
return {
...BASE_DATA,
Expand All @@ -77,7 +81,7 @@ export function useData({
xaxis: pair.xref,
yaxis: pair.yref,
textposition: subplots.text.map((_, i) => textPositionOptions[i % textPositionOptions.length]),
...(isEmpty(selectedList) ? {} : { selectedpoints: selectedList.map((idx) => subplots.idToIndex.get(idx)) }),
...(isEmpty(selectedSet) ? {} : { selectedpoints: selectedList.map((idx) => subplots.idToIndex.get(idx)) }),
mode: config.showLabels === ELabelingOptions.NEVER || config.xAxisScale === 'log' || config.yAxisScale === 'log' ? 'markers' : 'text+markers',
...(config.showLabels === ELabelingOptions.NEVER
? {}
Expand All @@ -86,7 +90,7 @@ export function useData({
text: subplots.text.map((t) => truncateText(value.idToLabelMapper(t), true, 10)),
}
: {
text: subplots.text.map((t, i) => (selectedList.includes(subplots.ids[i] ?? '') ? truncateText(value.idToLabelMapper(t), true, 10) : '')),
text: subplots.text.map((t, i) => (visibleLabelsSet.has(subplots.ids[i]!) ? truncateText(value.idToLabelMapper(t), true, 10) : '')),
}),
hovertext: subplots.ids.map((p_id, index) =>
`${value.idToLabelMapper(p_id)}
Expand All @@ -108,6 +112,7 @@ export function useData({
}

if (scatter && config && value && value.validColumns[0]) {
const visibleLabelsSet = config.showLabelLimit ? new Set(selectedList.slice(0, config.showLabelLimit)) : selectedSet;
const traces = [
{
...BASE_DATA,
Expand All @@ -116,7 +121,7 @@ export function useData({
y: scatter.plotlyData.y,
// text: scatter.plotlyData.text,
textposition: scatter.plotlyData.text.map((_, i) => textPositionOptions[i % textPositionOptions.length]),
...(isEmpty(selectedList) ? {} : { selectedpoints: selectedList.map((idx) => scatter.idToIndex.get(idx)) }),
...(isEmpty(selectedSet) ? {} : { selectedpoints: selectedList.map((idx) => scatter.idToIndex.get(idx)) }),
mode: config.showLabels === ELabelingOptions.NEVER || config.xAxisScale === 'log' || config.yAxisScale === 'log' ? 'markers' : 'text+markers',
...(config.showLabels === ELabelingOptions.NEVER
? {}
Expand All @@ -126,9 +131,7 @@ export function useData({
// textposition: 'top center',
}
: {
text: scatter.plotlyData.text.map((t, i) =>
selectedList.includes(scatter.ids[i] ?? '') ? truncateText(value.idToLabelMapper(t), true, 10) : '',
),
text: scatter.plotlyData.text.map((t, i) => (visibleLabelsSet.has(scatter.ids[i]!) ? truncateText(value.idToLabelMapper(t), true, 10) : '')),
// textposition: 'top center',
}),
hovertext: value.validColumns[0].resolvedValues.map((v, i) =>
Expand All @@ -155,6 +158,9 @@ export function useData({

if (facet && config && value && value.validColumns[0] && value.validColumns[1]) {
const plots = facet.resultData.map((group) => {
const visibleLabelsSet = config.showLabelLimit
? new Set(group.data.ids.filter((id) => selectedSet.has(id)).slice(0, config.showLabelLimit))
: selectedSet;
return {
...BASE_DATA,
type: 'scattergl',
Expand All @@ -172,11 +178,11 @@ export function useData({
// textposition: 'top center',
}
: {
text: group.data.text.map((t, i) => (selectedList.includes(group.data.ids[i]!) ? truncateText(value.idToLabelMapper(t), true, 10) : '')),
text: group.data.text.map((t, i) => (visibleLabelsSet.has(group.data.ids[i]!) ? truncateText(value.idToLabelMapper(t), true, 10) : '')),
// textposition: 'top center',
}),
name: getLabelOrUnknown(group.data.facet),
...(isEmpty(selectedList) ? {} : { selectedpoints: selectedList.map((idx) => group.idToIndex.get(idx)).filter((v) => v !== undefined) }),
...(isEmpty(selectedSet) ? {} : { selectedpoints: selectedList.map((idx) => group.idToIndex.get(idx)).filter((v) => v !== undefined) }),
hovertext: group.data.ids.map((p_id, index) =>
`${value.idToLabelMapper(p_id)}
${(value.resolvedLabelColumnsWithMappedValues ?? []).map((l) => `<br />${columnNameWithDescription(l.info)}: ${getLabelOrUnknown(l.mappedValues.get(p_id))}`)}
Expand Down Expand Up @@ -214,7 +220,7 @@ export function useData({
${value.colorColumn ? `<br />${columnNameWithDescription(value.colorColumn.info)}: ${getLabelOrUnknown(value.colorColumn.resolvedValues[i]?.val)}` : ''}
${value.shapeColumn && value.shapeColumn.info.id !== value.colorColumn?.info.id ? `<br />${columnNameWithDescription(value.shapeColumn.info)}: ${getLabelOrUnknown(value.shapeColumn.resolvedValues[i]?.val)}` : ''}`.trim(),
),
...(isEmpty(selectedList) ? {} : { selectedpoints: selectedList.map((idx) => splom.idToIndex.get(idx)) }),
...(isEmpty(selectedSet) ? {} : { selectedpoints: selectedList.map((idx) => splom.idToIndex.get(idx)) }),
marker: {
size: 8,
color: value.colorColumn && mappingFunction ? value.colorColumn.resolvedValues.map((v) => mappingFunction(v.val)) : VIS_NEUTRAL_COLOR,
Expand All @@ -229,5 +235,5 @@ export function useData({
}

return [];
}, [status, value, subplots, scatter, config, facet, splom, selectedList, shapeScale, mappingFunction]);
}, [status, value, subplots, scatter, config, facet, splom, selectedList, selectedSet, shapeScale, mappingFunction]);
}
4 changes: 2 additions & 2 deletions src/vis/scatter/useLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { PlotlyTypes } from '../../plotly';
import { VIS_NEUTRAL_COLOR, VIS_TRACES_COLOR } from '../general/constants';
import { FastTextMeasure } from '../general/FastTextMeasure';
import { getLabelOrUnknown } from '../general/utils';
import { IInternalScatterConfig } from './interfaces';
import { useDataPreparation } from './useDataPreparation';
import { IScatterConfig } from './interfaces';

const textMeasure = new FastTextMeasure('12px Open Sans');

Expand Down Expand Up @@ -87,7 +87,7 @@ export function useLayout({
splom?: ReturnType<typeof useDataPreparation>['splom'];
subplots?: ReturnType<typeof useDataPreparation>['subplots'];
regressions: { shapes: Partial<PlotlyTypes.Shape>[]; annotations: Partial<PlotlyTypes.Annotations>[] };
config: IInternalScatterConfig;
config: IScatterConfig;
width: number;
height: number;
internalLayoutRef: React.MutableRefObject<Partial<PlotlyTypes.Layout>>;
Expand Down

0 comments on commit dcced5d

Please sign in to comment.