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

Add vizarr layer #49

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1,229 changes: 1,194 additions & 35 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "kaibu",
"version": "0.1.25",
"version": "0.1.26",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
Expand All @@ -11,6 +11,7 @@
"format": "prettier --write \"{src,tests}/**/**\""
},
"dependencies": {
"@hms-dbmi/vizarr": "^0.2.0",
"@mdi/font": "^5.3.45",
"@turf/turf": "^5.1.6",
"buefy": "^0.8.0",
Expand Down
100 changes: 100 additions & 0 deletions public/CustomVizarr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import __SNOWPACK_ENV__ from './vizarr_module/__snowpack__/env.js';
import.meta.env = __SNOWPACK_ENV__;

import React from './vizarr_module/web_modules/react.js';
import {useRecoilState, useSetRecoilState, useRecoilValue} from './vizarr_module/web_modules/recoil.js';
import {createSourceData} from './vizarr_module/_dist_/io.js';

import { layerIdsState, sourceInfoState, viewerViewState } from './vizarr_module/_dist_/state.js';
import Vizarr from './vizarr_module/_dist_/vizarr.js';

import ReactDOM from "./vizarr_module/web_modules/react-dom.js";
import {RecoilRoot} from "./vizarr_module/web_modules/recoil.js";
import {ThemeProvider} from "./vizarr_module/web_modules/@material-ui/styles.js";
import theme2 from "./vizarr_module/_dist_/theme.js";


function Button({ onClick }) {
const style = { position: 'absolute', right: '30px' };
return React.createElement('button', { onClick, style }, "It worked!");
}

let resolveVizarr;

export function CustomVizarr() {
const setLayerIds = useSetRecoilState(layerIdsState);
const setSourceInfo = useSetRecoilState(sourceInfoState);
const [viewState, setViewState] = useRecoilState(viewerViewState);


// Copied from './vizarr_modules/_dist_/vizarr.js
async function addImage(config) {
// Generate ID unique to image (layer)
const id = Math.random().toString(36).slice(2);
// Config is same as ImJoy API
const sourceData = await createSourceData(config);
// Adds source info to state
setSourceInfo((prevSourceInfo) => {
if (!sourceData.name) {
sourceData.name = `image_${Object.keys(prevSourceInfo).length}`;
}
return {...prevSourceInfo, [id]: sourceData};
});
// Update active Layer IDs
setLayerIds((prevIds) => [...prevIds, id]);
}



// Runs once on page Load
// useEffect(() => {
// const url = 'https://storage.googleapis.com/vitessce-demo-data/test-data/spraggins_ome.zarr';
// const config = {
// source: url, // source could be a custom Zarr.js Store!
// };
// addImage(config);
// }, []);

const onClick = () => {
console.log('Resetting viewState');
// setViewState({ target: [ 0, 0, 0 ], zoom: 0 });
console.log('=====vizarr==>',viewState.target, viewState.zoom);
const map_veiw = window.map.getView();
const zoom = map_veiw.getZoom();
const center = map_veiw.getCenter();
console.log("=====openlayers==>", center, zoom)
// setViewState({ target: [ center[0], center[1], 0 ], zoom: zoom*Math.sqrt(46.85276874422804) });

console.log('====diff====>', viewState.target[0] - center[0], viewState.target[1]-center[1], viewState.zoom-zoom)

};



if(resolveVizarr){
resolveVizarr({
setViewState,
addImage
})
resolveVizarr = null
}
return React.createElement('div', null,
React.createElement(Vizarr, null),
React.createElement(Button, { onClick })
)
}

window.CreateVizarrViewer = (container)=>{
return new Promise((resolve)=>{
resolveVizarr = resolve
ReactDOM.render(
/* @__PURE__ */ React.createElement(ThemeProvider, { theme: theme2 },
/* @__PURE__ */ React.createElement(RecoilRoot, null,
/* @__PURE__ */ React.createElement(CustomVizarr, null))),
container
);
})
}

document.dispatchEvent(new CustomEvent('vizarr-loaded', { detail: window.VizarrViewer }))

1 change: 1 addition & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<script type="text/javascript" src="https://lib.imjoy.io/imjoy-loader.js"></script>
<script src="https://oeway.github.io/itk-vtk-viewer/itkVtkViewerCDN.js"></script>
<script type="module" src="/CustomVizarr.js"></script>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>

Expand Down
17 changes: 12 additions & 5 deletions src/components/ImageViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -486,8 +486,8 @@ export default {
new View({
projection: projection,
center: getCenter(config.extent),
zoom: 1,
minZoom: -10
zoom: 10,
minZoom: -20
})
);
},
Expand Down Expand Up @@ -524,10 +524,17 @@ export default {
setMode: this.setMode
});
} else {
// this.addLayer({
// type: "itk-vtk",
// name: "example image",
// data: "https://images.proteinatlas.org/19661/221_G2_1_red_green.jpg"
// });

this.addLayer({
type: "itk-vtk",
name: "example image",
data: "https://images.proteinatlas.org/19661/221_G2_1_red_green.jpg"
type: "vizarr",
name: "vizarr image",
data:
"https://storage.googleapis.com/vitessce-demo-data/test-data/spraggins_ome.zarr"
});

await this.addLayer({
Expand Down
2 changes: 1 addition & 1 deletion src/components/layers/ItkVtkLayer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ export default {
containerStyle: containerStyle
};

var itk_layer = new CanvasLayer();
const itk_layer = new CanvasLayer();

let viewer, extent, is2D;
if (
Expand Down
186 changes: 186 additions & 0 deletions src/components/layers/VizarrLayer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
<template>
<div class="itk-vtk-layer">
<section>
<input
ref="file_input"
@change="resolveFiles && resolveFiles($event)"
type="file"
style="display:none;"
multiple
/>

<b-button
v-if="showLoadButton"
@click="$refs.file_input.click()"
icon-left="file-import"
>
Load File(s)
</b-button>
</section>
<b-field v-if="layer" label="opacity">
<b-slider
v-model="config.opacity"
@input="updateOpacity"
:min="0"
:max="1.0"
:step="0.1"
></b-slider>
</b-field>
<section
:id="'itk-vtk-control_' + config.id"
style="position: relative;"
></section>
</div>
</template>

<script>
import { Map } from "ol";
import Layer from "ol/layer/Layer";

const CanvasLayer = /*@__PURE__*/ (function(Layer) {
function CanvasLayer(options) {
options = options || {};
Layer.call(this, options);
this.viewerElement = document.createElement("div");
this.viewerElement.classList.add("ol-layer");
this.viewerElement.style.position = "absolute";
this.viewerElement.style.width = "100%";
this.viewerElement.style.height = "100%";
this.sync_callback = options.sync_callback;
}

if (Layer) CanvasLayer.__proto__ = Layer;
CanvasLayer.prototype = Object.create(Layer && Layer.prototype);
CanvasLayer.prototype.constructor = CanvasLayer;

CanvasLayer.prototype.getSourceState = function getSourceState() {
return "ready";
};

CanvasLayer.prototype.render = function render(frameState) {
if (this.sync_callback) {
const center = frameState.viewState.center
const zoom = frameState.viewState.zoom
this.sync_callback(center, zoom);
}


this.viewerElement.style.opacity = this.getOpacity();
return this.viewerElement; //return the viewer element
};

return CanvasLayer;
})(Layer);

export default {
name: "vizarr-layer",
type: "vizarr",
show: true,
props: {
map: {
type: Map,
default: null
},
selected: {
type: Boolean,
default: false
},
visible: {
type: Boolean,
default: false
},
config: {
type: Object,
default: function() {
return {};
}
}
},
data() {
return {
layer: null,
mode: "2D",
resolveFiles: null,
showLoadButton: false,
viewer: null
};
},
watch: {
visible: function(newVal) {
this.layer.setVisible(newVal);
this.$forceUpdate();
}
},
mounted() {
this.config.name = this.config.name || "vizarr image";
this.config.opacity = 1.0;
this.config.init = this.init;
},
beforeDestroy() {
if (this.layer) {
this.map.removeLayer(this.layer);
}
},
created() {},
methods: {
async init() {
this.layer = await this.setupLayer();
this.map.addLayer(this.layer);
if (typeof this.config.data === "string") {
this.config.source = this.config.data;
}
this.viewer.addImage(this.config);
window.viewer = this.viewer;
window.map = this.map;
this.$forceUpdate();
return this.layer;
},
updateOpacity() {
if (this.layer) this.layer.setOpacity(this.config.opacity);
},
selectLayer() {},

setupLayer() {
return new Promise(resolve => {
const vizarrLayer = new CanvasLayer();
if (window.CreateVizarrViewer) {
window.CreateVizarrViewer(vizarrLayer.viewerElement).then(viewer => {
this.viewer = viewer;
// vizarrLayer.sync_callback = (center, zoom)=>{
// // viewer.setViewState({ target: [ center[0], center[1], 0 ], zoom: zoom*Math.sqrt(46.85276874422804) });
// }
resolve(vizarrLayer);
});
} else {
window.document.addEventListener("vizarr-loaded", () => {
window
.CreateVizarrViewer(vizarrLayer.viewerElement)
.then(viewer => {
this.viewer = viewer;
// vizarrLayer.sync_callback = (center, zoom)=>{
// // viewer.setViewState({ target: [ center[0], center[1], 0 ], zoom: zoom*Math.sqrt(46.85276874422804) });
// }
resolve(vizarrLayer);
});
});
}
});
},
getLayerAPI() {
const me = this;
return {
_rintf: true,
name: this.config.name,
id: this.config.id,
async set_image(image) {
const vtkImage = await me.normalizeImage(image);
me.viewer.setImage(vtkImage);
}
};
}
}
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style></style>
1 change: 1 addition & 0 deletions src/components/layers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export { default as VectorLayer } from "./VectorLayer.vue";
export { default as ImageLayer } from "./ImageLayer.vue";
export { default as ItkVtkLayer } from "./ItkVtkLayer.vue";
export { default as RemoteLayer } from "./RemoteLayer.vue";
export { default as VizarrLayer } from "./VizarrLayer.vue";
5 changes: 5 additions & 0 deletions vue.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ module.exports = {
from: path.join(__dirname, "./docs"),
to: path.join(__dirname, "dist/docs"),
toType: "dir"
},
{
from: path.join(__dirname, "node_modules/@hms-dbmi/vizarr"),
to: path.join(__dirname, "dist/vizarr_module"),
toType: "dir"
}
])]
}
Expand Down