Base/Knowledges/Статистика/Список книг.md

5.6 KiB
Raw Blame History

📊 Статистика

const books = dv.pages('"Библиотека/Книги"').where(p => p.Тип == "Книга");
const read = books.where(p => p.Статус == "Прочитано");
const inProgress = books.where(p => p.Статус == "В процессе");
const planned = books.where(p => p.Статус == "Хочу прочитать" || p.Статус == "Запланировано");
const abandoned = books.where(p => p.Статус == "Заброшена");

const totalPages = read.array().reduce((sum, p) => sum + (Number(p["Количество страниц"]) || 0), 0);
const rated = read.where(p => p.Оценка);
const avgRating = rated.length
  ? (rated.array().reduce((s, p) => s + Number(p.Оценка), 0) / rated.length).toFixed(1)
  : "—";

dv.table(["", ""], [
  ["📚 Всего книг",         books.length],
  ["✅ Прочитано",          read.length],
  ["📖 Читаю сейчас",      inProgress.length],
  ["🔖 Хочу прочитать",    planned.length],
  ["⛔ Заброшено",          abandoned.length],
  ["📄 Страниц прочитано", totalPages.toLocaleString("ru-RU")],
  ["⭐ Средняя оценка",    avgRating],
]);

const books = dv.pages('"Библиотека/Книги"')
  .where(p => p.Тип == "Книга" && p.Статус == "В процессе");

if (!books.length) {
  dv.paragraph("*Сейчас ничего не читаю*");
} else {
  dv.table(["Обложка", "Название", "Автор", "Прогресс", "Страниц"],
    books.map(p => {
      const total = Number(p["Количество страниц"]) || 0;
      const done = Number(p.Прогресс) || 0;
      const pct = total ? Math.round(done / total * 100) : 0;
      const filled = Math.round(pct / 10);
      const bar = "█".repeat(filled) + "░".repeat(10 - filled);
      return [
        p.Обложка ? dv.span(`![|75](${p.Обложка})`) : "—",
        p.file.link,
        p.Автор ? [].concat(p.Автор).join(", ") : "—",
        `\`${bar}\` ${pct}%`,
        `${done} / ${total}`
      ];
    })
  );
}

const details = document.createElement("details");
details.setAttribute("open", "");
const summary = document.createElement("summary");
summary.innerHTML = `<strong>📖 Читаю сейчас (${books.length})</strong>`;
details.appendChild(summary);
Array.from(this.container.childNodes).forEach(n => details.appendChild(n));
this.container.appendChild(details);

const fmt = f => ({ "Электронная": "📱", "Бумажная": "📗", "Аудио": "🎧" }[f] ?? "");
const books = dv.pages('"Библиотека/Книги"')
  .where(p => p.Тип == "Книга" && (p.Статус == "Хочу прочитать" || p.Статус == "Запланировано"))
  .sort(p => p.Название, "asc");

dv.table(["Обложка", "Название", "Автор", "Страниц", "Формат", "Категория"],
  books.map(p => [
    p.Обложка ? dv.span(`![|75](${p.Обложка})`) : "—",
    p.file.link,
    p.Автор ? [].concat(p.Автор).join(", ") : "—",
    p["Количество страниц"] || "—",
    fmt(p.Формат),
    p.Категории ? [].concat(p.Категории).join(", ") : "—"
  ])
);

const details = document.createElement("details");
const summary = document.createElement("summary");
summary.innerHTML = `<strong>🔖 Хочу прочитать (${books.length})</strong>`;
details.appendChild(summary);
Array.from(this.container.childNodes).forEach(n => details.appendChild(n));
this.container.appendChild(details);

const star = n => n ? `⭐ ${Number(n)}` : "—";
const fmt = f => ({ "Электронная": "📱", "Бумажная": "📗", "Аудио": "🎧" }[f] ?? f ?? "—");
const books = dv.pages('"Библиотека/Книги"')
  .where(p => p.Тип == "Книга" && p.Статус == "Прочитано")
  .sort(p => Number(p.Закончена) || 0, "desc");

dv.table(["Обложка", "Название", "Автор", "Год", "Оценка", "Формат", "Категория"],
  books.map(p => [
    p.Обложка ? dv.span(`![|75](${p.Обложка})`) : "—",
    p.file.link,
    p.Автор ? [].concat(p.Автор).join(", ") : "—",
    p.Закончена || "—",
    star(p.Оценка),
    fmt(p.Формат),
    p.Категории ? [].concat(p.Категории).join(", ") : "—"
  ])
);

const details = document.createElement("details");
const summary = document.createElement("summary");
summary.innerHTML = `<strong>✅ Прочитано (${books.length})</strong>`;
details.appendChild(summary);
Array.from(this.container.childNodes).forEach(n => details.appendChild(n));
this.container.appendChild(details);

const books = dv.pages('"Библиотека/Книги"')
  .where(p => p.Тип == "Книга" && p.Статус == "Заброшена");

if (!books.length) {
  dv.paragraph("*Нет заброшенных книг*");
} else {
  dv.table(["Название", "Автор", "Прочитано страниц"],
    books.map(p => [
      p.file.link,
      p.Автор ? [].concat(p.Автор).join(", ") : "—",
      p.Прогресс || "—"
    ])
  );
}

const details = document.createElement("details");
const summary = document.createElement("summary");
summary.innerHTML = `<strong>⛔ Заброшено (${books.length})</strong>`;
details.appendChild(summary);
Array.from(this.container.childNodes).forEach(n => details.appendChild(n));
this.container.appendChild(details);