Skip to content

weight-tracker #19

@jiyunzhang2024-rgb

Description

@jiyunzhang2024-rgb

function draw() {
const canvas = document.getElementById('chart');
const ctx = canvas.getContext('2d');

canvas.width = canvas.offsetWidth;
canvas.height = 400;

const w = canvas.width;
const h = canvas.height;

ctx.clearRect(0, 0, w, h);

const padding = { left: 60, right: 20, top: 20, bottom: 50 };

const allData = [];
for (let p in db.people) {
db.people[p].forEach(r => allData.push(r));
}

if (allData.length === 0) {
ctx.fillText("暂无数据", w / 2, h / 2);
return;
}

// ===== 时间处理 =====
const dates = [...new Set(allData.map(d => d.date))].sort();
const dateIndex = {};
dates.forEach((d, i) => dateIndex[d] = i);

// ===== weight range =====
const weights = allData.map(d => d.weight);
const minW = Math.min(...weights) - 1;
const maxW = Math.max(...weights) + 1;

const cw = w - padding.left - padding.right;
const ch = h - padding.top - padding.bottom;

function getX(date) {
return padding.left + (dateIndex[date] / (dates.length - 1)) * cw;
}

function getY(weight) {
return padding.top + ch - ((weight - minW) / (maxW - minW)) * ch;
}

// ===== 坐标轴 =====
ctx.strokeStyle = "#ccc";
ctx.beginPath();
ctx.moveTo(padding.left, padding.top);
ctx.lineTo(padding.left, padding.top + ch);
ctx.lineTo(padding.left + cw, padding.top + ch);
ctx.stroke();

// ===== Y轴刻度 =====
ctx.fillStyle = "#666";
ctx.textAlign = "right";

for (let i = 0; i <= 5; i++) {
const val = minW + (maxW - minW) * (i / 5);
const y = getY(val);

ctx.fillText(val.toFixed(1), padding.left - 8, y + 4);

ctx.strokeStyle = "#eee";
ctx.beginPath();
ctx.moveTo(padding.left, y);
ctx.lineTo(padding.left + cw, y);
ctx.stroke();

}

// ===== X轴日期 =====
ctx.textAlign = "center";
dates.forEach(d => {
const x = getX(d);
ctx.fillText(d.slice(5), x, padding.top + ch + 20);
});

// ===== 多人曲线 =====
const colors = ["#ff6b81", "#1e90ff", "#2ed573", "#ffa502", "#a55eea"];

let idx = 0;
for (let name in db.people) {
const arr = db.people[name];
if (arr.length === 0) continue;

ctx.strokeStyle = colors[idx % colors.length];
ctx.lineWidth = 2;

ctx.beginPath();

arr.forEach((r, i) => {
  const x = getX(r.date);
  const y = getY(r.weight);

  if (i === 0) ctx.moveTo(x, y);
  else ctx.lineTo(x, y);
});

ctx.stroke();

// 点
arr.forEach(r => {
  const x = getX(r.date);
  const y = getY(r.weight);

  ctx.beginPath();
  ctx.arc(x, y, 4, 0, Math.PI * 2);
  ctx.fillStyle = colors[idx % colors.length];
  ctx.fill();
});

// legend
ctx.fillStyle = colors[idx % colors.length];
ctx.fillText(name, w - 80, 20 + idx * 18);

idx++;

}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions