Skip to content

Instantly share code, notes, and snippets.

@weshouman
Last active March 22, 2024 23:50
Show Gist options
  • Save weshouman/f6ffcbedf46fc1dc56c0fc198f181550 to your computer and use it in GitHub Desktop.
Save weshouman/f6ffcbedf46fc1dc56c0fc198f181550 to your computer and use it in GitHub Desktop.
Using Chart.js in Trilium tutorial files
module.exports = async (noteId) => {
const csvContent = await api.runOnBackend(async (noteId) => {
try {
console.log(noteId)
const note = await api.getNote(noteId);
if (note) {
console.log(note);
return await note.getContent();
} else {
console.log('Note not found:', noteId);
return '';
}
} catch (error) {
console.error('Failed to fetch note content:', error);
return '';
}
}, [noteId]);
return csvContent;
}
<div id="chart-containerL">
<canvas id="dataChartFull"></canvas>
</div>
<style>
#chart-containerL {
width: 800px; /* Set to desired width */
height: 400px; /* Set to desired height */
}
</style>
function transformDataPoints(dataPoints) {
return dataPoints.map(point => {
const transformedPoint = {};
Object.entries(point).forEach(([key, value], index) => {
if (index === 0) {
// Transform the first value to Date
transformedPoint[key] = new Date(value);
} else {
// Transform other values to float
transformedPoint[key] = parseFloat(value.replace(/[^\d.-]/g, ''));
}
});
return transformedPoint;
});
}
async function visualizeData(note_id, elem) {
const extractHeaders = true;
console.log(note_id)
const csvContent = await fetchNoteData(note_id);
if (!csvContent) {
console.error('No CSV content retrieved.');
return; // No content was fetched
}
const { data, headers } = parseCSV(csvContent, extractHeaders);
console.log(data);
console.log("headers");
console.log(headers);
const transformedData = transformDataPoints(data);
console.log(transformedData);
renderLineChart(transformedData, headers, elem);
}
let note_id = 'XXXXXXXXXXX';
let elem = '#dataChartFull';
await visualizeData(note_id, elem);
module.exports = (csvContent, hasHeaders = false, defaultHeaders = null) => {
const lines = csvContent.trim().split('\n');
let data = [];
let headers = [];
// Determine headers
if (hasHeaders && lines.length > 0) {
headers = lines.shift().split(',').map(header => header.trim());
} else if (defaultHeaders) {
headers = defaultHeaders;
} else {
// Assume the first line is data and generate default headers
headers = lines[0].split(',').map((_, i) => `Value${i}`);
}
// Parse data
data = lines.map(line => {
const values = line.split(',').map(value => value.trim());
const dataPoint = {};
values.forEach((value, index) => {
dataPoint[headers[index] || `Value${index}`] = value;
});
return dataPoint;
});
return { data, headers };
}
function calculatePadding(datasets, yValueColumnIndices, belowPaddingPercentage = 0.1, abovePaddingPercentage = 0.1) {
// Flatten all y-values across specified column indices into a single array, parsing them as floats
const datasetValues = datasets.flatMap(dataset =>
yValueColumnIndices.map(index => parseFloat(Object.values(dataset)[index])).filter(value => !isNaN(value))
);
const minValue = Math.min(...datasetValues);
const maxValue = Math.max(...datasetValues);
// Calc range
const range = maxValue - minValue;
// Cal padding
const belowPadding = range * belowPaddingPercentage;
const abovePadding = range * abovePaddingPercentage;
return {
minPadding: minValue - belowPadding,
maxPadding: maxValue + abovePadding
};
}
module.exports = (data, headers, elem) => {
const ctx = api.$container.find(elem)[0].getContext("2d");
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
const totalColumns = Object.values(data[0]).length;
const yValueColumnIndices = Array.from({ length: totalColumns - 1 }, (_, i) => i + 1);
const padding = calculatePadding(data, yValueColumnIndices);
const datasets = headers.slice(1).map((header, index) => ({
label: header,
data: data.map(item => ({
t: item[headers[0]], // First header is the x-value
y: parseFloat(item[header]) // Convert y-values to float
})),
fill: false,
borderColor: `hsl(${360 * index / headers.length}, 70%, 50%)`, // Example color generation
lineTension: 0.01
}));
const myLineChart = new Chart(ctx, {
type: 'line',
data: { datasets },
options: {
plugins: {
datalabels: {
display: false
}
},
scales: {
yAxes: [{
ticks: {
suggestedMin: padding.minPadding,
suggestedMax: padding.maxPadding,
autoSkip: true,
autoSkipPadding: 20
}
}],
xAxes: [{
type: 'time',
time: {
tooltipFormat: 'YYYY-MM-DD HH:mm:ss',
displayFormats: {
minute: 'YYYY-MM-DD HH:mm',
hour: 'YYYY-MM-DD HH:mm',
day: 'YYYY-MM-DD'
}
},
scaleLabel: {
display: true,
labelString: headers[0] // First header for x-axis label
},
ticks: {
maxRotation: 90,
minRotation: 90,
autoSkip: true,
autoSkipPadding: 20
}
}]
},
legend: {
display: true
},
animation: {
duration: 0 // Disable animations
}
}
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment