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 min max #1127

Merged
merged 30 commits into from
Jun 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 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
7b05657
Adding margin to model delete button. Fixes #1122
alexsielicki Jun 12, 2023
a54bea9
Adding example checkerboard CSS
alexsielicki Jun 12, 2023
0ff4ecd
Swapping order of grayscale night/day to be consistent with order in …
alexsielicki Jun 12, 2023
7056ad5
Converting object to JSON to make it serializable before putting it i…
alexsielicki Jun 13, 2023
d9150bf
Changing object conversion to individual array contents instead of en…
alexsielicki Jun 16, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
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
2 changes: 1 addition & 1 deletion web-server/components/Model.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const Model = (props: ModelProps) => {
</em>
</small>
</a>
<span className='float-right'>
<span className='float-right ml-3'>
<button
type='button'
className='btn btn-sm btn-outline-danger'
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;
}
}
17 changes: 15 additions & 2 deletions web-server/js/slycat-color-maps-methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +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) {
isValueInColorscaleRange: function (
value: number,
colorscale: d3.ScaleLinear | d3.ScaleLogarithmic | d3.ScaleOrdinal
) {
// console.debug(`isValueInColorscaleRange with value of %o`, value);
// Check against min and max only if value is a number
if (Number.isFinite(value)) {
Expand Down Expand Up @@ -39,6 +41,17 @@ export default {
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 {
// console.log(`get_scatterplot_grid_color for window.store.getState().colormap`);
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 Down
18 changes: 12 additions & 6 deletions web-server/js/slycat-color-maps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export default {
background: d3.rgb(128, 128, 128),
null_color: "rgb(75,75,75)",
outofdomain_color: "black",
scatterplot_grid_color: "#666666",
opacity: "0.5",
colors: [
d3.rgb(59, 76, 192),
Expand Down Expand Up @@ -64,6 +65,7 @@ export default {
background: d3.rgb(255, 255, 255),
null_color: "gray",
outofdomain_color: "black",
scatterplot_grid_color: "rgb(80% 80% 80%)",
opacity: "0.7",
colors: [
d3.rgb(100, 108, 234),
Expand Down Expand Up @@ -106,6 +108,7 @@ export default {
background: d3.rgb(128, 128, 128),
null_color: "rgb(75,75,75)",
outofdomain_color: "black",
scatterplot_grid_color: "#666666",
opacity: "0.6",
colors: [d3.rgb(0, 0, 255), d3.rgb(0, 255, 255), d3.rgb(255, 255, 0), d3.rgb(255, 0, 0)],
},
Expand All @@ -114,24 +117,27 @@ export default {
background: d3.rgb(255, 255, 255),
null_color: "gray",
outofdomain_color: "black",
scatterplot_grid_color: "rgb(80% 80% 80%)",
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),
grayscale_night: {
label: "Grayscale Night",
background: d3.rgb(128, 128, 128),
// ToDo: fix this, null and outofdomain colors need to be different than normal colors
null_color: "rgb(75,75,75)",
outofdomain_color: "black",
scatterplot_grid_color: "#666666",
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),
grayscale_day: {
label: "Grayscale Day",
background: d3.rgb(255, 255, 255),
// ToDo: fix this, null and outofdomain colors need to be different than normal colors
null_color: "rgb(75,75,75)",
outofdomain_color: "black",
scatterplot_grid_color: "rgb(80% 80% 80%)",
opacity: "0.6",
colors: [d3.rgb(255, 255, 255), d3.rgb(0, 0, 0)],
},
Expand Down
13 changes: 13 additions & 0 deletions web-server/plugins/slycat-parameter-image/css/ui.css
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,8 @@
#scatterplot .image-frame.html {
position: absolute;
background-color: black;
/* Checkerboard background */
/* background: repeating-conic-gradient(#808080 0% 25%, white 0% 50%) 50% / 20px 20px; */
border: 1px solid black;
height: auto;
padding-bottom: 20px;
Expand Down Expand Up @@ -988,3 +990,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,62 @@
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) {
// console.debug("ScatterplotGrid.componentDidMount() updateGrid()");
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;
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from "react";
import { connect } from 'react-redux';
import d3 from 'd3';
import _ from 'lodash';
import d3 from "d3";
import _ from "lodash";

export default class ScatterplotLegend extends React.PureComponent {
constructor(props) {
Expand All @@ -13,72 +12,60 @@ export default class ScatterplotLegend extends React.PureComponent {
componentDidMount = () => {
this.createAxis();
this.setThreeDColorByLegend();
}
};

componentDidUpdate = (prevProps, prevState, snapshot) => {
this.createAxis();
const updateThreeDColorByLegend = this.props.height != prevProps.height
|| this.props.label != prevProps.label
|| this.props.fontSize != prevProps.fontSize
|| this.props.fontFamily != prevProps.fontFamily
;
if(updateThreeDColorByLegend)
{
const updateThreeDColorByLegend =
this.props.height != prevProps.height ||
this.props.label != prevProps.label ||
this.props.fontSize != prevProps.fontSize ||
this.props.fontFamily != prevProps.fontFamily;
if (updateThreeDColorByLegend) {
this.setThreeDColorByLegend();
}
}
};

createAxis = () => {
let domain = _.sortBy(this.props.domain).reverse();
let scale = d3.scale.linear()
.domain(domain)
.range([0, this.props.height])
;

let legend_axis = d3.svg.axis()
let scale = d3.scale.linear().domain(domain).range([0, this.props.height]);
let legend_axis = d3.svg
.axis()
.scale(scale)
.orient("right")
.ticks(this.props.height / 50)
;

d3.select(this.legend_axis_ref.current)
.call(legend_axis)
;
}
.ticks(this.props.height / 50);
d3.select(this.legend_axis_ref.current).call(legend_axis);
};

setThreeDColorByLegend = () => {
const bbox = this.legend_group_ref.current.getBBox();
// console.log(`createAxis for ${this.props.uid} has width ${bbox.width} and height ${bbox.height}`);
this.props.setThreeDColorByLegend(this.props.uid, bbox.width, bbox.height);
}
};

render() {
const stops = this.props.gradient_data.map((stop, index) => (
<stop
key={index}
offset={`${stop.offset}%`}
stopColor={stop.color}
/>
<stop key={index} offset={`${stop.offset}%`} stopColor={stop.color} />
));

return (
<React.Fragment>
<g className="legendGroup"
<g
className="legendGroup"
ref={this.legend_group_ref}
transform={`translate(${this.props.x_offset}, 0)`}
>
<g
<g
ref={this.legend_axis_ref}
className="legend-axis"
transform={`translate(${this.props.gradient_width}, 0)`}
style={{
fontSize: this.props.fontSize,
fontFamily: this.props.fontFamily,
}}
>
</g>
></g>
<defs>
<linearGradient
<linearGradient
x1="0%"
y1="0%"
x2="0%"
Expand All @@ -95,12 +82,12 @@ export default class ScatterplotLegend extends React.PureComponent {
x={0}
y="0"
style={{
fill: `url(#scatterplot-legend-color-gradient-${this.props.uid})`
fill: `url(#scatterplot-legend-color-gradient-${this.props.uid})`,
}}
></rect>
<text
className="label"
x={-15}
<text
className="label"
x={-15}
y={this.props.height / 2}
transform={`rotate(-90, ${-15}, ${this.props.height / 2})`}
style={{
Expand All @@ -114,4 +101,4 @@ export default class ScatterplotLegend extends React.PureComponent {
</React.Fragment>
);
}
}
}
Loading