class MetricBadge {
constructor (value, delta, options) {
this.value = value
this.delta = delta
this.options = this.setOptions(options)
this.svg = this.makeSvg()
}
makeSvg() {
return d3.create("svg").attr("viewBox", [0, 0, this.options.width, this.options.height])
}
setOptions(options) {
const defaultOpts = {
title: "My Metric",
width: 400,
height: 300,
margin: 50,
backgroundColor: "#1e4471",
backgroundRounding: 10,
titleColor: "#f2f2f2",
textColor: "#ffffff",
positiveDeltaColor: "#ffffff",
negativeDeltaColor: "#ffffff"
}
const temp = {}
for (const attr in defaultOpts) temp[attr] = defaultOpts[attr]
for (const attr in options) temp[attr] = options[attr]
return temp
}
getNode() {
const deltaOpts = {
show: this.delta && this.delta !== 0,
color: this.delta > 0 ? this.options.positiveDeltaColor : this.options.negativeDeltaColor,
rotation: this.delta > 0 ? `rotate(0)` : `rotate(180)`,
val: Math.abs(this.delta)
}
this.svg
.append("g")
.attr("class", "background-rect")
.append("rect")
.attr("x", 5)
.attr("y", 5)
.attr("width", this.options.width - 10)
.attr("height", this.options.height - 10)
.attr("rx", this.options.backgroundRounding)
.attr("fill", this.options.backgroundColor)
this.svg
.append("g")
.append("text")
.attr("x", this.options.margin)
.attr("y", this.options.margin)
.attr("font-family", "Tahoma")
.attr("letter-spacing", 1.2)
.attr("font-weight", "200")
.attr("fill", this.options.titleColor)
.text(this.options.title)
this.svg
.append("g")
.append("text")
.attr("x", this.options.margin)
.attr("y", this.options.height / 2)
.attr("font-family", "Tahoma")
.attr("letter-spacing", 1.2)
.attr("font-weight", "600")
.attr("text-anchor", "start")
.attr("alignment-baseline", "central")
.attr("font-size", "10rem")
.attr("fill", this.options.textColor)
.text(this.value)
this.svg
.append("g")
.attr("class", "delta")
.append("path")
.attr("transform", `translate(${this.options.width * 0.75}, ${this.options.height / 2}) ${deltaOpts.rotation}`)
.attr("d", `${d3.symbol().type(d3.symbolTriangle).size(120)()}`)
.attr("fill", deltaOpts.color)
this.svg
.select(".delta")
.append("text")
.attr("x", this.options.width * 0.75 + 15)
.attr("y", this.options.height / 2 - 3)
.attr("font-family", "Tahoma")
.attr("alignment-baseline", "central")
.attr("font-size", "3rem")
.attr("font-weight", "600")
.attr("fill", deltaOpts.color)
.text(deltaOpts.val)
return this.svg.node()
}
}