Skip to content

Commit

Permalink
display improvement in PrevImages
Browse files Browse the repository at this point in the history
  • Loading branch information
xtianpoli committed Nov 25, 2024
1 parent e152087 commit 53f20bc
Showing 1 changed file with 115 additions and 96 deletions.
211 changes: 115 additions & 96 deletions ipyprogressivis/js/src/previmages.js
Original file line number Diff line number Diff line change
@@ -1,53 +1,58 @@
//'use strict';
import * as widgets from '@jupyter-widgets/base';
import _ from 'lodash';
import $ from 'jquery';
import { new_id } from './base';
import { elementReady } from './es6-element-ready';
import * as colormaps from './colormaps';
import * as d3 from 'd3';
import History from './history';
import '../css/scatterplot.css';
import * as widgets from "@jupyter-widgets/base";
import _ from "lodash";
import $ from "jquery";
import { new_id } from "./base";
import { elementReady } from "./es6-element-ready";
import * as colormaps from "./colormaps";
import * as d3 from "d3";
import History from "./history";
import "../css/scatterplot.css";

const DEFAULT_SIGMA = 0;
const DEFAULT_FILTER = 'default';
const DEFAULT_FILTER = "default";
const MAX_PREV_IMAGES = 3;

export class PrevImagesModel extends widgets.DOMWidgetModel {
defaults() {
return {
...super.defaults(),
_model_name: 'PrevImagesModel',
_view_name: 'PrevImagesView',
_model_module: 'jupyter-progressivis',
_view_module: 'jupyter-progressivis',
_model_module_version: '0.1.0',
_view_module_version: '0.1.0',
hists: ndarray([]),
samples: ndarray([]),
target: '',
};
}
defaults() {
return {
...super.defaults(),
_model_name: "PrevImagesModel",
_view_name: "PrevImagesView",
_model_module: "jupyter-progressivis",
_view_module: "jupyter-progressivis",
_model_module_version: "0.1.0",
_view_module_version: "0.1.0",
hists: ndarray([]),
samples: ndarray([]),
target: "",
};
}
}

// Custom View. Renders the widget model.
export class PrevImagesView extends widgets.DOMWidgetView {
// Defines how the widget gets rendered into the DOM
render () {
this.id = 'view_' + new_id();
render() {
this.id = "view_" + new_id();
const previmgs = PrevImages(this);
this.previmgs = previmgs;
this.previmgs.template(this.el);
this.moduloCnt = 1;
this.counter = 0;
let that = this;
elementReady('#' + previmgs.with_id('prevImages')).then(() =>
previmgs.ready(that.model.get('target'))
elementReady("#" + previmgs.with_id("prevImages")).then(() =>
previmgs.ready(that.model.get("target")),
);
this.model.on('msg:custom', this.data_changed, this);
console.log("target", this.model.get('target'));
this.model.on("msg:custom", this.data_changed, this);
console.log("target", this.model.get("target"));
}
data_changed () {
const target = this.model.get('target');
this.previmgs.update_vis(target);
data_changed() {
const target = this.model.get("target");
if (this.counter % this.moduloCnt === 0) {
this.previmgs.update_vis(target);
}
this.counter++;
}
}

Expand All @@ -60,21 +65,21 @@ function PrevImages(ipyView) {
let bounds = null;
const imageHistory = new History(MAX_PREV_IMAGES);
function with_id(prefix) {
return prefix + '_' + id;
return prefix + "_" + id;
}
function s(id) {
return '#' + id;
return "#" + id;
}
function swith_id(id) {
return s(with_id(id));
}

function template(element) {
let temp = document.querySelector('#PrevImages');
let temp = document.querySelector("#PrevImages");
if (temp === null) {
// Install the template as a dom template node
temp = document.createElement('template');
temp.setAttribute('id', 'PrevImages');
temp = document.createElement("template");
temp.setAttribute("id", "PrevImages");
temp.innerHTML = `<div class="tab-content">
<div >
<div id=''>
Expand All @@ -89,12 +94,22 @@ function PrevImages(ipyView) {
</filter>
</svg>
<div class="form-inline">
<div id="historyGrp" style="height:80px;">
<div id="historyGrp" style="height:120px;">
<label>History</label>
<table style="height:120px;border:1px solid black;border-collapse: collapse;"><tr><td width='300px' id="prevImages"></td>
<td>Blur radius</td><td><input class="form-control" id="filterSlider" type="range" value="0" min="0" max="5" step="0.1"></input></td>
<td>Color map</td><td><select id="colorMapSelect" class="form-control"></select></td>
</tr></table>
<table style="height:120px;border:1px solid black;border-collapse: collapse;">
<tr>
<td width='360px' id="prevImages"></td>
<td>
<table>
<tr><td>Blur radius</td><td><input class="form-control" id="filterSlider" type="range" value="0" min="0" max="5" step="0.1"></input></td></tr>
<tr><td>Display freq.</td>
<td><input class="form-control" id="freqSlider" type="range" value="20" min="1" max="20" step="1"></input></td></tr>
<tr><td>Color map</td>
<td><select id="colorMapSelect" class="form-control"></select></td></tr>
</table>
</td>
</tr>
</table>
</div>
Expand All @@ -110,11 +125,11 @@ function PrevImages(ipyView) {
}
const templateClone = temp.content.cloneNode(true);
// Rename all the ids to be unique
const with_ids = templateClone.querySelectorAll('[id]');
const with_ids = templateClone.querySelectorAll("[id]");
const ids = new Set();

for (const element of with_ids) {
const eid = element.id ? with_id(element.id) : with_id('PrevImages');
const eid = element.id ? with_id(element.id) : with_id("PrevImages");
if (ids.has(eid)) {
console.log(`Error in PrevImages.template(), duplicate id '${eid}'`);
// TODO fix it
Expand All @@ -126,52 +141,52 @@ function PrevImages(ipyView) {
}
//https://github.com/jupyter-widgets/ipywidgets/issues/1840
function _update_vis(target) {
let targetP = '.' + target;
let targetCanvas = targetP + ' canvas';
let targetSvg = targetP + ' svg';
let targetP = "." + target;
let targetCanvas = targetP + " canvas";
let targetSvg = targetP + " svg";
elementReady(targetCanvas).then((that) => {
if (firstTime) {
let w = $(targetCanvas).first().attr('width');
let h = $(targetCanvas).first().attr('height');
let w = $(targetCanvas).first().attr("width");
let h = $(targetCanvas).first().attr("height");
_createSvg(w, h);
firstTime = false;
}
dataURL = $(that)[0].toDataURL();
$(targetCanvas).hide();
imageHistory.enqueueUnique(dataURL);
let svgQry = swith_id('PrevImages') + ' svg';
svg.select(svgQry + ' .heatmap').attr('xlink:href', dataURL);
let svgQry = swith_id("PrevImages") + " svg";
svg.select(svgQry + " .heatmap").attr("xlink:href", dataURL);
const prevImgElements = d3
.select(swith_id('prevImages'))
.selectAll('img')
.select(swith_id("prevImages"))
.selectAll("img")
.data(imageHistory.getItems(), (d) => d);
prevImgElements
.enter()
.append('img')
.attr('width', 50)
.attr('height', 50)
.on('mouseover', (event, d) => {
.append("img")
.attr("width", 50)
.attr("height", 50)
.on("mouseover", (event, d) => {
d3.select(`${svgQry} .heatmapCompare`)
.attr('xlink:href', d)
.attr('visibility', 'inherit');
.attr("xlink:href", d)
.attr("visibility", "inherit");
})
.on('mouseout', () => {
d3.select(`${svgQry} .heatmapCompare`).attr('visibility', 'hidden');
.on("mouseout", () => {
d3.select(`${svgQry} .heatmapCompare`).attr("visibility", "hidden");
});
prevImgElements
.transition()
.duration(500)
.attr('src', (d) => d)
.attr('width', 100)
.attr('height', 100);
let lenImgs = $(swith_id('prevImages') + ' img').length;
.attr("src", (d) => d)
.attr("width", 100)
.attr("height", 100);
let lenImgs = $(swith_id("prevImages") + " img").length;
let exitDuration = 500 - 100 * Math.max(lenImgs - 3, 0);
prevImgElements
.exit()
.transition()
.duration(exitDuration)
.attr('width', 5)
.attr('height', 5)
.attr("width", 5)
.attr("height", 5)
.remove();
}); //end elementReady
}
Expand All @@ -182,59 +197,63 @@ function PrevImages(ipyView) {
*/
function makeOptions(select, names) {
if (!select) {
console.warn('makeOptions requires an existing select element');
console.warn("makeOptions requires an existing select element");
return;
}
names.forEach((name) => {
const option = document.createElement('option');
option.setAttribute('value', name);
const option = document.createElement("option");
option.setAttribute("value", name);
option.innerHTML = name;
select.appendChild(option);
});
}

function _createSvg(w, h) {
console.log('bounds [w, h]', w, h);
console.log("bounds [w, h]", w, h);
svg = d3
.select(swith_id('PrevImages') + ' svg')
.attr('width', w)
.attr('height', h);
zoomable = svg.append('g').attr('id', with_id('zoomable'));
.select(swith_id("PrevImages") + " svg")
.attr("width", w)
.attr("height", h);
zoomable = svg.append("g").attr("id", with_id("zoomable"));
zoomable
.append('image')
.attr('class', 'heatmap')
.style('pointer-events', 'none')
.attr('xlink:href', dataURL)
.attr('preserveAspectRatio', 'none')
.attr('width', w)
.attr('height', h)
.attr('filter', `url(${swith_id('gaussianBlur')})`);
.append("image")
.attr("class", "heatmap")
.style("pointer-events", "none")
.attr("xlink:href", dataURL)
.attr("preserveAspectRatio", "none")
.attr("width", w)
.attr("height", h)
.attr("filter", `url(${swith_id("gaussianBlur")})`);
svg
.append('image')
.attr('class', 'heatmapCompare')
.style('pointer-events', 'none')
.attr('preserveAspectRatio', 'none')
.attr('opacity', 0.5)
.attr('width', w)
.attr('height', h);
.append("image")
.attr("class", "heatmapCompare")
.style("pointer-events", "none")
.attr("preserveAspectRatio", "none")
.attr("opacity", 0.5)
.attr("width", w)
.attr("height", h);
const gaussianBlur = document.getElementById(
with_id('gaussianBlurElement')
with_id("gaussianBlurElement"),
);
const filterSlider = $(swith_id('filterSlider'));
const freqSlider = $(swith_id("freqSlider"));
freqSlider.change(function () {
ipyView.moduloCnt = Math.max(this.max-this.value, 1);
});
const filterSlider = $(swith_id("filterSlider"));
filterSlider.change(function () {
const value = this.value;
gaussianBlur.setStdDeviation(value, value);
});
filterSlider.get(0).value = DEFAULT_SIGMA;
gaussianBlur.setStdDeviation(DEFAULT_SIGMA, DEFAULT_SIGMA);
const colorMap = document.getElementById(with_id('colorMap'));
const colorMapSelect = $(swith_id('colorMapSelect'));
const colorMap = document.getElementById(with_id("colorMap"));
const colorMapSelect = $(swith_id("colorMapSelect"));
colorMapSelect.change(function () {
colormaps.makeTableFilter(colorMap, this.value);
});
colorMapSelect.get(0).value = DEFAULT_FILTER;
makeOptions(colorMapSelect.get(0), colormaps.getTableNames());
colormaps.makeTableFilter(colorMap, 'Default');
colormaps.makeTableFilter(colorMap, "Default");
}
function _ready(t) {}
return {
Expand Down

0 comments on commit 53f20bc

Please sign in to comment.