class SimpleSVG {
constructor(width, height, styles = {}) {
this.root = d3.create('div');
this.pre = this.root.append('div');
this.post = this.root.append('div');
const svg = this.post.append('svg')
.style('width', `${width}px`)
.style('height', `${height}px`)
for (const key of Object.keys(styles)) {
svg.style(
key.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`),
styles[key],
)
}
this.svg = svg;
}
addStaticLabel(text, styles = {}) {
const node = this.pre.append('div')
.style('height', '25px')
.text(text);
for (const key of Object.keys(styles)) {
node.style(
key.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`),
styles[key],
)
}
}
addLabel(name, styles = {}){
const node = this.pre.append('div')
.style('height', '25px')
.text(`${name}: ---`);
for (const key of Object.keys(styles)) {
node.style(
key.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`),
styles[key],
)
}
return new Label(name, node);
}
addStaticCircle(attributes = {}) {
let x = attributes.cx || attributes.x || 0;
delete attributes.cx; delete attributes.x;
let y = attributes.cy || attributes.y || 0;
delete attributes.cy; delete attributes.y;
const r = attributes.r || attributes.rad || attributes.radius || 2;
delete attributes.r; delete attributes.rad; delete attributes.radius;
const fill = attributes.fill || attributes.color || 'Black';
delete attributes.fill; delete attributes.color;
const p = attributes.p; delete attributes.p;
if(p != undefined) {
const d = Get2DData(p);
x = d.x; y = d.y;
}
const circle = this.svg.append('circle')
.attr('cx', x)
.attr('cy', y)
.attr('r', r)
.attr('fill', fill);
for (const key of Object.keys(attributes)) {
circle.attr(
key.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`),
attributes[key],
)
}
}
addStaticCircles(data, attributes = {}) {
let x = attributes.cx || attributes.x || 0;
delete attributes.cx; delete attributes.x;
let y = attributes.cy || attributes.y || 0;
delete attributes.cy; delete attributes.y;
const r = attributes.r || attributes.rad || attributes.radius || 2;
delete attributes.r; delete attributes.rad; delete attributes.radius;
const fill = attributes.fill || attributes.color || 'Black';
delete attributes.fill; delete attributes.color;
let compoundFunction = false;
const p = attributes.p; delete attributes.p;
if(p != undefined) {
if (typeof p === 'function') compoundFunction = true;
else {
const d = Get2DData(p);
x = d.x; y = d.y;
}
}
const attributeKeys = Object.keys(attributes).map(d => {
return {
original: d,
processed: d.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`),
}
})
for (let i = 0; i < data.length; i++) {
const circle = this.svg.append('circle')
.attr('r', typeof r === 'function' ? r(data[i], i) : r)
.attr('fill', typeof fill === 'function' ? fill(data[i], i) : fill);
if(compoundFunction) {
const d = Get2DData(p(data[i], i));
circle.attr('cx', d.x).attr('cy', d.y);
} else {
circle
.attr('cx', typeof x === 'function' ? x(data[i], i) : x)
.attr('cy', typeof y === 'function' ? y(data[i], i) : y)
}
attributeKeys.forEach(d => {
const a = attributes[d.original];
circle.attr(d.processed, typeof a === 'function' ? a(data[i], i) : a);
});
}
}
addStaticLine(attributes = {}) {
let x1 = attributes.x1 || 0;
delete attributes.x1;
let y1 = attributes.y1 || 0;
delete attributes.y1;
let x2 = attributes.x2 || 10;
delete attributes.x2;
let y2 = attributes.y2 || 10;
delete attributes.y2;
const stroke = attributes.stroke || attributes.color || 'Black';
delete attributes.stroke; delete attributes.color;
const strokeWidth = attributes.strokeWidth || 1;
delete attributes.strokeWidth;
const p1 = attributes.p1; delete attributes.p1;
if(p1 != undefined) {
const d = Get2DData(p1);
x1 = d.x; y1 = d.y;
}
const p2 = attributes.p2; delete attributes.p2;
if(p2 != undefined) {
const d = Get2DData(p2);
x2 = d.x; y2 = d.y;
}
const line = this.svg.append('line')
.attr('x1', x1)
.attr('y1', y1)
.attr('x2', x2)
.attr('y2', y2)
.attr('stroke', stroke)
.attr('stroke-width', strokeWidth);
for (const key of Object.keys(attributes)) {
line.attr(
key.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`),
attributes[key],
)
}
}
get node() {
return this.root.node();
}
}