Example: Doughnut | Error: Uncaught ReferenceError: Utils is not defined - javascript

unfortunately I fail with this example.
I include the following scripts:
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns" crossorigin="anonymous"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/chart.js#3.2.0/dist/helpers.esm.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.2.0/dist/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.2.0/dist/chart.js"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/chart.js#3.2.0/dist/chart.esm.min.js"></script>
and this is my function(it is a copy from the example side)
https://www.chartjs.org/docs/3.2.0/samples/other-charts/doughnut.html
function donutchart(){
//-----SETUP-------
const DATA_COUNT = 5;
const NUMBER_CFG = {count: DATA_COUNT, min: 0, max: 100};
const data = {
labels: ['Red', 'Orange', 'Yellow', 'Green', 'Blue'],
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
backgroundColor: Object.values(Utils.CHART_COLORS),
}
]
};
//-----Config----------
const config = {
type: 'doughnut',
data: data,
options: {
responsive: true,
plugins: {
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Doughnut Chart'
}
}
},
};
//-------Actions--------
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: 0, max: 100});
});
chart.update();
}
},
{
name: 'Add Dataset',
handler(chart) {
const data = chart.data;
const newDataset = {
label: 'Dataset ' + (data.datasets.length + 1),
backgroundColor: [],
data: [],
};
for (let i = 0; i < data.labels.length; i++) {
newDataset.data.push(Utils.numbers({count: 1, min: 0, max: 100}));
const colorIndex = i % Object.keys(Utils.CHART_COLORS).length;
newDataset.backgroundColor.push(Object.values(Utils.CHART_COLORS)[colorIndex]);
}
chart.data.datasets.push(newDataset);
chart.update();
}
},
{
name: 'Add Data',
handler(chart) {
const data = chart.data;
if (data.datasets.length > 0) {
data.labels.push('data #' + (data.labels.length + 1));
for (var index = 0; index < data.datasets.length; ++index) {
data.datasets[index].data.push(Utils.rand(0, 100));
}
chart.update();
}
}
},
{
name: 'Remove Dataset',
handler(chart) {
chart.data.datasets.pop();
chart.update();
}
},
{
name: 'Remove Data',
handler(chart) {
chart.data.labels.splice(-1, 1); // remove the label first
chart.data.datasets.forEach(dataset => {
dataset.data.pop();
});
chart.update();
}
}
];
// === include 'setup' then 'config' above ===
var myChart = new Chart(
document.getElementById('Quota'),
config
);
}
If i run the script i get the following error message:
Uncaught ReferenceError: Utils is not defined
and now I've been looking for one or two days what "utils" is and how I can integrate it
Please Help me!
Thx
Thomas

Utils is a helper file chart.js uses and makes internally to generate datasets and some more things, it was removed as a public source in chart.js version 3, if you want to use it you can download it here: (https://github.com/chartjs/Chart.js/blob/master/docs/scripts/utils.js) or get the online file here: (https://www.chartjs.org/samples/2.9.4/utils.js)
If you want a good starting point/example you can copy the code from the usage page, there is the chart code for a basic chart where you don't need anything else for: https://www.chartjs.org/docs/master/getting-started/usage.html

Related

Chart.js hover over label

This bounty has ended. Answers to this question are eligible for a +50 reputation bounty. Bounty grace period ends in 3 hours.
Software Dev wants to draw more attention to this question.
I have a bar chart in Chart.js (using the latest version), and I want to make some visual change when the mouse is hovering over a category label. How would I implement either or both of the following visual changes?
Make the cursor be a pointer while hovering over a label.
Make the label be in a different color while it is being hovered on.
A related question is here: How to detect click on chart js 3.7.1 axis label?. However, my question is about hovering over a label, without clicking on the label.
In the example below, I want something to happen when hovering on these texts: Item A, Item B, Item C.
window.onload = function() {
var ctx = document.getElementById('myChart').getContext('2d');
window.myBar = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Item A', 'Item B', 'Item C'],
datasets: [{
data: [1, 2, 3],
backgroundColor: 'lightblue'
}]
},
options: {
responsive: true,
indexAxis: 'y',
plugins: {
legend: {
display: false
},
tooltip: {
enabled: false
},
}
}
});
};
.chart-container {
position: relative;
height: 90vh;
}
<script src="https://cdn.jsdelivr.net/npm/chart.js#4.2.0"></script>
<div class="chart-container">
<canvas id="myChart"></canvas>
</div>
You can just use the custom plugin from that question and ignore everything but mousemove events instead of ignoring everything but click events:
const findLabel = (labels, evt) => {
let found = false;
let res = null;
labels.forEach(l => {
l.labels.forEach((label, index) => {
if (evt.x > label.x && evt.x < label.x2 && evt.y > label.y && evt.y < label.y2) {
res = {
label: label.label,
index
};
found = true;
}
});
});
return [found, res];
};
const getLabelHitboxes = (scales) => (Object.values(scales).map((s) => ({
scaleId: s.id,
labels: s._labelItems.map((e, i) => ({
x: e.translation[0] - s._labelSizes.widths[i],
x2: e.translation[0] + s._labelSizes.widths[i] / 2,
y: e.translation[1] - s._labelSizes.heights[i] / 2,
y2: e.translation[1] + s._labelSizes.heights[i] / 2,
label: e.label,
index: i
}))
})));
const plugin = {
id: 'customHover',
afterEvent: (chart, event, opts) => {
const evt = event.event;
if (evt.type !== 'mousemove') {
return;
}
const [found, labelInfo] = findLabel(getLabelHitboxes(chart.scales), evt);
if (found) {
console.log(labelInfo);
}
}
}
Chart.register(plugin);
const options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderColor: 'pink'
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderColor: 'orange'
}
]
},
options: {}
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.js"></script>
</body>
To change the cursor to a pointer when hovering over a category label in a Chart.js bar chart, you can add:
options: {
plugins: {
tooltip: {
mode: 'index',
intersect: false
},
},
interaction: {
mode: 'index',
intersect: false
},
onHover: function(evt, elements) {
if (elements.length) {
document.getElementById("myChart").style.cursor = "pointer";
} else {
document.getElementById("myChart").style.cursor = "default";
}
},
// ...
}
To change the color of a label when it is being hovered on, you can add:
options: {
plugins: {
tooltip: {
mode: 'index',
intersect: false
},
},
interaction: {
mode: 'index',
intersect: false
},
onHover: function(evt, elements) {
if (elements.length) {
var chart = evt.chart;
var datasetIndex = elements[0].datasetIndex;
var index = elements[0].index;
chart.data.labels[index] = '<span style="color: red;">' + chart.data.labels[index] + '</span>';
chart.update();
} else {
var chart = evt.chart;
chart.data.labels = ['Item A', 'Item B', 'Item C'];
chart.update();
}
},
// ...
}
To make the cursor a pointer while hovering over a label, you can try to assign a CSS cursor value to event.native.target.style.cursor when hover is triggered.
event.native.target.style.cursor = 'pointer';
To make the label a different color while it is being hovered on, you can try this
myChart.config.options.scales.y.ticks.color = hoverColors; // ['black','red','black'], ['black','black','red'], ['red','black','black']
UPDATE
Thanks to LeeLenalee for giving an almost correct answer. I've edited the code above so it fits what is required in the problem. Don't forget to change source of the library in the HTML from :
https://cdn.jsdelivr.net/npm/chart.js#4.2.0
to :
https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.js
Updated code:
window.onload = function() {
const findLabel = (labels, evt) => {
let found = false;
let res = null;
try {
labels.forEach(l => {
l.labels.forEach((label, index) => {
if (evt.x > label.x && evt.x < label.x2 && evt.y > label.y && evt.y < label.y2) {
res = {
label: label.label,
index
};
found = true;
}
});
});
} catch (e) {}
return [found, res];
};
const getLabelHitboxes = (scales) => {
try {
return Object.values(scales).map((s) => ({
scaleId: s.id,
labels: s._labelItems.map((e, i) => ({
x: e.translation[0] - s._labelSizes.widths[i],
x2: e.translation[0] + s._labelSizes.widths[i] / 2,
y: e.translation[1] - s._labelSizes.heights[i] / 2,
y2: e.translation[1] + s._labelSizes.heights[i] / 2,
label: e.label,
index: i
}))
}));
} catch (e) {}
};
const changeCursorAndLabelColor = (event, chart, index, hoverMode) => {
// your hover color here
// const hoverColor = '#ff0000';
const hoverColor = 'red';
const hoverColors = [];
for (let i = 0; i < myChart.data.datasets[0].data.length; i++) {
if (hoverMode) {
// change cursor
event.native.target.style.cursor = 'pointer';
if (index === i) {
hoverColors.push(hoverColor);
} else {
hoverColors.push(defaultLabelColor);
}
} else {
// change cursor
event.native.target.style.cursor = 'default';
hoverColors.push(defaultLabelColor);
}
}
// change label to your hover color
myChart.config.options.scales.y.ticks.color = hoverColors;
// update chart when hover is triggered
myChart.update();
}
let foundMode = false;
const plugin = {
id: 'customHover',
afterEvent: (chart, event, opts) => {
const evt = event.event;
if (evt.type !== 'mousemove') {
return;
}
const [found, labelInfo] = findLabel(getLabelHitboxes(chart.scales), evt);
if (found && myChart.data.labels.includes(labelInfo.label)) {
changeCursorAndLabelColor(evt, chart, labelInfo.index, true);
foundMode = true;
} else {
if (foundMode) changeCursorAndLabelColor(evt, chart, null, false);
foundMode = false;
}
}
}
Chart.register(plugin);
var ctx = document.getElementById('myChart');
const myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Item A', 'Item B', 'Item C'],
datasets: [{
label: 'My Data',
data: [1, 2, 3],
backgroundColor: 'lightblue'
}]
},
options: {
responsive: true,
indexAxis: 'y',
plugins: {
legend: {
display: false
},
tooltip: {
enabled: false
},
},
onHover: (event, chart) => {
if (foundMode) changeCursorAndLabelColor(event, chart, null, false);
foundMode = false;
}
}
});
const defaultLabelColor = myChart.config.options.scales.y.ticks.color;
};
.chart-container {
position: relative;
height: 90vh;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.js"></script>
<div class="chart-container">
<canvas id="myChart"></canvas>
</div>

how to run a python file in Typescript file

I have a typescript extension that needs to run a python file. after a file dialog is opened the extension uses exec to run the following command.
python C:\\Users\\schriste\\.vscode\\extensions\\consolidatedExtension\\src\\testingFile.py C:\\EquipVsCode\\5G_ServingCell_Rsrp_Rsrq_Sinr_RSSI_B974_all.isf
I thought exec would work since ive tired exec using the windows command dir and it worked just fine.
all I need is the right function to run the command shown above. has anyone done this? it seems like such a simple and common task but im having so much difficulty finding information on how this can be done.
below is the code from extension.ts
perhaps someone has information on how the following work for what I am trying to accomplish but I have not found a way for these to work as of right now: execFile spawn
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';
import { open } from 'fs';
import * as path from 'path';
import { json } from 'stream/consumers';
const { ChildProcess, exec } = require('child_process');
const { execFile } = require('node:child_process');
const { spawn } = require('node:child_process');
const { stdout, stderr } = require('process');
// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {
//File Dialog
let disposable = vscode.commands.registerCommand('consolidatedExtension.openFile', function () {
const options = {
canSelectMany: false,
openLabel: 'Open'
};
vscode.window.showOpenDialog(options).then(fileUri => {
if (fileUri && fileUri[0]) {
console.log('Selected file: ' + fileUri[0].fsPath);
let cmd = `python C:\\Users\\schriste\\.vscode\\extensions\\consolidatedExtension\\src\\testingFile.py` + ` ` + fileUri[0].fsPath
exec(cmd2, (...args: any[])=>{
console.log(args);
});
}
});
});
//open graphView
let openWebview = vscode.commands.registerCommand('consolidatedExtension.openWebview', () => {
const panel = vscode.window.createWebviewPanel(
'openWebview', // Identifies the type of the webview. Used internally
'Example Page', // Title of the panel displayed to the user
vscode.ViewColumn.One, // Editor column to show the new webview panel in.
{ // Enable scripts in the webview
enableScripts: true //Set this to true if you want to enable Javascript.
});
//get path to json on disk
const onDiskPath = vscode.Uri.file(
path.join(context.extensionPath, 'src', 'data.json')
);
//get vegaLite js on disk
const JsonDiskPath = vscode.Uri.file(
path.join(context.extensionPath, 'src', 'vegaLiteGraphs.js')
);
//and get the special URI to use with the webview
const jsonSRC = panel.webview.asWebviewUri(onDiskPath);
const jsSRC = panel.webview.asWebviewUri(JsonDiskPath);
panel.webview.html = getWebviewContent(jsonSRC, jsSRC);
});
context.subscriptions.push(openWebview);
context.subscriptions.push(disposable);
}
// this method is called when your extension is deactivated
export function deactivate() {}
function getWebviewContent(jsonSRC:vscode.Uri, jsSRC:vscode.Uri) {
return `<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdn.jsdelivr.net/npm/vega#5.21.0"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-lite#5.2.0"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-embed#6.20.2"></script>
</head>
<body>
<script type = "module">
import users from '${jsonSRC}' assert {type: 'json'};
const graphDataContainer = []
let dataPoints = []
for(let i = 0; i < users.length; i += 2)
{
for (let j = 1; j < users[i].length; j++) {
dataPoints.push({
x: users[i][j],
y: users[i + 1][j]
});
}
graphDataContainer.push(dataPoints)
dataPoints = []
}
console.log(graphDataContainer)
window.onload = function() {
let i = 0
var chart1 = new CanvasJS.Chart("chart1", {
animationEnabled: true,
zoomEnabled: true,
theme: "light2",
"title": { "text": "RSRP" },
axisX: {
gridThickness: 0,
tickLength: 0,
lineThickness: 0,
labelFormatter: function(){ return " "; },
crosshair: {
enabled: true,
color: "black",
labelFontColor: "#F8F8F8"
},
//interval: 10,
//intervalType: "millisecond",
//valueFormatString: "##.##.####"
},
axisY: {
crosshair: {
enabled: true,
color: "black",
labelFontColor: "#F8F8F8"
},
title: "Serving Cell RSRP (dBm)",
minimum: -100,
maximum: 0,
interval: 16.67
},
data: [{
type: "line",
//yValueFormatString: "#,### Units",
dataPoints: graphDataContainer[i]
}],
rangeChanged: syncHandler
});
chart1.render();
i++
var rsrqChart = new CanvasJS.Chart("chart2", {
animationEnabled: true,
zoomEnabled: true,
theme: "light2",
axisX: {
valueFormatString:"##:##:##.###",
crosshair: {
enabled: true,
color: "black",
labelFontColor: "#F8F8F8"
},
},
axisY: {
crosshair: {
enabled: true,
color: "black",
labelFontColor: "#F8F8F8"
},
title: "Serving Cell RSRQ",
minimum: -15,
interval: 2.5
},
data: [{
type: "line",
dataPoints: graphDataContainer[i]
}],
rangeChanged: syncHandler
});
rsrqChart.render();
// var chart3 = new CanvasJS.Chart("chartContainer3", {
// animationEnabled: true,
// theme: "light2",
// data: [{
// type: "line",
// dataPoints: sinrPoints
// }]
// });
// chart3.render();
var charts = [chart1, rsrqChart];
function syncHandler(e){
for (var i = 0; i < charts.length; i++) {
var chart = charts[i];
if (!chart.options.axisX)
chart.options.axisX = {};
if (!chart.options.axisY)
chart.options.axisY = {};
if (e.trigger === "reset") {
chart.options.axisX.viewportMinimum = chart.options.axisX.viewportMaximum = null;
chart.options.axisY.viewportMinimum = chart.options.axisY.viewportMaximum = null;
chart.render();
} else if (chart !== e.chart) {
chart.options.axisX.viewportMinimum = e.axisX[0].viewportMinimum;
chart.options.axisX.viewportMaximum = e.axisX[0].viewportMaximum;
chart.options.axisY.viewportMinimum = e.axisY[0].viewportMinimum;
chart.options.axisY.viewportMaximum = e.axisY[0].viewportMaximum;
chart.render();
}
}
}
}
</script>
<script type = "module" src = "${jsSRC}"></script>
<div id="chart1" style="height: 370px; width: 100%;"></div>
<div id="chart2" style="height: 370px; width: 100%;"></div>
<div id="vis"></div>
<!-- <div id="chartContainer3" style="height: 370px; width: 100%;"></div> -->
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"> </script>
</body>
</html>
`;
}

