Chart / dataset /web /Chart.js /scatter /chart_0053_scatter.html
Pekku's picture
Upload folder using huggingface_hub
79dc9c8 verified
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Quadrants</title>
<style>
:root {
color-scheme: light;
}
body {
margin: 0;
padding: 20px;
font-family: Segoe UI, Arial, sans-serif;
background: #f5f7fb;
color: #1f2a37;
}
h1 {
margin: 0 0 10px 0;
font-size: 20px;
font-weight: 600;
}
#legend-container {
margin-bottom: 8px;
}
#chart-wrap {
position: relative;
width: min(1100px, 100%);
height: 520px;
background: #ffffff;
border: 1px solid #e2e8f0;
border-radius: 10px;
padding: 12px;
box-sizing: border-box;
}
#chart {
width: 100%;
height: 100%;
}
</style>
<script src="./luxon.min.js"></script>
<script src="./chart.umd.min.js"></script>
<script src="./chartjs-adapter-luxon.umd.min.js"></script>
</head>
<body>
<h1>Quadrants</h1>
<div id="legend-container"></div>
<div id="chart-wrap">
<canvas id="chart"></canvas>
</div>
<script>
const components = { Tooltip: Chart.Tooltip };
const Utils = (() => {
let _seed = 1;
const valueOrDefault = (value, defaultValue) => (value === undefined ? defaultValue : value);
const MONTHS = [
'January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'
];
const COLORS = [
'#4dc9f6', '#f67019', '#f53794', '#537bc4',
'#acc236', '#166a8f', '#00a950', '#58595b', '#8549ba'
];
const CHART_COLORS = {
red: 'rgb(255, 99, 132)',
orange: 'rgb(255, 159, 64)',
yellow: 'rgb(255, 205, 86)',
green: 'rgb(75, 192, 192)',
blue: 'rgb(54, 162, 235)',
purple: 'rgb(153, 102, 255)',
grey: 'rgb(201, 203, 207)'
};
const NAMED_COLORS = [
CHART_COLORS.red,
CHART_COLORS.orange,
CHART_COLORS.yellow,
CHART_COLORS.green,
CHART_COLORS.blue,
CHART_COLORS.purple,
CHART_COLORS.grey
];
function srand(seedValue) {
const normalized = Number(seedValue);
_seed = Number.isFinite(normalized) ? (normalized >>> 0) : 1;
}
function rand(min, max) {
const low = valueOrDefault(min, 0);
const high = valueOrDefault(max, 0);
_seed = (_seed * 9301 + 49297) % 233280;
return low + (_seed / 233280) * (high - low);
}
function numbers(config) {
const cfg = config || {};
const min = valueOrDefault(cfg.min, 0);
const max = valueOrDefault(cfg.max, 100);
const from = valueOrDefault(cfg.from, []);
const count = valueOrDefault(cfg.count, 8);
const decimals = valueOrDefault(cfg.decimals, 8);
const continuity = valueOrDefault(cfg.continuity, 1);
const dfactor = Math.pow(10, decimals) || 0;
const data = [];
for (let i = 0; i < count; ++i) {
const value = (from[i] || 0) + rand(min, max);
if (rand(0, 1) <= continuity) {
data.push(Math.round(dfactor * value) / dfactor);
} else {
data.push(null);
}
}
return data;
}
function points(config) {
const xs = numbers(config);
const ys = numbers(config);
return xs.map((x, i) => ({x, y: ys[i]}));
}
function bubbles(config) {
const cfg = config || {};
return points(cfg).map((pt) => ({...pt, r: rand(cfg.rmin, cfg.rmax)}));
}
function labels(config) {
const cfg = config || {};
const min = valueOrDefault(cfg.min, 0);
const max = valueOrDefault(cfg.max, 100);
const count = valueOrDefault(cfg.count, 8);
const decimals = valueOrDefault(cfg.decimals, 8);
const prefix = valueOrDefault(cfg.prefix, '');
const step = (max - min) / count;
const dfactor = Math.pow(10, decimals) || 0;
const values = [];
for (let i = min; i < max; i += step) {
values.push(prefix + Math.round(dfactor * i) / dfactor);
}
return values;
}
function months(config) {
const cfg = config || {};
const count = valueOrDefault(cfg.count, 12);
const section = cfg.section;
const values = [];
for (let i = 0; i < count; ++i) {
const value = MONTHS[Math.ceil(i) % 12];
values.push(value.substring(0, section));
}
return values;
}
function color(index) {
return COLORS[index % COLORS.length];
}
function parseColorToRgb(input) {
const value = String(input || '').trim();
const hex3 = /^#([0-9a-f]{3})$/i.exec(value);
if (hex3) {
const r = parseInt(hex3[1][0] + hex3[1][0], 16);
const g = parseInt(hex3[1][1] + hex3[1][1], 16);
const b = parseInt(hex3[1][2] + hex3[1][2], 16);
return [r, g, b];
}
const hex6 = /^#([0-9a-f]{6})$/i.exec(value);
if (hex6) {
const intValue = parseInt(hex6[1], 16);
const r = (intValue >> 16) & 255;
const g = (intValue >> 8) & 255;
const b = intValue & 255;
return [r, g, b];
}
const rgb = /^rgba?\(([^)]+)\)$/i.exec(value);
if (rgb) {
const parts = rgb[1].split(',').map((part) => Number(part.trim()));
if (parts.length >= 3) {
return [parts[0] || 0, parts[1] || 0, parts[2] || 0];
}
}
const helper = document.createElement('canvas').getContext('2d');
helper.fillStyle = value || '#000000';
const normalized = helper.fillStyle;
const fallback = /^rgba?\(([^)]+)\)$/i.exec(normalized);
if (fallback) {
const parts = fallback[1].split(',').map((part) => Number(part.trim()));
if (parts.length >= 3) {
return [parts[0] || 0, parts[1] || 0, parts[2] || 0];
}
}
return [0, 0, 0];
}
function transparentize(value, opacity) {
const alpha = opacity === undefined ? 0.5 : 1 - opacity;
const [r, g, b] = parseColorToRgb(value);
return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + alpha + ')';
}
const BASE_DATE_MS = Date.UTC(2021, 0, 1, 0, 0, 0, 0);
function newDate(days) {
return new Date(BASE_DATE_MS + (Number(days) || 0) * 24 * 60 * 60 * 1000);
}
function newDateString(days) {
return newDate(days).toISOString();
}
function parseISODate(str) {
const millis = Date.parse(str);
return {
toMillis() {
return millis;
}
};
}
return {
srand,
rand,
numbers,
points,
bubbles,
labels,
months,
color,
transparentize,
CHART_COLORS,
namedColor(index) {
return NAMED_COLORS[index % NAMED_COLORS.length];
},
newDate,
newDateString,
parseISODate
};
})();
window.components = components;
window.Utils = Utils;
Utils.srand(101050);
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const data = {
datasets: [
{
label: 'Dataset 1',
data: Utils.points(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
},
{
label: 'Dataset 2',
data: Utils.points(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
}
]
};
const quadrants = {
id: 'quadrants',
beforeDraw(chart, args, options) {
const {ctx, chartArea: {left, top, right, bottom}, scales: {x, y}} = chart;
const midX = x.getPixelForValue(0);
const midY = y.getPixelForValue(0);
ctx.save();
ctx.fillStyle = options.topLeft;
ctx.fillRect(left, top, midX - left, midY - top);
ctx.fillStyle = options.topRight;
ctx.fillRect(midX, top, right - midX, midY - top);
ctx.fillStyle = options.bottomRight;
ctx.fillRect(midX, midY, right - midX, bottom - midY);
ctx.fillStyle = options.bottomLeft;
ctx.fillRect(left, midY, midX - left, bottom - midY);
ctx.restore();
}
};
const config = {
type: 'scatter',
data: data,
options: {
plugins: {
quadrants: {
topLeft: Utils.CHART_COLORS.red,
topRight: Utils.CHART_COLORS.blue,
bottomRight: Utils.CHART_COLORS.green,
bottomLeft: Utils.CHART_COLORS.yellow,
}
}
},
plugins: [quadrants]
};
function forceEnableHoverTooltip(chartConfig) {
if (!chartConfig || typeof chartConfig !== 'object') {
return;
}
if (!chartConfig.options || typeof chartConfig.options !== 'object') {
chartConfig.options = {};
}
const options = chartConfig.options;
if (!options.plugins || typeof options.plugins !== 'object') {
options.plugins = {};
}
const plugins = options.plugins;
if (plugins.tooltip === false) {
plugins.tooltip = {};
}
if (!plugins.tooltip || typeof plugins.tooltip !== 'object') {
plugins.tooltip = {};
}
const hasExternalTooltip = typeof plugins.tooltip.external === 'function';
if (!hasExternalTooltip) {
plugins.tooltip.enabled = true;
}
}
forceEnableHoverTooltip(config);
const sampleCanvas = document.getElementById('chart');
const sampleChart = new Chart(sampleCanvas, config);
</script>
</body>
</html>