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

Alex grid #1124

Merged
merged 28 commits into from
Jun 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e7ac2f1
Minor cleanup
alexsielicki May 10, 2023
4b1a4cf
prettier code formatting
alexsielicki May 10, 2023
eb7b516
Adding d3fc and d3 version 7 packages
alexsielicki May 10, 2023
ff3e1cc
Creating new ScatterplotGrid React component to render a background grid
alexsielicki May 10, 2023
c7cc939
Adding todo
alexsielicki May 15, 2023
7c6d126
Merge branch 'master' into alex-grid
alexsielicki May 25, 2023
8585ecc
Adding basic grid to scatterplot
alexsielicki May 25, 2023
8d8418a
Removing unused xoffset option
alexsielicki May 25, 2023
435a848
Refactoring to update grid on mount and update
alexsielicki May 25, 2023
f6efe26
Adding combined-reduction package
alexsielicki Jun 7, 2023
d391da1
Creating Redux slice to hold info about UI dimensions
alexsielicki Jun 7, 2023
b015003
Refactoring to use Redux Toolkit selectors, configureStore
alexsielicki Jun 7, 2023
333c555
Renaming helpers to selectors
alexsielicki Jun 7, 2023
bc22ae9
Removing unused color map file
alexsielicki Jun 7, 2023
1c4e039
Adding scatterplot grid color values to each colormap and using them …
alexsielicki Jun 7, 2023
dcdf74d
Commenting out debug statements
alexsielicki Jun 7, 2023
6e520cf
Fixing issue with reducer altering state due to non-deep cloning
alexsielicki Jun 7, 2023
73ac1e7
Adding support for custom min & max variable ranges, log and linear s…
alexsielicki Jun 8, 2023
696d36e
Commenting out debug statements
alexsielicki Jun 8, 2023
cca2065
Adding support for date & time scales. Refactoring.
alexsielicki Jun 9, 2023
f71f4e4
Refactoring and switching numeric min/max to use table statistics.
alexsielicki Jun 9, 2023
8dfed47
Refactoring to get rid of min and max and instead use extent, since w…
alexsielicki Jun 9, 2023
258ad78
Adding more types
alexsielicki Jun 9, 2023
48a9e77
Renaming uiSlice to scatterplotSlice and adjusting code
alexsielicki Jun 9, 2023
5d6672a
Adding component to show and hide the grid.
alexsielicki Jun 9, 2023
c6e763e
Deleting console logs and debugs. Addresses #1124
alexsielicki Jun 20, 2023
2e5f12f
Converting reused colors to constants and using same latest CSS synta…
alexsielicki Jun 20, 2023
ec52d4f
Removing commented out code. Addresses #1124
alexsielicki Jun 20, 2023
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
612 changes: 609 additions & 3 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@
"@reduxjs/toolkit": "^1.9.3",
"bootstrap": "^4",
"buffer": "6.0.3",
"combined-reduction": "^1.1.0",
"d3": "^3",
"d3fc": "^15.2.6",
"d3v7": "npm:d3@^7.8.4",
"deep-equal": "^2",
"font-awesome": "4.7.0",
"he": "1.2.0",
Expand Down
7 changes: 7 additions & 0 deletions web-server/components/ScatterplotOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faUndo } from "@fortawesome/free-solid-svg-icons";
import "css/slycat-scatterplot-options.scss";
import ScatterplotOptionsGrid from "./ScatterplotOptionsGrid";

export const DEFAULT_UNSELECTED_POINT_SIZE = 8;
export const MIN_UNSELECTED_POINT_SIZE = 1;
Expand Down Expand Up @@ -171,6 +172,12 @@ class ScatterplotOptions extends React.PureComponent {
/>
</div>
</div>
<hr className="mt-4 mb-4" />
<div className="slycat-scatterplot-grid">
<div className="form-inline">
<ScatterplotOptionsGrid />
</div>
</div>
</div>
);
}
Expand Down
33 changes: 33 additions & 0 deletions web-server/components/ScatterplotOptionsGrid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from "react";
import { useSelector, useDispatch } from "react-redux";
import {
toggleShowGrid,
selectShowGrid,
} from "plugins/slycat-parameter-image/js/scatterplotSlice";