uplot freezing, when zooming, using svelte, nodered and uibuilder

uplot is used to dislay timeseries data from VictoriaMetrics database.
For the backend Node-Red is used to forward and recieve the query with node-red-contrib-uibuilder.
It works basically and is very fast.
The problem is, when I try to zoom into the uplot graph, my browser (Chrome, Firefox, Edge) freezes. It seems to run out of memory.
Here are parts of my code, using svelte.
<script>
import { onMount } from "svelte";
import { query } from "../lib/uibStore";
import { transformToUplot } from "../lib/helper";
// import uPlot from "uplot";
import Browsebar from "../components/Browsebar.svelte";
import TimerangeSelect from "../components/TimerangeSelect.svelte";
let uplotdiv; //
let opts = {
title: "Temperaturen1",
id: "chart1",
class: "my-chart",
width: 1000,
height: 600,
series: [
{},
{
show: true, // initial toggled state (optional)
spanGaps: true,
label: "RT",
stroke: "red", // series style
scale: "Temperature",
value: (self, rawValue) => rawValue.toFixed(1) + "°C",
},
{
show: true,
spanGaps: true,
label: "KT",
stroke: "green",
scale: "Temperature",
value: (self, rawValue) => rawValue.toFixed(1) + "°C",
},
{
show: true,
spanGaps: true,
label: "VT",
stroke: "blue",
scale: "Temperature",
value: (self, rawValue) => rawValue.toFixed(1) + "°C",
},
],
scales: {
x: { time: true },
Temperature: {
auto: true,
// range: [-10, 20],
side: 3,
},
},
axes: [
{},
{
scale: "Temperature",
values: (self, ticks) => ticks.map((rawValue) => rawValue.toFixed(1) + "°C"),
},
],
cursor: { drag: { x: true, y: true } },
};
let plot; // = new uPlot(opts);
let uPlot;
let d = [[0], [0], [0], [0]];
let resolved = false;
$: uisend($query); //use uibilder.send, if query changes which occurs when timerange or nav index changes
//send a victoriametrics query to the backend, _q is part of query
function uisend(_q) {
// Example 'uvr_prozess_celsius{ort="1"}&start=-3d&step=60s'
uibuilder.send({ topic: "getVMetrics", payload: _q });
}
onMount(async () => {
uisend($query);
const uplotModule = await import("https://unpkg.com/uplot#1.6.22/dist/uPlot.esm.js");
uPlot = uplotModule.default;
plot = new uPlot(opts, [[0], [0], [0], [0]], uplotdiv);
});
uibuilder.onChange("msg", function (msg) {
// load Metrics via Node-Red's uibuilder, serverside
if (msg.topic === "getVMetrics") {
resolved = true;
if (msg.payload.data.result.length > 0) {
d = transformToUplot(msg.payload.data);
plot.setData(d);
}
}
});
</script>
<svelte:head>
<link rel="stylesheet" href="https://unpkg.com/uplot#1.6.22/dist/uPlot.min.css" />
</svelte:head>
<Browsebar>
<TimerangeSelect />
</Browsebar>
<hr />
<div bind:this={uplotdiv} />
{#if resolved}
<code>{$query}</code>
{:else}
<h4>lade Metriken... {$query}</h4>
{/if}
<hr />
Has anyone experienced freezing with uplot? What did you do?
Lucky me, I found the problem. It had to do with the way I transformed the victoriametrics data. On every timestamp I did Number(timestamp).toFixed(0). Without toFixed(0) it is working now. :)
//transform raw data from metrics query to the uplot format
export function transformToUplot(dt) {
let udata = []; //2d data array, conforming uPlot
let tsd = []; //timestamp array
//from first result take only the timestamps
for (let t of dt.result[0].values) {
// tsd.push(Number(t[0]).toFixed(0)); //this was bad!!!!, it lead to freezing
tsd.push(Number(t[0]));
}
udata.push(tsd);
//then the values
for (let r of dt.result) {
let sd = [];
for (let d of r.values) {
let val = Number(d[1]);
sd.push(val);
}
udata.push(sd);
}
return udata;
}
Thanks for your interest!

