UNPKG

@rcsb/rcsb-saguaro

Version:
169 lines (168 loc) 6.39 kB
import { RcsbAbstractTrack } from "./RcsbAbstractTrack"; import * as classes from "../../scss/RcsbBoard.module.scss"; import { select } from "d3-selection"; import { RcsbD3EventDispatcher } from "../RcsbD3/RcsbD3EventDispatcher"; import { RcsbD3Constants } from "../RcsbD3/RcsbD3Constants"; import { EventType } from "../../RcsbFv/RcsbFvContextManager/RcsbFvContextManager"; import { Subject } from "rxjs"; export class RcsbAbstractDisplay extends RcsbAbstractTrack { constructor(boardId, trackId) { super(); this._displayColor = "#FF6666"; this.minRatio = 0; this.selectDataInRangeFlag = false; this.hideEmptyTracksFlag = false; this.hidden = false; this.elementSelection = select(RcsbD3Constants.EMPTY); this.elementSubject = { mouseclick: new Subject(), mouseenter: new Subject(), mouseleave: new Subject(), }; this.trackId = trackId; } setDisplayColor(color) { this._displayColor = color; } setMinRatio(ratio) { this.minRatio = ratio; } setSelectDataInRange(flag) { this.selectDataInRangeFlag = flag; } setHideEmptyTrack(flag) { this.hideEmptyTracksFlag = flag; } reset() { this.g.selectAll("." + classes.rcsbElement).remove(); } subscribeElementHighlight(action) { this.elementSubject.mouseenter.subscribe(({ d, e }) => action.enter(d)); this.elementSubject.mouseleave.subscribe(({ d, e }) => action.leave(d)); } plot(element) { element.on(RcsbD3Constants.CLICK, (event, d) => { var _a; if (event.defaultPrevented) return; this.elementSubject.mouseclick.next({ d, e: event }); (_a = d.elementClickCallback) === null || _a === void 0 ? void 0 : _a.call(d, d, event); RcsbD3EventDispatcher.elementClick(event, this.getBoardHighlight(), d); }); element.on(RcsbD3Constants.MOUSE_ENTER, (event, d) => { if (event.defaultPrevented) return; this.elementSubject.mouseenter.next({ d, e: event }); }); element.on(RcsbD3Constants.DBL_CLICK, (event, d) => { if (event.defaultPrevented) return; }); element.on(RcsbD3Constants.MOUSE_LEAVE, (event, d) => { if (event.defaultPrevented) { return; } this.elementSubject.mouseleave.next({ d, e: event }); }); } update(compKey) { const where = { from: Math.floor(this.xScale.domain()[0]), to: Math.ceil(this.xScale.domain()[1]) }; if (typeof this.updateDataOnMove === "function") { this.updateDataOnMove(where).then((result) => { this.data(result); if (this.data() != null) { this._update(where, compKey); } else { this.displayEmpty(); } }).catch((error) => { console.error(error); }); } else { if (this.data() == null) { this.displayEmpty(); return; } this._update(where, compKey); } } _update(where, compKey) { if (this.selectDataInRangeFlag) { let dataElems = this.processData(this.data().filter((s, i) => { if (s.end == null) { return (s.begin >= where.from && s.begin <= where.to); } else { return !(s.begin > where.to || s.end < where.from); } })); if (this.hideEmptyTracksFlag) { if (dataElems.length == 0 && !this.hidden) { this.contextManager.next({ eventType: EventType.TRACK_HIDE, eventData: { trackId: this.trackId, visibility: false } }); this.hidden = true; } else if (dataElems.length > 0 && this.hidden) { this.contextManager.next({ eventType: EventType.TRACK_HIDE, eventData: { trackId: this.trackId, visibility: true } }); this.hidden = false; } } this.selectElements(dataElems, compKey) .attr("class", classes.rcsbElement) .classed(classes.rcsbElement + "_" + compKey, typeof compKey === "string") .call(this.plot.bind(this)); } else if ((this.minRatio == 0 || this.getRatio() > this.minRatio) && !this.isDataUpdated()) { let dataElems = this.processData(this.data()); this.selectElements(dataElems, compKey) .attr("class", classes.rcsbElement) .classed(classes.rcsbElement + "_" + compKey, typeof compKey === "string") .call(this.plot.bind(this)); this.setDataUpdated(true); } else if (this.minRatio > 0 && this.getRatio() <= this.minRatio) { this.getElements().remove(); this.setDataUpdated(false); } } displayEmpty() { } ; move() { } ; processData(dataElems) { return dataElems; } selectElements(dataElems, compKey) { const className = typeof compKey === "string" ? "." + classes.rcsbElement + "_" + compKey : "." + classes.rcsbElement; const elements = this.g.selectAll(className).data(dataElems, RcsbAbstractDisplay.dataKey); const newElems = elements.enter() .append(RcsbD3Constants.G) .attr("class", classes.rcsbElement) .classed(classes.rcsbElement + "_" + compKey, typeof compKey === "string"); newElems.call(this.enter); elements.exit().remove(); this.elementSelection = elements.merge(newElems); return this.elementSelection; } enter(e) { } getElements() { return this.elementSelection; } static dataKey(d) { return d.begin + ":" + d.end; } getRatio() { const xScale = this.xScale; return (xScale.range()[1] - xScale.range()[0]) / (xScale.domain()[1] - xScale.domain()[0]); } }