const ScatterplotOptionsGrid: React.FC = () => {
const dispatch = useDispatch();
const select_show_grid = useSelector(selectShowGrid);

const handleShowGridChange = () => {
dispatch(toggleShowGrid());
};

return (
<div className="form-check">
<input
className="form-check-input"
type="checkbox"
value=""
id="showGrid"
checked={select_show_grid}
onChange={handleShowGridChange}
/>
<label className="form-check-label" htmlFor="showGrid">
Show Background Grid
</label>
</div>
);
};

export default ScatterplotOptionsGrid;
3 changes: 3 additions & 0 deletions web-server/css/slycat-scatterplot-options.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,7 @@
color: black;
}
}
.form-check-input {
margin-right: 0.6em;
}
}
20 changes: 14 additions & 6 deletions web-server/js/slycat-color-maps-methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ retains certain rights in this software. */
import d3 from "d3";

export default {

isValueInColorscaleRange: function (value: number, colorscale: d3.ScaleLinear | d3.ScaleLogarithmic | d3.ScaleOrdinal) {
// console.debug(`isValueInColorscaleRange with value of %o`, value);
isValueInColorscaleRange: function (
value: number,
colorscale: d3.ScaleLinear | d3.ScaleLogarithmic | d3.ScaleOrdinal
) {
// Check against min and max only if value is a number
if (Number.isFinite(value)) {
const rangeMin = colorscale.domain()[0];
Expand All @@ -34,11 +35,20 @@ export default {

// Return the out of domain color value for the given color map.
get_outofdomain_color: function (name: string): string {
// console.log(`get_outofdomain_color for window.store.getState().colormap`);
if (name === undefined) name = window.store.getState().colormap;
return this.color_maps[name]["outofdomain_color"];
},

// Return the scatterplot grid color value for the given color map.
get_scatterplot_grid_color: function (name: string): string {
if (name === undefined) name = window.store.getState().colormap;
const scatterplot_grid_color =
this.color_maps[name]["scatterplot_grid_color"] !== undefined
? this.color_maps[name]["scatterplot_grid_color"]
: "black";
return scatterplot_grid_color;
},

// Return the suggested opacity value for the given color map.
get_opacity: function (name: string): string {
if (name === undefined) name = window.store.getState().colormap;
Expand All @@ -48,8 +58,6 @@ export default {
// Return a d3 linear color scale with the current color map for the domain [0, 1].
// Callers should modify the domain by passing a min and max to suit their own needs.
get_color_scale: function (name: string, min: number, max: number) {
// console.debug(`get_color_scale, name is %o, min is %o, max is %o`, name, min, max);
// console.debug(`get_color_scale, this is %o`, this);
if (name === undefined) name = window.store.getState().colormap;
if (min === undefined) min = 0.0;
if (max === undefined) max = 1.0;
Expand Down
53 changes: 34 additions & 19 deletions web-server/js/slycat-color-maps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,30 @@ import slycat_color_maps_methods from "js/slycat-color-maps-methods";
interface ColorMapsInterface {
[key: string]: {
label: string;
background: d3.RGBColor;
background: string;
null_color: string;
outofdomain_color: string;
scatterplot_grid_color: string;
opacity: string;
colors: d3.RGBColor[];
};
}

const WHITE = "rgb(255 255 255)";
const GRAY1 = "rgb(204, 204, 204)";
const GRAY2 = "rgb(128 128 128)";
const GRAY3 = "rgb(102 102 102)";
const GRAY4 = "rgb(75 75 75)";
const BLACK = "rgb(0 0 0)";

export default {
color_maps: {
night: {
label: "Night",
background: d3.rgb(128, 128, 128),
null_color: "rgb(75,75,75)",
outofdomain_color: "black",
background: GRAY2,
null_color: GRAY4,
outofdomain_color: BLACK,
scatterplot_grid_color: GRAY3,
opacity: "0.5",
colors: [
d3.rgb(59, 76, 192),
Expand Down Expand Up @@ -61,9 +71,10 @@ export default {
},
day: {
label: "Day",
background: d3.rgb(255, 255, 255),
null_color: "gray",
outofdomain_color: "black",
background: WHITE,
null_color: GRAY2,
outofdomain_color: BLACK,
scatterplot_grid_color: GRAY1,
opacity: "0.7",
colors: [
d3.rgb(100, 108, 234),
Expand Down Expand Up @@ -103,35 +114,39 @@ export default {
},
rainbow: {
label: "Rainbow Night",
background: d3.rgb(128, 128, 128),
null_color: "rgb(75,75,75)",
outofdomain_color: "black",
background: GRAY2,
null_color: GRAY4,
outofdomain_color: BLACK,
scatterplot_grid_color: GRAY3,
opacity: "0.6",
colors: [d3.rgb(0, 0, 255), d3.rgb(0, 255, 255), d3.rgb(255, 255, 0), d3.rgb(255, 0, 0)],
},
rainbow_day: {
label: "Rainbow Day",
background: d3.rgb(255, 255, 255),
null_color: "gray",
outofdomain_color: "black",
background: WHITE,
null_color: GRAY2,
outofdomain_color: BLACK,
scatterplot_grid_color: GRAY1,
opacity: "0.7",
colors: [d3.rgb(0, 0, 255), d3.rgb(0, 255, 255), d3.rgb(255, 255, 0), d3.rgb(255, 0, 0)],
},
grayscale_day: {
label: "Grayscale Day",
background: d3.rgb(255, 255, 255),
background: WHITE,
// ToDo: fix this, null and outofdomain colors need to be different than normal colors
null_color: "rgb(75,75,75)",
outofdomain_color: "black",
null_color: GRAY4,
outofdomain_color: BLACK,
scatterplot_grid_color: GRAY1,
opacity: "0.6",
colors: [d3.rgb(255, 255, 255), d3.rgb(0, 0, 0)],
},
grayscale_night: {
label: "Grayscale Night",
background: d3.rgb(128, 128, 128),
background: GRAY2,
// ToDo: fix this, null and outofdomain colors need to be different than normal colors
null_color: "rgb(75,75,75)",
outofdomain_color: "black",
null_color: GRAY4,
outofdomain_color: BLACK,
scatterplot_grid_color: GRAY3,
opacity: "0.6",
colors: [d3.rgb(255, 255, 255), d3.rgb(0, 0, 0)],
},
Expand Down
11 changes: 11 additions & 0 deletions web-server/plugins/slycat-parameter-image/css/ui.css
Original file line number Diff line number Diff line change
Expand Up @@ -988,3 +988,14 @@ button#controls-button-var-options {
font-size: var(--custom-font-size, 15px);
font-family: var(--custom-font-family, Arial);
}

/* Scatterplot Grid */
#scatterplot-grid-svg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
/* Sends the grid behind everything else. Canvas points are -1, so this moves the grid behind them. */
z-index: -2;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React, { useEffect, useRef } from "react";
import { useSelector } from "react-redux";
import * as d3 from "d3v7";
import * as fc from "d3fc";
import _ from "lodash";
import {
selectColormap,
selectXScale,
selectYScale,
selectXTicks,
selectYTicks,
} from "../selectors";
import { selectShowGrid } from "../scatterplotSlice";
import slycat_color_maps from "js/slycat-color-maps";

type ScatterplotGridProps = {};

const ScatterplotGrid: React.FC<ScatterplotGridProps> = (props) => {
const gridRef = useRef<SVGGElement>(null);

// Select values from the state with `useSelector`
const show_grid = useSelector(selectShowGrid);
const colormap = useSelector(selectColormap);
const x_scale = useSelector(selectXScale);
const y_scale = useSelector(selectYScale);
const x_ticks = useSelector(selectXTicks);
const y_ticks = useSelector(selectYTicks);

const scatterplot_grid_color = slycat_color_maps.get_scatterplot_grid_color(colormap);

// Only execute the useEffect hook if show_grid is true
useEffect(() => {
if (show_grid) {
updateGrid();
}
});

const updateGrid = () => {
const setStrokeStyle = (sel: d3.Selection<SVGGElement, unknown, null, undefined>) => {
sel.style("stroke", scatterplot_grid_color);
};

const gridline = fc
.annotationSvgGridline()
.xScale(x_scale)
.yScale(y_scale)
.xTicks(x_ticks)
.yTicks(y_ticks)
.xDecorate(setStrokeStyle)
.yDecorate(setStrokeStyle);
d3.select(gridRef.current).call(gridline);
};

// Only render the component if show_grid is true
if (!show_grid) {
return null;
}
return <g id="grid" ref={gridRef} />;
};

export default ScatterplotGrid;