How can I show extra data in chart.js tooltip?

I'm trying to show weight_id retrieved from mysql data in a chart.js tooltip (shown as (weight_ids[index]) in the image). And later, I intend to show a modal instead of a tooltip to let users update or delete that data. I presume I cannot achieve that without linking the linechart's point data with id stored in mysql. How can I incorporate this id data?
I would appreciate any help very much.
enter image description here
My code is as follows:
<canvas id="myChart"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.9.4/dist/Chart.min.js"></script>
{{-- グラフを描画--}}
<script>
//ラベル
const labels = #json($date_labels);
// id
const weight_ids = #json($weight_ids);
//体重ログ
const weight_logs = #json($weight_logs);
const aryMax = function(a, b) {
return Math.max(a, b);
};
const aryMin = function(a, b) {
return Math.min(a, b);
};
let min_label = Math.floor((weight_logs).reduce(aryMin) - 0.5);
let max_label = Math.ceil((weight_logs).reduce(aryMax) + 0.5);
console.log(weight_ids);
console.log(weight_logs);
console.log(min_label, max_label);
//グラフを描画
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data : {
labels: labels, // x軸ラベル
datasets: [
{
label: `Weight (weight_ids[index])`,
data: weight_logs,
tension: 0,
borderColor: "rgba(37,78,255,1)",
backgroundColor: "rgba(0,0,0,0)",
pointRadius: 3
}
]
},
options: {
title: {
display: false,
text: ''
},
legend: {
display: false,
},
scales: {
yAxes: [
{
ticks: {
min: min_label, // ラベル最小値
max: max_label, // ラベル最大値
},
scaleLabel: {
display: true,
fontSize: 16,
labelString: '体重 (kg)'
}
}
],
},
hover: {
mode: 'point'
},
onClick: function clickHandler(evt) {
var firstPoint = myChart.getElementAtEvent(evt)[0];
if (firstPoint) {
var label = myChart.data.labels[firstPoint._index];
var value = myChart.data.datasets[firstPoint._datasetIndex].data[firstPoint._index];
console.log(label);
console.log(value);
if (value) {
$('#weidhtModal').modal('show');
}
}
}
}
});
</script>
Thank you!
I found a way to retrieve weight_id using the following function.
onClick: function clickHandler(evt, activeElements) {
if (activeElements.length) {
var element = this.getElementAtEvent(evt);
var index = element[0]._index;
var _datasetIndex = element[0]._datasetIndex;
var weightId = weight_ids[index];
var weightLog = weight_logs[index];
console.log(index);
console.log(weightId);
console.log(this.data.labels[index]);
console.log(weightLog);
}
}

