import * as d3 from "d3";
|
import { types } from "mobx-state-tree";
|
|
import { Hotkey } from "../core/Hotkey";
|
import NormalizationMixin from "../mixins/Normalization";
|
import RegionsMixin from "../mixins/Regions";
|
import { TimeSeriesModel } from "../tags/object/TimeSeries";
|
import { guidGenerator } from "../core/Helpers";
|
import Registry from "../core/Registry";
|
import { AreaMixin } from "../mixins/AreaMixin";
|
import { AnnotationMixin } from "../mixins/AnnotationMixin";
|
|
const hotkeys = Hotkey("TimeSeries", "Time Series Segmentation");
|
|
const Model = types
|
.model("TimeSeriesRegionModel", {
|
id: types.optional(types.identifier, guidGenerator),
|
pid: types.optional(types.string, guidGenerator),
|
type: "timeseriesregion",
|
object: types.late(() => types.reference(TimeSeriesModel)),
|
|
start: types.union(types.number, types.string),
|
end: types.union(types.number, types.string),
|
instant: false,
|
})
|
.volatile(() => ({
|
hideable: true,
|
}))
|
.views((self) => ({
|
get parent() {
|
return self.object;
|
},
|
|
getRegionElement() {
|
return self._brushRef;
|
},
|
}))
|
.actions((self) => ({
|
growRight(size) {
|
self.end = self.end + size;
|
},
|
|
growLeft(size) {
|
self.start = self.start - size;
|
},
|
|
shrinkRight(size) {
|
self.end = self.end - size;
|
},
|
|
shrinkLeft(size) {
|
self.start = self.start + size;
|
},
|
|
selectRegion() {
|
const one = 1000;
|
const lots = one * 10;
|
|
hotkeys.addNamed("ts:grow-left", () => self.growLeft(one));
|
hotkeys.addNamed("ts:grow-right", () => self.growRight(one));
|
hotkeys.addNamed("ts:shrink-left", () => self.shrinkLeft(one));
|
hotkeys.addNamed("ts:shrink-right", () => self.shrinkRight(one));
|
|
hotkeys.addNamed("ts:grow-left-large", () => self.growLeft(lots));
|
hotkeys.addNamed("ts:grow-right-large", () => self.growRight(lots));
|
hotkeys.addNamed("ts:shrink-left-large", () => self.shrinkLeft(lots));
|
hotkeys.addNamed("ts:shrink-right-large", () => self.shrinkRight(lots));
|
|
self.parent.scrollToRegion(self);
|
},
|
|
updateAppearenceFromState() {
|
const s = self.labelsState;
|
|
if (!s) return;
|
|
// @todo remove
|
self.parent.updateView();
|
},
|
|
afterUnselectRegion() {
|
[
|
"ts:grow-left",
|
"ts:grow-right",
|
"ts:shrink-left",
|
"ts:shrink-right",
|
"ts:grow-left-large",
|
"ts:grow-right-large",
|
"ts:shrink-left-large",
|
"ts:shrink-right-large",
|
].forEach((sc) => hotkeys.removeNamed(sc));
|
|
self.parent.updateView();
|
},
|
|
updateRegion(start, end) {
|
self.start = start;
|
self.end = end;
|
self.notifyDrawingFinished();
|
},
|
|
afterCreate() {
|
if (typeof self.start === "string") {
|
// deal only with timestamps/indices
|
self.start = self.parent.parseTime(self.start);
|
self.end = self.parent.parseTime(self.end);
|
}
|
},
|
|
serialize() {
|
// convert to original format from data/csv
|
const format = self.parent.timeformat ? d3.utcFormat(self.parent.timeformat) : Number;
|
const res = {
|
value: {
|
start: format(self.start),
|
end: format(self.end),
|
instant: self.instant,
|
},
|
};
|
|
return res;
|
},
|
}));
|
|
const TimeSeriesRegionModel = types.compose(
|
"TimeSeriesRegionModel",
|
RegionsMixin,
|
AreaMixin,
|
NormalizationMixin,
|
AnnotationMixin,
|
Model,
|
);
|
|
Registry.addTag("timeseriesregion", TimeSeriesRegionModel, () => {});
|
Registry.addRegionType(TimeSeriesRegionModel, "timeseries");
|
|
export { TimeSeriesRegionModel };
|