Install
$ agentstack add skill-gsarig-skills-obsidian-charts ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Build charts inside dataviewjs code blocks using the obsidian-charts plugin (phibr0).
Two rendering modes
1. YAML chart block (simple — no data labels)
Output a fenced `chart ` block as a string and pass it to dv.paragraph(). Supported for line and bar charts.
const NL = String.fromCharCode(10); // never use \n inside JS string literals in dataviewjs
function lineChart(labels, series) {
return [
'```chart', 'type: line',
'labels: ' + JSON.stringify(labels),
'series:', ...series,
'tension: 0.3', 'width: 100%', 'labelColors: true',
'transparency: 0.1', 'fill: false', 'beginAtZero: false',
'```'
].join(NL);
}
// series item helper
function seriesYaml(title, data) {
return [` - title: "${title}"`, ` data: ${JSON.stringify(data)}`].join(NL);
}
dv.paragraph(lineChart(['Jan', 'Feb', 'Mar'], [seriesYaml('Sales', [10, 20, 15])]));
Use this mode for: line charts, when data labels above bars are not needed.
Supported YAML options: type, labels, series, tension, width, labelColors, transparency, fill, beginAtZero, spanGaps, stacked, indexAxis, borderWidth, borderColor, pointStyle.
dataLabels: true does NOT exist in this plugin — it is silently ignored.
2. window.renderChart (full Chart.js — supports data labels)
Use window.renderChart(config, container) to get access to Chart.js directly. Required whenever values need to appear above bars.
const topLabelsPlugin = {
id: 'topLabels',
afterDatasetsDraw(chart) {
const ctx = chart.ctx;
ctx.save();
ctx.font = 'bold 11px sans-serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
chart.data.datasets.forEach((ds, di) => {
const meta = chart.getDatasetMeta(di);
if (meta.hidden) return;
ds.data.forEach((val, i) => {
if (val == null || val === 0) return;
const bar = meta.data[i];
if (!bar) return;
ctx.fillStyle = '#666';
ctx.fillText(String(val), bar.x, bar.y - 3);
});
});
ctx.restore();
}
};
Container element:
- Single chart per dataviewjs block: use
this.container(the block's own container). - Multiple charts in one block: create a fresh container per chart with
dv.el('div', '').
// Multiple charts in one block
function renderBar(title, labelsArr, seriesArr) {
dv.header(3, title);
const el = dv.el('div', '');
window.renderChart({
type: 'bar',
data: {
labels: labelsArr,
datasets: seriesArr.map((s, i) => ({
label: s.title,
data: s.data,
backgroundColor: BAR_COLORS[i % BAR_COLORS.length][0],
borderColor: BAR_COLORS[i % BAR_COLORS.length][1],
borderWidth: 1
}))
},
options: {
responsive: true,
plugins: { legend: { display: true } },
scales: { y: { beginAtZero: true } },
layout: { padding: { top: 20 } } // room for labels above tallest bar
},
plugins: [topLabelsPlugin]
}, el);
}
plugins is a top-level key in the config object (Chart.js v3 per-chart plugin syntax), not inside options.
Standard color palette
const BAR_COLORS = [
['rgba(54,162,235,0.7)', 'rgba(54,162,235,1)'], // blue
['rgba(255,159,64,0.7)', 'rgba(255,159,64,1)'], // orange
['rgba(153,102,255,0.7)','rgba(153,102,255,1)'], // purple
];
Pitfalls
- Never use
\ninside JS string literals in a dataviewjs block — it causes a SyntaxError when Obsidian parses the block. Always useconst NL = String.fromCharCode(10)and build multi-line strings with.join(NL). - Plugin id collisions: if multiple
window.renderChartcalls share the same plugin object but register under the sameid, Chart.js may warn. Give each plugin instance a uniqueid('topLabels','topLabels2', etc.) when rendering multiple charts. chartjs-plugin-datalabelsis not bundled in the obsidian-charts plugin. Do not attempt to use it.- Dataview DataArray is not a plain array.
dv.pages().map().filter()returns a DataviewDataArray, which does not have.reduce(),.indexOf(), or other standard Array methods. Call.array()to convert before using them:dv.pages().map(...).filter(...).array().for...ofand.lengthwork on DataArrays without conversion.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: gsarig
- Source: gsarig/skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.