Click on chartjs pie slice to hide the slice

I'm trying to get chartjs to hide pie slices on click; the same behavior seen when clicking on the legend.
Here is the code I'm using - I commented out the code that actually removes the data from the chart since it doesn't re-render the pie chart correctly.
const values = [50, 55, 60, 33];
const data = {
labels: ["India", "China", "US", "Canada"],
datasets: [{
data: values,
backgroundColor: [
"#4b77a9",
"#5f255f",
"#d21243",
"#B27200"
],
borderColor: "#fff"
}]
};
const options = {
tooltips: {
enabled: false
},
legend: {
enabled: true,
position: 'bottom'
},
animation: false,
onClick: handleClick,
plugins: {
datalabels: {
formatter: (value = 0, ctxx) => {
const sum = values.reduce((acc, val = 0) => (acc + val), 0);
return `${(value * 100 / sum).toFixed(2)}%`;
},
color: '#fff',
}
}
};
const ctx = document.getElementById("pie-chart").getContext('2d');
const myChart = new Chart(ctx, {
type: 'pie',
data,
options: options
});
function handleClick(e, slice) {
setTimeout(() => {
const legend = myChart.legend.legendItems;
if (slice && slice[0]) {
// get clicked on slice index
const sliceIndex = slice[0]._index;
// Removing the data "really" messes up the chart
// myChart.data.labels.splice(sliceIndex, 1);
// myChart.data.datasets[0].data.splice(sliceIndex, 1);
legend[sliceIndex].hidden = true;
chart.update();
}
const visibleSlices = legend.filter(l => !l.hidden);
console.log('visible slices', visibleSlices);
});
}
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels#0.4.0/dist/chartjs-plugin-datalabels.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="pie-chart"></canvas>
It seems like setting the hidden flag then updating the chart should work because that's what the plugin is doing: https://github.com/chartjs/Chart.js/blob/master/src/plugins/plugin.legend.js#L20-L30.
The code below is hiding a slice by the index
myChart.getDatasetMeta(0).data[sliceIndex].hidden = true
const values = [50, 55, 60, 33];
const data = {
labels: ["India", "China", "US", "Canada"],
datasets: [{
data: values,
backgroundColor: [
"#4b77a9",
"#5f255f",
"#d21243",
"#B27200"
],
borderColor: "#fff"
}]
};
const options = {
tooltips: {
enabled: false
},
legend: {
enabled: true,
position: 'bottom'
},
animation: false,
onClick: handleClick,
plugins: {
datalabels: {
formatter: (value = 0, ctxx) => {
const sum = values.reduce((acc, val = 0) => (acc + val), 0);
return `${(value * 100 / sum).toFixed(2)}%`;
},
color: '#fff',
}
}
};
const ctx = document.getElementById("pie-chart").getContext('2d');
const myChart = new Chart(ctx, {
type: 'pie',
data,
options: options
});
function handleClick(e, slice) {
setTimeout(() => {
const legend = myChart.legend.legendItems;
if (slice && slice[0]) {
const sliceIndex = slice[0]._index;
myChart.getDatasetMeta(0).data[sliceIndex].hidden = true
myChart.update();
}
});
}
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels#0.4.0/dist/chartjs-plugin-datalabels.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="pie-chart"></canvas>

Categories

Resources