@xulab-research/vue-anatomogram
Version:
Interactive anatomical diagrams for Vue.js applications - A Vue-compatible rewrite of EBI anatomogram
129 lines (103 loc) • 3.43 kB
JavaScript
import { getDefaultView, supportedSpecies } from './Assets.js';
import Switcher from './Switcher.js';
import AnatomogramSvg from './AnatomogramSvg.js';
export class Anatomogram {
constructor(options = {}) {
this.atlasUrl = options.atlasUrl || 'https://www.ebi.ac.uk/gxa/';
this.species = options.species || '';
this.selectedView = options.selectedView || getDefaultView(this.species);
this.idsWithMarkup = options.idsWithMarkup || [];
this.onMouseOver = options.onMouseOver || (() => {});
this.onMouseOut = options.onMouseOut || (() => {});
this.onClick = options.onClick || (() => {});
this.onViewChanged = options.onViewChanged || (() => {});
this.container = null;
this.switcher = null;
this.anatomogramSvg = null;
this.init();
}
init() {
this.switcher = new Switcher({
atlasUrl: this.atlasUrl,
species: this.species,
selectedView: this.selectedView,
onChangeView: (view) => this.switchAnatomogramView(view)
});
this.anatomogramSvg = new AnatomogramSvg({
atlasUrl: this.atlasUrl,
species: this.species,
selectedView: this.selectedView,
idsWithMarkup: this.idsWithMarkup,
onMouseOver: this.onMouseOver,
onMouseOut: this.onMouseOut,
onClick: this.onClick
});
}
switchAnatomogramView(anatomogramView) {
this.selectedView = anatomogramView;
this.switcher.update({
selectedView: anatomogramView
});
this.anatomogramSvg.update({
selectedView: anatomogramView
});
this.onViewChanged(anatomogramView);
}
updateSpecies(newSpecies) {
if (supportedSpecies.includes(newSpecies)) {
this.species = newSpecies;
this.selectedView = getDefaultView(newSpecies);
this.switcher.update({
species: newSpecies,
selectedView: this.selectedView
});
this.anatomogramSvg.update({
species: newSpecies,
selectedView: this.selectedView
});
}
}
render() {
const wrapper = document.createElement('div');
wrapper.className = 'anatomogram-container';
if (supportedSpecies.includes(this.species)) {
const switcherContainer = document.createElement('div');
this.switcher.mount(switcherContainer);
wrapper.appendChild(switcherContainer);
const svgContainer = document.createElement('div');
this.anatomogramSvg.mount(svgContainer);
wrapper.appendChild(svgContainer);
} else {
const message = document.createElement('div');
message.textContent = `Species "${this.species}" is not supported`;
message.style.cssText = 'color: #999; text-align: center; padding: 20px;';
wrapper.appendChild(message);
}
return wrapper;
}
mount(container) {
this.container = container;
const element = this.render();
container.appendChild(element);
return this;
}
update(options = {}) {
const oldSpecies = this.species;
Object.assign(this, options);
if (options.species && options.species !== oldSpecies) {
this.updateSpecies(options.species);
}
if (this.container) {
this.container.innerHTML = '';
const element = this.render();
this.container.appendChild(element);
}
return this;
}
destroy() {
if (this.container) {
this.container.innerHTML = '';
}
}
}
export default Anatomogram;