class Tex {
constructor(plot, text, px, py, options = {}) {
this.plot = plot;
this.px = px;
this.py = py;
this.text = text;
this.options = Object.assign({}, defaults, {
width: 1,
size: 14,
weight: 300,
opacity: 1,
anchor: 'middle',
baseline: 'baseline',
angle: 0,
font: 'sans-serif, verdana, arial',
}, options);
}
round(x){
return Math.round(x*10)/10
}
getPosition() {
const {
x,
y,
} = this.plot;
const px = x(this.px);
const py = y(this.py);
return { px, py };
}
enter(g) {
const {
px,
py,
} = this.getPosition();
const {
stroke,
fill,
opacity,
anchor,
baseline,
weight,
font,
width,
angle,
interactive,
size,
color,
} = this.options;
const round = this.round;
g.append('g')
.attr('class', 'shape')
.attr('fill', color || fill || stroke)
.attr('fill-opacity', opacity)
.attr('stroke-width', width)
.attr('dominant-baseline', baseline)
.style('text-anchor', anchor)
//.style('font-size', size + 'px')
//.style('font-weight', weight)
//.style('font-family', font)
.attr('transform', `translate(${px},${py}) rotate(${angle}) scale(${round(size/16)})`)
.append(() => MJ.tex2svg(this.text).querySelector("svg"));
if (interactive) {
this.createUI(g);
}
}
update(g) {
const {
px,
py,
} = this.getPosition();
const t = this.plot.options.transitions;
const {
stroke,
fill,
opacity,
anchor,
baseline,
weight,
font,
width,
angle,
interactive,
size,
color,
} = this.options;
const round = this.round;
const shape = t ? g.select('.shape').transition() : g.select('.shape');
shape
.attr('fill', color || fill || stroke)
.attr('fill-opacity', opacity)
.attr('stroke-width', width)
.attr('dominant-baseline', baseline)
.style('text-anchor', anchor)
//.style('font-size', size + 'px')
//.style('font-weight', weight)
//.style('font-family', font)
.attr('transform', `translate(${px},${py}) rotate(${angle}) scale(${round(size/16)})`)
.append(() => MJ.tex2svg(this.text).querySelector("svg"));
}
// for interactive points
onChange() {
if (this.options.onChange) {
this.options.onChange({
x: this.px,
y: this.py,
});
}
}
createUI(container) {
const {
x,
y,
} = this.plot;
this.gUI = createUIContainer(container);
this._translate = this.getPosition();
// move handle
const mHandle = addUIHandler(
this,
this.gUI.select('.ghost'),
'move_handle',
() => {
this.px = x.invert(this._translate.px);
this.py = y.invert(this._translate.py);
this.plot.render();
this.onChange();
},
);
}
refreshUI(key, dx, dy) {
const {size}=this.options;
const round = this.round;
const g = this.gUI;
const ghost = g.select('.ghost');
if (key === 'move_handle') {
this._translate.px += dx;
this._translate.py += dy;
} else if (key === 'reset') {
const p = this.getPositions();
this._translate.px = p.px;
this._translate.py = p.py;
}
const { px, py } = this._translate;
ghost.attr('transform', `translate(${px},${py}) scale(${round(size/16)})`);
}
}