Skip to content

DataviewJS Examples

Josh Glazer edited this page May 31, 2026 · 2 revisions

DataviewJS Examples

Annotation Manager integrates with the Dataview plugin. When Dataview is enabled, each note gets a cc field containing one object per annotation found in that note.


The cc field

Each object in cc has five properties:

Property Type Description
parent string Parent part of the identifier (e.g. math)
child string Child part (e.g. hot), or empty string if none
text string Annotation content
line number 1-based line number where the annotation appears
citation string BibTeX key from a {=/{key}/=} marker immediately following the annotation, or empty string

Example — Dataview (DQL)

Show all math/hot and stats annotations across the vault as a simple table:

dataview
TABLE rows.c.parent AS Parent, rows.c.child AS Child, rows.c.text AS "Annotation"
FROM ""
FLATTEN cc AS c
WHERE (c.parent = "math" AND c.child = "hot") OR c.parent = "stats"
GROUP BY file.link AS File

Example — DataviewJS annotation table

Show all math/hot and stats annotations with clickable line numbers, citation keys, and sorted by Note → Identifier → Line → Annotation:

dataviewjs
const targets = [
  { parent: 'math', child: 'hot' },
  { parent: 'stats', child: '' },
];

function matches(ann, t) {
  return String(ann.parent) === t.parent && String(ann.child) === t.child;
}

const terms = targets.map(t => t.child ? (t.parent + '/' + t.child) : t.parent);
dv.header(2, 'Annotations for ' + terms.join(' and '));

function lineLink(filePath, line) {
  const el = document.createElement('a');
  el.textContent = String(line);
  el.href = '#';
  el.classList.add('internal-link');
  el.addEventListener('click', async (e) => {
    e.preventDefault();
    const file = app.vault.getAbstractFileByPath(filePath);
    if (!file) return;
    const leaf = app.workspace.getLeaf(false);
    await leaf.openFile(file);
    const view = leaf.view;
    if (view?.editor) {
      const pos = { line: line - 1, ch: 0 };
      view.editor.setCursor(pos);
      view.editor.scrollIntoView({ from: pos, to: pos }, true);
    }
  });
  return el;
}

const rows = [];
for (const page of dv.pages().where(p => p.cc)) {
  for (const rawAnn of page.cc) {
    const ann = {
      parent: String(rawAnn.parent ?? ''),
      child: String(rawAnn.child ?? ''),
      text: String(rawAnn.text ?? ''),
      line: rawAnn.line ? Number(rawAnn.line) : null,
      citation: String(rawAnn.citation ?? ''),
    };
    if (targets.some(t => matches(ann, t))) {
      const id = ann.child ? (ann.parent + '/' + ann.child) : ann.parent;
      rows.push({
        note: page.file.name,
        link: page.file.link,
        filePath: page.file.path,
        id,
        line: ann.line,
        text: ann.text,
        citation: ann.citation,
      });
    }
  }
}

rows.sort((a, b) => {
  if (a.note !== b.note) return a.note.localeCompare(b.note);
  if (a.id !== b.id) return a.id.localeCompare(b.id);
  if (a.line !== b.line) {
    if (a.line == null) return 1;
    if (b.line == null) return -1;
    return a.line - b.line;
  }
  return String(a.text).localeCompare(String(b.text));
});

dv.table(
  ['Note', 'Identifier', 'Line', 'Annotation', 'Citation'],
  rows.map(r => [r.link, r.id, r.line ? lineLink(r.filePath, r.line) : '', r.text, r.citation])
);

Example — DataviewJS citation table

Show every annotation that has a citation key attached, across the entire vault, sorted by Note → Identifier → Line → Annotation:

dataviewjs
dv.header(2, 'All citations');

function lineLink(filePath, line) {
  const el = document.createElement('a');
  el.textContent = String(line);
  el.href = '#';
  el.classList.add('internal-link');
  el.addEventListener('click', async (e) => {
    e.preventDefault();
    const file = app.vault.getAbstractFileByPath(filePath);
    if (!file) return;
    const leaf = app.workspace.getLeaf(false);
    await leaf.openFile(file);
    const view = leaf.view;
    if (view?.editor) {
      const pos = { line: line - 1, ch: 0 };
      view.editor.setCursor(pos);
      view.editor.scrollIntoView({ from: pos, to: pos }, true);
    }
  });
  return el;
}

const rows = [];
for (const page of dv.pages().where(p => p.cc)) {
  for (const rawAnn of page.cc) {
    const ann = {
      parent: String(rawAnn.parent ?? ''),
      child: String(rawAnn.child ?? ''),
      text: String(rawAnn.text ?? ''),
      line: rawAnn.line ? Number(rawAnn.line) : null,
      citation: String(rawAnn.citation ?? ''),
    };
    if (!ann.citation) continue;
    const id = ann.child ? (ann.parent + '/' + ann.child) : ann.parent;
    rows.push({
      note: page.file.name,
      link: page.file.link,
      filePath: page.file.path,
      id,
      line: ann.line,
      text: ann.text,
      citation: ann.citation,
    });
  }
}

rows.sort((a, b) => {
  if (a.note !== b.note) return a.note.localeCompare(b.note);
  if (a.id !== b.id) return a.id.localeCompare(b.id);
  if (a.line !== b.line) {
    if (a.line == null) return 1;
    if (b.line == null) return -1;
    return a.line - b.line;
  }
  return String(a.text).localeCompare(String(b.text));
});

dv.table(
  ['Note', 'Identifier', 'Line', 'Annotation', 'Citation'],
  rows.map(r => [r.link, r.id, r.line ? lineLink(r.filePath, r.line) : '', r.text, r.citation])
);

Example — DataviewJS bibliography table

List every .bib file in your configured bib folder as a level-2 header, with a table of entries (key, author, year, title) sorted alphabetically. Requires the Bib files folder path to be set in settings.

dataviewjs
const plugin = app.plugins.plugins['annotation-manager'];
if (!plugin) { dv.paragraph('Annotation Manager plugin not found.'); return; }

const bibData = await plugin.getBibEntries();
const sorted = [...bibData.entries()].sort(([a], [b]) => a.localeCompare(b));

for (const [filename, entries] of sorted) {
  dv.header(2, filename);
  if (entries.length === 0) { dv.paragraph('No entries found.'); continue; }
  dv.table(
    ['Key', 'Author', 'Year', 'Title'],
    entries.map(e => [e.key, e.author, e.year, e.title])
  );
}

Clone this wiki locally