2023-10-09 23:30:39 +00:00
|
|
|
class ResourceChart extends HTMLElement {
|
2023-10-05 16:38:25 +00:00
|
|
|
constructor () {
|
2023-10-04 18:59:46 +00:00
|
|
|
super();
|
|
|
|
this.attachShadow({ mode: "open" });
|
|
|
|
this.shadowRoot.innerHTML = `
|
|
|
|
<style>
|
2023-10-05 16:38:25 +00:00
|
|
|
* {
|
|
|
|
box-sizing: border-box;
|
|
|
|
font-family: monospace;
|
|
|
|
}
|
|
|
|
figure {
|
|
|
|
margin: 0;
|
|
|
|
}
|
2023-10-04 18:59:46 +00:00
|
|
|
div {
|
|
|
|
max-width: 400px;
|
|
|
|
aspect-ratio: 1 / 1;
|
|
|
|
}
|
2023-10-05 16:38:25 +00:00
|
|
|
figcaption {
|
|
|
|
text-align: center;
|
|
|
|
margin-top: 10px;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
}
|
2023-10-04 18:59:46 +00:00
|
|
|
</style>
|
2023-10-05 16:38:25 +00:00
|
|
|
<style id="responsive-style" media="not all">
|
|
|
|
figure {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
flex-direction: row;
|
|
|
|
flex-wrap: nowrap;
|
|
|
|
justify-content: flex-start;
|
|
|
|
}
|
|
|
|
div {
|
|
|
|
max-height: 1lh;
|
|
|
|
}
|
|
|
|
figcaption {
|
|
|
|
margin: 0;
|
|
|
|
margin-left: 10px;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: row;
|
|
|
|
gap: 1ch;
|
|
|
|
font-size: small;
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
<figure>
|
|
|
|
<div>
|
2023-10-09 23:30:39 +00:00
|
|
|
<canvas></canvas>
|
2023-10-05 16:38:25 +00:00
|
|
|
</div>
|
|
|
|
<figcaption></figcaption>
|
|
|
|
</figure>
|
2023-10-04 18:59:46 +00:00
|
|
|
`;
|
2023-10-05 16:38:25 +00:00
|
|
|
this.responsiveStyle = this.shadowRoot.querySelector("#responsive-style");
|
2023-10-11 20:50:10 +00:00
|
|
|
this.canvas = this.shadowRoot.querySelector("canvas");
|
2023-10-05 16:38:25 +00:00
|
|
|
this.caption = this.shadowRoot.querySelector("figcaption");
|
2023-10-04 18:59:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
set data (data) {
|
2023-10-11 20:50:10 +00:00
|
|
|
for (const line of data.title) {
|
|
|
|
this.caption.innerHTML += `<span>${line}</span>`;
|
2023-10-05 16:38:25 +00:00
|
|
|
}
|
2023-10-09 23:30:39 +00:00
|
|
|
|
2023-10-04 18:59:46 +00:00
|
|
|
this.canvas.role = "img";
|
|
|
|
this.canvas.ariaLabel = data.ariaLabel;
|
|
|
|
|
2023-10-09 23:30:39 +00:00
|
|
|
const chartData = {
|
|
|
|
type: "pie",
|
|
|
|
data: data.data,
|
|
|
|
options: {
|
|
|
|
plugins: {
|
|
|
|
title: {
|
|
|
|
display: false
|
|
|
|
},
|
|
|
|
legend: {
|
|
|
|
display: false
|
|
|
|
},
|
|
|
|
tooltip: {
|
|
|
|
enabled: true
|
|
|
|
}
|
2023-10-11 00:26:25 +00:00
|
|
|
},
|
|
|
|
interaction: {
|
|
|
|
mode: "nearest"
|
|
|
|
},
|
2023-10-11 20:50:10 +00:00
|
|
|
onHover: function (e, activeElements) {
|
|
|
|
if (window.innerWidth <= data.breakpoint) {
|
|
|
|
updateTooltipShow(e.chart, false);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
updateTooltipShow(e.chart, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2023-10-09 23:30:39 +00:00
|
|
|
|
2023-10-11 00:26:25 +00:00
|
|
|
this.chart = createChart(this.canvas, chartData);
|
2023-10-05 16:38:25 +00:00
|
|
|
|
2023-10-09 23:30:39 +00:00
|
|
|
if (data.breakpoint) {
|
2023-10-11 00:26:25 +00:00
|
|
|
this.responsiveStyle.media = `screen and (width <= ${data.breakpoint}px)`;
|
2023-10-05 16:38:25 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
this.responsiveStyle.media = "not all";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-09 23:30:39 +00:00
|
|
|
get data () {
|
|
|
|
return null;
|
2023-10-05 16:38:25 +00:00
|
|
|
}
|
2023-10-04 18:59:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function createChart (ctx, data) {
|
2023-10-11 20:50:10 +00:00
|
|
|
return new window.Chart(ctx, data);
|
2023-10-04 18:59:46 +00:00
|
|
|
}
|
|
|
|
|
2023-10-11 20:50:10 +00:00
|
|
|
// this is a really bad way to do this, but chartjs api does not expose many ways to dynamically set hover and tooltip options
|
2023-10-11 00:26:25 +00:00
|
|
|
function updateTooltipShow (chart, enabled) {
|
|
|
|
chart.options.plugins.tooltip.enabled = enabled;
|
|
|
|
chart.options.interaction.mode = enabled ? "nearest" : null;
|
|
|
|
chart.update();
|
|
|
|
}
|
|
|
|
|
2023-10-09 23:30:39 +00:00
|
|
|
customElements.define("resource-chart", ResourceChart);
|