I'm playing with this code:
https://jsfiddle.net/netquik/e3jp2k5o/37/
First created a plugin to hightlight Labels (ticks) on x axis when hovering on chart bars (used mousemove for now). Then i tried trigger externally setActiveElements for chart and tooltip. And it seems to work as intended.
expected result
My problem is i can't find a way to "update" datalabels at the same time so it can show me datalabels. In the code you can see i tried manually enable some $context property of $datalabels with no luck. After setActiveElements externally i see in debugging that datalabels trigger itself after chart update and try
display: function (context) {
return context.active; // display labels if active
},
but even if the element in chart is "active" ti return a false context.active.
Could be a problem of interaction modes? Thanks for your help.
trigger result without datalabel
var SCRIPTOBJ = null;
var LABEL = ["Gino", "Samantha", "Vercingetorige"];
var DATA = [5, 28, 500];
var MAX = Math.max(...DATA);
var ctx = $('#stat');
Chart.defaults.font.size = 14;
Chart.register(ChartDataLabels);
var lastLabelH = null;
var stat = new Chart(ctx, {
type: 'bar',
data: {
labels: LABEL,
datasets: [{
minBarLength: 15,
barPercentage: 1,
label: '# VOTES',
data: DATA,
backgroundColor: [
'rgba(255, 99, 132, 0.5)',
'rgba(54, 162, 235, 0.5)',
'rgba(255, 206, 86, 0.5)',
'rgba(75, 192, 192, 0.5)',
'rgba(153, 102, 255, 0.5)',
'rgba(255, 159, 64, 0.5)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
hoverBackgroundColor: [
'rgba(255, 99, 132, 1.0)',
'rgba(54, 162, 235, 1.0)',
'rgba(255, 206, 86, 1.0)',
'rgba(75, 192, 192, 1.0)',
'rgba(153, 102, 255, 1.0)',
'rgba(255, 159, 64, 1.0)'
],
borderWidth: 1
}]
},
plugins: [{
id: 'LabelHighlight',
beforeEvent(c, args, pluginOptions) {
const event = args.event;
if (event.type === 'mouseout') {
if (lastLabelH != null) {
//c.scales.x._labelItems[lastLabelH].color = "rgba(255, 159, 64, 1)";
c.update();
lastLabelH = null;
}
} else if (event.type === 'mousemove') {
if (c._active.length > 0) {
let labelindex = c._active[0].index;
if (c.scales.x._labelItems) {
let label = c.scales.x._labelItems[labelindex];
label.color = "rgba(255, 255, 64, 1)";
}
if (lastLabelH != null && lastLabelH != labelindex) {
if (c.scales.x._labelItems) {
c.scales.x._labelItems[lastLabelH].color = "rgba(255, 159, 64, 1)";
}
}
lastLabelH = labelindex;
} else {
if (lastLabelH != null) {
if (c.scales.x._labelItems) {
c.scales.x._labelItems[lastLabelH].color = "rgba(255, 159, 64, 1)";
}
lastLabelH = null;
}
}
}
}
}],
options: {
responsive: false,
interaction: {
mode: 'index',
intersect: true
},
/* onHover: function (event, elements, c) {
if (elements && elements.length) {
if (c._active.length > 0) {
let labelindex = c._active[0].index;
let label = c.scales.x._labelItems[labelindex];
label.color = "rgba(255, 255, 64, 1)";
lastLabelH = labelindex;
}
} else {
if (lastLabelH != null) {
c.scales.x._labelItems[lastLabelH].color = "rgba(255, 159, 64, 1)";
lastLabelH = null;
}
}
}, */
layout: {
padding: {
top: 50,
left: 0,
right: 0,
bottom: 0
}
},
indexAxis: 'x',
scales: {
x: {
beginAtZero: true,
ticks: {
display: true,
color: 'rgba(255, 159, 64, 1)',
autoSkip: false,
maxRotation: 90,
minRotation: 90,
labelOffset: -8,
textStrokeColor: 'rgba(0, 0, 0, 0.5)',
textStrokeWidth: '2',
font: {
weight: 'bold',
family: 'Arial',
size: 16
},
align: 'start'
}
},
y: {
max: MAX + 1,
beginAtZero: true,
ticks: {
color: 'rgba(255, 159, 64, 1)',
stepSize: 1
}
}
},
plugins: {
legend: {
display: false
},
datalabels: {
listeners: {
enter: function(context) {
// Receives `enter` events for any labels of any dataset. Indices of the
// clicked label are: `context.datasetIndex` and `context.dataIndex`.
// For example, we can modify keep track of the hovered state and
// return `true` to update the label and re-render the chart.
context.hovered = true;
return true;
},
leave: function(context) {
// Receives `leave` events for any labels of any dataset.
context.hovered = false;
return true;
}
},
display: function(context) {
return context.active; // display labels with an odd index
},
font: {
size: '24px'
},
padding: '6',
align: 'end',
anchor: 'end',
borderRadius: 4,
backgroundColor: function(context) {
return context.active ? context.dataset.hoverBackgroundColor : context.dataset.backgroundColor;
},
borderColor: function(context) {
return context.dataset.borderColor;
},
borderWidth: 1,
color: 'rgb(253, 225, 186)',
textShadowBlur: 4,
textShadowColor: 'rgb(0, 0, 0)',
formatter: Math.round
}
}
}
});
if (stat) {
console.log(stat);
$('#activate').click(function() {
if (stat.getActiveElements().length > 0) {
stat.setActiveElements([]);
} else {
stat.setActiveElements([{
datasetIndex: 0,
index: 2,
}]);
//stat.$datalabels._hovered = true;
stat.$datalabels._datasets[0][1]._el.$context.active = true;
stat.$datalabels._datasets[0][1].$context.active = true;
stat.$datalabels._labels[1].$context.active = true;
stat.$datalabels._labels[1]._el.active = true;
stat.$datalabels._labels[1]._el.$context.active = true;
stat.$datalabels._datasets[0][1].update(stat.$datalabels._datasets[0][1].$context);
stat.$datalabels._labels[1].update(stat.$datalabels._labels[1].$context);
}
const tooltip = stat.tooltip;
if (tooltip.getActiveElements().length > 0) {
tooltip.setActiveElements([], {
x: 0,
y: 0
});
} else {
const chartArea = stat.chartArea;
tooltip.setActiveElements([{
datasetIndex: 0,
index: 2,
}], {
x: (chartArea.left + chartArea.right) / 2,
y: (chartArea.top + chartArea.bottom) / 2,
});
}
stat.update();
});
}
Found a solution
I just modified the display function for datalabels integrating my external variable lastLabelH
var SCRIPTOBJ = null;
var LABEL = ["Gino", "Samantha", "Vercingetorige"];
var DATA = [5, 28, 500];
var MAX = Math.max(...DATA);
var ctx = $('#stat');
Chart.defaults.font.size = 14;
Chart.register(ChartDataLabels);
var lastLabelH = null;
var stat = new Chart(ctx, {
type: 'bar',
data: {
labels: LABEL,
datasets: [{
minBarLength: 15,
barPercentage: 1,
label: '# USERS',
data: DATA,
backgroundColor: [
'rgba(255, 99, 132, 0.5)',
'rgba(54, 162, 235, 0.5)',
'rgba(255, 206, 86, 0.5)',
'rgba(75, 192, 192, 0.5)',
'rgba(153, 102, 255, 0.5)',
'rgba(255, 159, 64, 0.5)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
hoverBackgroundColor: [
'rgba(255, 99, 132, 1.0)',
'rgba(54, 162, 235, 1.0)',
'rgba(255, 206, 86, 1.0)',
'rgba(75, 192, 192, 1.0)',
'rgba(153, 102, 255, 1.0)',
'rgba(255, 159, 64, 1.0)'
],
borderWidth: 1
}]
},
plugins: [{
id: 'LabelHighlight',
beforeEvent(c, args, pluginOptions) {
const event = args.event;
/* if (event.type === 'mouseout') {
if (lastLabelH != null) {
//c.scales.x._labelItems[lastLabelH].color = "rgba(255, 159, 64, 1)";
c.update();
lastLabelH = null;
}
} else */
labelcolor(c);
}
}],
options: {
responsive: false,
interaction: {
mode: 'index',
intersect: true
},
/* onHover: function (event, elements, c) {
if (elements && elements.length) {
if (c._active.length > 0) {
let labelindex = c._active[0].index;
let label = c.scales.x._labelItems[labelindex];
label.color = "rgba(255, 255, 64, 1)";
lastLabelH = labelindex;
}
} else {
if (lastLabelH != null) {
c.scales.x._labelItems[lastLabelH].color = "rgba(255, 159, 64, 1)";
lastLabelH = null;
}
}
}, */
layout: {
padding: {
top: 50,
left: 0,
right: 0,
bottom: 0
}
},
indexAxis: 'x',
scales: {
x: {
beginAtZero: true,
ticks: {
display: true,
color: function(c) {
return lastLabelH != null && c.index == lastLabelH ? "rgba(255, 255, 64, 1)" : "rgba(255, 159, 64, 1)";
},
autoSkip: false,
maxRotation: 90,
minRotation: 90,
labelOffset: -8,
textStrokeColor: 'rgba(0, 0, 0, 0.5)',
textStrokeWidth: '2',
font: {
weight: 'bold',
family: 'Arial',
size: 16
},
align: 'start'
}
},
y: {
max: MAX + 1,
beginAtZero: true,
ticks: {
color: 'rgba(255, 159, 64, 1)',
stepSize: 1
}
}
},
plugins: {
legend: {
display: false
},
datalabels: {
listeners: {
enter: function(context) {
// Receives `enter` events for any labels of any dataset. Indices of the
// clicked label are: `context.datasetIndex` and `context.dataIndex`.
// For example, we can modify keep track of the hovered state and
// return `true` to update the label and re-render the chart.
context.hovered = true;
return true;
},
leave: function(context) {
// Receives `leave` events for any labels of any dataset.
context.hovered = false;
return true;
}
},
display: function(context) {
return lastLabelH != null && context.dataIndex == lastLabelH || context.active;
},
font: {
size: '24px'
},
padding: '6',
align: 'end',
anchor: 'end',
borderRadius: 4,
backgroundColor: function(context) {
return context.active ? context.dataset.hoverBackgroundColor : context.dataset.backgroundColor;
},
borderColor: function(context) {
return context.dataset.borderColor;
},
borderWidth: 1,
color: 'rgb(253, 225, 186)',
textShadowBlur: 4,
textShadowColor: 'rgb(0, 0, 0)',
formatter: Math.round
}
}
}
});
function labelcolor(c) {
if (c._active.length > 0) {
let labelindex = c._active[0].index;
if (c.scales.x._labelItems) {
let label = c.scales.x._labelItems[labelindex];
label.color = "rgba(255, 255, 64, 1)";
}
if (lastLabelH != null && lastLabelH != labelindex) {
if (c.scales.x._labelItems) {
c.scales.x._labelItems[lastLabelH].color = "rgba(255, 159, 64, 1)";
}
}
lastLabelH = labelindex;
} else {
if (lastLabelH != null) {
if (c.scales.x._labelItems) {
c.scales.x._labelItems[lastLabelH].color = "rgba(255, 159, 64, 1)";
}
lastLabelH = null;
c.update();
}
}
}
if (stat) {
$('#activate').click(function() {
if (stat.getActiveElements().length > 0) {
stat.setActiveElements([]);
} else {
stat.setActiveElements([{
datasetIndex: 0,
index: 2,
}]);
labelcolor(stat);
}
const tooltip = stat.tooltip;
if (tooltip.getActiveElements().length > 0) {
tooltip.setActiveElements([], {
x: 0,
y: 0
});
} else {
const chartArea = stat.chartArea;
tooltip.setActiveElements([{
datasetIndex: 0,
index: 2,
}], {
x: (chartArea.left + chartArea.right) / 2,
y: (chartArea.top + chartArea.bottom) / 2,
});
}
stat.update();
});
}
body {
background-color: grey;
}
#stat {
margin-top: auto;
}
#content {
width: 300px;
margin: auto;
}
;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.0/chart.min.js"></script>
<div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.0.0/chartjs-plugin-datalabels.min.js"></script>
<div id="content">
<canvas id="stat" width="300" height="300" style="margin-top:10px"></canvas>
<input id="activate" type="button" value="Vergingetorige">
</div>
</div>
had to modify the color fuction to update when set null lastLabelH i also add color label from external trigger
updated jsfiddle
https://jsfiddle.net/netquik/e3jp2k5o/41/
Related
I'm trying to add a space between the actual Chart and the Legend/labels.
Legend has a position rigtht and I don't know how to add a padding/margin between Chart and labels.
Found some discussions but not relevant to react hooks.
From what I understood, I need to make use of beforeinit built in function.
Here is the code snippet and sandbox link.
import React from "react";
import { Chart as ChartJS, ArcElement, Tooltip, Legend } from "chart.js";
import { Doughnut } from "react-chartjs-2";
ChartJS.register(ArcElement, Tooltip, Legend);
export const data = {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [
{
label: "# of Votes",
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
"rgba(255, 99, 132, 0.2)",
"rgba(54, 162, 235, 0.2)",
"rgba(255, 206, 86, 0.2)",
"rgba(75, 192, 192, 0.2)",
"rgba(153, 102, 255, 0.2)",
"rgba(255, 159, 64, 0.2)"
],
borderColor: [
"rgba(255, 99, 132, 1)",
"rgba(54, 162, 235, 1)",
"rgba(255, 206, 86, 1)",
"rgba(75, 192, 192, 1)",
"rgba(153, 102, 255, 1)",
"rgba(255, 159, 64, 1)"
],
borderWidth: 1
}
]
};
export function App() {
return (
<div style={{ width: "300px", height: "300px" }}>
<Doughnut
options={{
maintainAspectRatio: true,
plugins: {
legend: {
position: "right",
rtl: true,
labels: {
usePointStyle: true,
pointStyle: "circle",
padding: 20
}
}
}
}}
data={data}
/>
</div>
);
}
Any help will be appreciated
You can't add space but increase the width of the legend using the beforeInit plugin (codesandbox). Increasing the width adds some space but it decreases the overall width available to the chart, so you might have to tweak that a little -
const plugin = {
beforeInit(chart) {
console.log("be");
// reference of original fit function
const originalFit = chart.legend.fit;
// override the fit function
chart.legend.fit = function fit() {
// call original function and bind scope in order to use `this` correctly inside it
originalFit.bind(chart.legend)();
// increase the width to add more space
this.width += 20;
};
}
};
<Doughnut
plugins={[plugin]}
...
Is there any way to add an image into chart area [I'm using chart JS bubble chart].
Presently I added image to canvas through css.
Best approach, drawing it on the canvas
The best way to achieve this is by drawing it directly on the canvas since you have direct access and control over the pixels so you are sure it is aligned pixel perfect.
Extending on uminders answer, but making it so it only draws within the chart area:
const myChart = new Chart('myChart', {
type: 'bubble',
plugins: [{
beforeDraw: chart => {
var ctx = chart.ctx;
ctx.save();
const image = new Image();
image.src = 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/Stack_Overflow_logo.svg/2560px-Stack_Overflow_logo.svg.png';
ctx.drawImage(image, chart.chartArea.left, chart.chartArea.top, chart.chartArea.width, chart.chartArea.height);
ctx.restore();
}
}],
data: {
datasets: [{
label: 'My Dataset',
data: [{
x: 0,
y: 12,
r: 10
},
{
x: 1,
y: 19,
r: 12
},
{
x: 2,
y: 3,
r: 8
},
{
x: 3,
y: 5,
r: 7
},
{
x: 4,
y: 2,
r: 4
},
{
x: 5,
y: 3,
r: 8
}
],
backgroundColor: [
'rgba(255, 99, 132, 0.4)',
'rgba(54, 162, 235, 0.4)',
'rgba(255, 206, 86, 0.4)',
'rgba(75, 192, 192, 0.4)',
'rgba(153, 102, 255, 0.4)',
'rgba(255, 159, 64, 0.4)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
]
}]
},
options: {
responsive: true,
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.js"></script>
<canvas id="myChart" height="80"></canvas>
Alternative approach without drawing on the canvas
If you really don't want to draw it on the canvas but use a normal img element, you can use an absolute position and use a custom plugin to position it correctly, downside is that it seems that canvas pixels are different from CSS so they cant be used 1:1 and have to be approximated which may lead to slight alignment issues:
const myChart = new Chart('myChart', {
type: 'bubble',
plugins: [{
beforeDraw: chart => {
const image = document.getElementById('img')
image.width = chart.chartArea.width;
image.height = chart.chartArea.height;
image.style.left = `${chart.chartArea.left*1.3}px`;
image.style.top = `${chart.chartArea.top*1.3}px`;
}
}],
data: {
datasets: [{
label: 'My Dataset',
data: [{
x: 0,
y: 12,
r: 10
},
{
x: 1,
y: 19,
r: 12
},
{
x: 2,
y: 3,
r: 8
},
{
x: 3,
y: 5,
r: 7
},
{
x: 4,
y: 2,
r: 4
},
{
x: 5,
y: 3,
r: 8
}
],
backgroundColor: [
'rgba(255, 99, 132, 0.4)',
'rgba(54, 162, 235, 0.4)',
'rgba(255, 206, 86, 0.4)',
'rgba(75, 192, 192, 0.4)',
'rgba(153, 102, 255, 0.4)',
'rgba(255, 159, 64, 0.4)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
]
}]
},
options: {
responsive: true,
}
});
#img {
position: absolute;
z-index: -1/* Draw image behind the canvas */
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.js"></script>
<img id="img" src="https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/Stack_Overflow_logo.svg/2560px-Stack_Overflow_logo.svg.png" />
<canvas id="myChart" height="80"></canvas>
The Plugin Core API offers a range of hooks that can be used for performing custom code. You can use the beforeDraw for example to draw the images through CanvasRenderingContext2D.drawImage(). But this effectively draws the image directly on the canvas.
plugins: [{
beforeDraw: chart => {
var ctx = chart.chart.ctx;
ctx.save();
var image = new Image();
image.src = 'https://i.stack.imgur.com/S7tJH.png';
imageSize = 250;
ctx.drawImage(image, chart.chart.width / 2 - imageSize / 2, chart.chart.height / 2 - imageSize / 2, imageSize, imageSize);
ctx.restore();
}
}],
Please have a look at the runnable code snippet below.
var myChart = new Chart('myChart', {
type: 'bubble',
plugins: [{
beforeDraw: chart => {
var ctx = chart.chart.ctx;
ctx.save();
var image = new Image();
image.src = 'https://i.stack.imgur.com/S7tJH.png';
imageSize = 250;
ctx.drawImage(image, chart.chart.width / 2 - imageSize / 2, chart.chart.height / 2 - imageSize / 2, imageSize, imageSize);
ctx.restore();
}
}],
data: {
datasets: [{
label: 'My Dataset',
data: [
{ x: "05:22", y: 12, r: 10 },
{ x: "12:13", y: 19, r: 12 },
{ x: "13:45", y: 3, r: 8 },
{ x: "18:31", y: 5, r: 7 },
{ x: "19:05", y: 2, r: 4 },
{ x: "22:55", y: 3, r: 8 }
],
backgroundColor: [
'rgba(255, 99, 132, 0.4)',
'rgba(54, 162, 235, 0.4)',
'rgba(255, 206, 86, 0.4)',
'rgba(75, 192, 192, 0.4)',
'rgba(153, 102, 255, 0.4)',
'rgba(255, 159, 64, 0.4)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
]
}]
},
options: {
responsive: true,
legend: {
display: false
},
scales: {
xAxes: [{
type: 'time',
time: {
parser: 'HH:mm',
unit: 'hour',
stepSize: 1,
displayFormats: {
hour: 'HH:mm'
},
tooltipFormat: 'HH:mm'
},
ticks: {
min: '00:00',
max: '24:00',
callback: (value, index) => index == 24 ? '24:00' : value
}
}],
yAxes: [{
ticks: {
beginAtZero: true,
stepSize: 5
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<canvas id="myChart" height="80"></canvas>
I have an issue when displaying a chart. I have a function that load data by default for today. After that, I can select a date range. But there is an issue when hovering on labels. They load old chart values and lines. I know that I need to use destroy or update function. But I don't know how to implement it in my code.
Script:
<script type="text/javascript">
$(document).ready(function() {
getdata_chart();
{{-- chartjs --}}
function getdata_chart(start_date='', end_date='')
{
$.ajax({
url: "{{ route('ajaxdata.getdata_chart') }}",
method: "GET",
data:{
start_date:start_date, end_date:end_date
},
success: function(data) {
console.log(data);
var timeFormat = 'DD MMM YYYY г. kk:mm:ss ч.';
var progress = document.getElementById('animationProgress');
var dateANDtime = [];
var Gblok9osx = [];
var Gblok9osy = [];
var Gblok11osx = [];
var Gblok11osy = [];
var Gfilblok10 = [];
var Gfilblok11 = [];
var Gcvn = [];
var Gndk = [];
var Gndk2 = [];
for (var i in data) {
dateANDtime.push(data[i].timestamp);
Gblok9osx.push(data[i].blok9osx);
Gblok9osy.push(data[i].blok9osy);
Gblok11osx.push(data[i].blok11osx);
Gblok11osy.push(data[i].blok11osy);
Gfilblok10.push(data[i].filblok10);
Gfilblok11.push(data[i].filblok11);
Gcvn.push(data[i].cvn);
Gndk.push(data[i].ndk);
Gndk2.push(data[i].ndk2);
}
var chartdata = {
labels: dateANDtime,
datasets: [{
fill: false,
label: 'Отвес блок 9 x',
backgroundColor: 'rgba(199, 228, 238, 0.75)',
borderColor: 'rgba(1, 150, 200, 0.75)',
//hoverBackgroundColor: 'rgba(200, 200, 200, 0.75)',
hoverBorderColor: 'rgba(200, 200, 200, 1)',
data: Gblok9osx,
hidden: false
},
{
fill: false,
label: 'Отвес блок 9 y',
backgroundColor: 'rgba(163, 147, 222, 0.75)',
borderColor: 'rgba(50, 10, 200, 0.75)',
//hoverBackgroundColor: 'rgba(200, 200, 200, 1)',
hoverBorderColor: 'rgba(200, 200, 200, 1)',
data: Gblok9osy,
hidden: true
},
{
fill: false,
label: 'Отвес блок 11 x',
backgroundColor: 'rgba(221, 221, 241, 0.75)',
borderColor: 'rgba(100, 100, 200, 0.75)',
//hoverBackgroundColor: 'rgba(200, 200, 200, 1)',
hoverBorderColor: 'rgba(200, 200, 200, 1)',
data: Gblok11osx,
hidden: true
},
{
fill: false,
label: 'Отвес блок 11 y',
backgroundColor: 'rgba(147, 227, 227, 0.75)',
borderColor: 'rgba(1, 200, 200, 0.75)',
//hoverBackgroundColor: 'rgba(200, 200, 200, 1)',
hoverBorderColor: 'rgba(200, 200, 200, 1)',
data: Gblok11osy,
hidden: true
},
{
fill: false,
label: 'Филтрация блок 10',
backgroundColor: 'rgba(139, 105, 132, 0.75)',
borderColor: 'rgba(255, 1, 200, 0.75)',
//hoverBackgroundColor: 'rgba(200, 200, 200, 1)',
hoverBorderColor: 'rgba(200, 200, 200, 1)',
data: Gfilblok10,
hidden: true
},
{
fill: false,
label: 'Филтрация блок 11',
backgroundColor: 'rgba(0, 200, 1, 1)',
borderColor: 'rgba(0, 101,1, 0.75)',
hoverBackgroundColor: 'rgba(200, 200, 200, 1)',
hoverBorderColor: 'rgba(50, 50, 50, 1)',
data: Gfilblok11,
hidden: true
},
{
fill: false,
label: 'КВН',
backgroundColor: 'rgba(30, 100, 100, 1)',
borderColor: 'rgba(100, 200,1, 0.75)',
hoverBackgroundColor: 'rgba(101, 200, 200, 1)',
hoverBorderColor: 'rgba(50, 50, 50, 1)',
data: Gcvn,
hidden: true
},
{
fill: false,
label: 'КДК',
backgroundColor: 'rgba(30, 100, 100, 1)',
borderColor: 'rgba(100, 200,1, 0.75)',
hoverBackgroundColor: 'rgba(101, 200, 200, 1)',
hoverBorderColor: 'rgba(50, 50, 50, 1)',
data: Gndk,
hidden: true
},
{
fill: false,
label: 'НДК',
backgroundColor: 'rgba(30, 100, 100, 1)',
borderColor: 'rgba(100, 200,1, 0.75)',
hoverBackgroundColor: 'rgba(101, 200, 200, 1)',
hoverBorderColor: 'rgba(50, 50, 50, 1)',
data: Gndk2,
hidden: true
}
]
};
$('#reset_zoom').click(function() {
barGraph.resetZoom();
})
$("#save-btn").click(function() {
$("#mycanvas").get(0).toBlob(function(blob) {
saveAs(blob, "chart_1.png");
});
});
var config = {
type: 'line',
data: chartdata,
options: {
responsive: true,
title: {
display: true,
text: 'Диаграма: Отвеси и филтрации'
},
scales: {
yAxes: [{
type: type,
scaleLabel: {
display: true,
labelString: '[ mm ] ,[ m ], [ l/s ]'
},
ticks: {
beginAtZero: false
}
}],
xAxes: [{
type: 'time',
time: {
tooltipFormat: timeFormat,
displayFormats: {
'hour': timeFormat
}
},
scaleLabel: {
display: true,
labelString: 'Дата/Час'
},
ticks: {
beginAtZero: true
}
}]
},
// Container for pan options
pan: {
// Boolean to enable panning
enabled: true,
// Panning directions. Remove the appropriate direction to disable
// Eg. 'y' would only allow panning in the y direction
mode: 'y'
},
// Container for zoom options
zoom: {
// Boolean to enable zooming
enabled: true,
// Zooming directions. Remove the appropriate direction to disable
// Eg. 'y' would only allow zooming in the y direction
mode: 'xy'
},
animation: {
duration: 2000,
onProgress: function(animation) {
progress.value = animation.currentStep / animation.numSteps;
},
onComplete: function() {
window.setTimeout(function() {
progress.value = 0;
}, 2000);
}
},
legend: {
display: true,
labels: {
//fontColor: 'rgb(255, 99, 132)'
usePointStyle: true
}
}
},
plugins: [{
beforeDraw: function(c) {
var reset_zoom = document.getElementById("reset_zoom"); //reset button
var ticks = c.scales['x-axis-0', 'y-axis-0'].ticks.length; //x-axis ticks array
var labels = c.data.labels.length; //labels array
if (ticks < labels) reset_zoom.hidden = false;
else reset_zoom.hidden = true;
}
}]
};
var type = 'linear';
var ctx = document.getElementById("mycanvas");
var barGraph = new Chart(ctx, config);
window.onload = function() {
var ctx = document.getElementById("mycanvas");
window.myLine = barGraph;
};
document.getElementById('toggleScale').addEventListener('click', function() {
type = type === 'linear' ? 'logarithmic' : 'linear';
window.myLine.options.title.text = 'Диаграма('+type+'): Отвеси и филтрации';
window.myLine.options.scales.yAxes[0] = {
display: true,
type: type
};
window.myLine.update();
}); //end data
},
error: function(data) {
console.log(data);
}
});
}
$('#search').click(function(){
var start_date = $('#start_date').val();
var end_date = $('#end_date').val();
if(start_date != '' && end_date != '')
{
getdata_chart(start_date, end_date);
}
else
{
alert('Both Date is required');
}
});
});
</script>
in to the controller:
function getdata_chart(Request $request)
{
$start_date = date('d-m-Y 00:00:00');
$end_date = date('d-m-Y 23:59:59');
if($request->start_date != '' && $request->end_date != '')
{
$dateScope = array($request->start_date ." 00:00:00", $request->end_date ." 23:59:59");
} else {
$dateScope = array($start_date, $end_date);
};
$students = otv_fil::whereBetween('timestamp', $dateScope)
->selectRaw('timestamp,blok9osx,blok9osy,blok11osx,blok11osy,filblok10,filblok11,cvn,ndk,ndk - ? as ndk2',[743.38])
->orderBy('timestamp', 'ASC')
->get();
return response()->json($students);
}
The main part need to be in search click function right?
I want to show a percentage sign in the chart.I take data from my database from controller and show the data from vue js file.Here is my chart code.
<script>
import { Doughnut } from 'vue-chartjs';
export default {
props:['appurl'],
extends: Doughnut,
data(){
return{
item:[],
}
},
mounted() {
this.getData();
},
methods:{
setChartLoader: function(e) {
this.$emit('setChartLoader', e);
},
renderDoughnutChart(serviceName,serviceData){
this.renderChart({
datasets: [{
data: serviceData,
backgroundColor: [
'rgba(41, 121, 255, 1)',
'rgba(38, 198, 218, 1)',
'rgba(138, 178, 248, 1)',
'rgba(255, 100, 200, 1)',
'rgba(116, 96, 238, 1)',
'rgba(215, 119, 74, 1)',
'rgba(173, 92, 210, 1)',
'rgba(255, 159, 64, 1)',
'rgba(247, 247, 247, 1)',
'rgba(227, 247, 227, 1)',
],
}],
// These labels appear in the legend and in the tooltips when hovering different arcs
labels: serviceName,
}, {responsive: true, maintainAspectRatio: false, cutoutPercentage: 80})
},
getData(){
axios.get(this.appurl+'/dashboardgetdatadoughnut').then(response => {
this.item = response.data;
this.setChartLoader(false);
this.renderDoughnutChart(this.item.serviceName,this.item.serviceCount)
}).then(function(){
});
}
},
}
</script>
Here is my controller
public function doughnutData()
{
$serviceNameArray = array();
$serviceConfirmed = DB::table('bookings')->whereDate('booking_date', date('Y-m-d'))
->select('status',DB::raw('round(count(*) *100 / (select count(*) from bookings WHERE booking_date = curdate())) as count'))
->groupBy('status')->get();
$serviceCount = array();
foreach($serviceConfirmed as $name)
{
array_push($serviceNameArray,$name->status);
array_push($serviceCount,$name->count);
}
return ['serviceName'=>$serviceNameArray,
'serviceCount'=>$serviceCount];
}
I want to show 67% in the chart but i can not show the % sign
in the chart options, you can use the tooltips callback to customize the tooltip.
here, the % sign is added to the standard tooltip text...
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
return data['labels'][tooltipItem['index']] + ': ' + data['datasets'][0]['data'][tooltipItem['index']] + '%';
}
}
}
see following working snippet...
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'pie',
data: {
labels: ['confirmed', 'pending'],
datasets: [{
data: [67, 33],
backgroundColor: [
'rgba(41, 121, 255, 1)',
'rgba(38, 198, 218, 1)',
'rgba(138, 178, 248, 1)',
'rgba(255, 100, 200, 1)',
'rgba(116, 96, 238, 1)',
'rgba(215, 119, 74, 1)',
'rgba(173, 92, 210, 1)',
'rgba(255, 159, 64, 1)',
'rgba(247, 247, 247, 1)',
'rgba(227, 247, 227, 1)',
],
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
cutoutPercentage: 80,
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
return data['labels'][tooltipItem['index']] + ': ' + data['datasets'][0]['data'][tooltipItem['index']] + '%';
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script>
<canvas id="myChart"></canvas>
I am developing a django app using the Django Rest Framework with chart.JS in order to render some chart.
My ajax call is taking a long long long time and I am on local..
Is there a way to check what is taking so long in order to know where to look in order to refactor ?
it takes on average on local between 10 and 15 second each time..
Here is my code for example:
<script>
var endpoint = 'api/chart/data2'
$('.ajaxProgress').show();
$('.dashboard-container').hide();
function getAvg(grades) {
return grades.reduce(function (p, c) {
return p + c;
}) / grades.length;
}
$.ajax({
method: "GET",
url: endpoint,
success: function(data){
console.log(data)
complete_data = data.team_complete,
info_data = data.team_info_score,
motiv_data = data.team_motiv_score,
action_data = data.team_action_score,
behaviour_data = data.team_behaviour_score,
user_list = data.users,
user_dist = data.user_dist,
info_dist = data.info_dist,
motiv_dist = data.motiv_dist,
action_dist = data.action_dist,
behav_dist = data.behav_dist,
info_label = data.info_label,
motivation_label = data.motivation_label,
action_label = data.action_label,
behav_label = data.behav_label,
complete_label = data.complete_label,
cohesiveness_score = data.cohesiveness_score
var bar_color = [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)',
'rgba(255, 220, 89, 0.2)',
'rgba(255, 192, 35, 0.2)',
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)',
'rgba(255, 220, 89, 0.2)',
'rgba(255, 192, 35, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(255, 99, 132, 0.2)'
]
var ctx = document.getElementById("mainGraph").getContext('2d');
var ctx2 = document.getElementById("mainGraph2").getContext('2d');
var ctx3 = document.getElementById("mainGraphLine1").getContext('2d');
var ctx4 = document.getElementById("mainGraphLine2").getContext('2d');
var ctx5 = document.getElementById("mainGraphLine3").getContext('2d');
var ctx6 = document.getElementById("mainGraphLine4").getContext('2d');
$('.ajaxProgress').hide();
$('.dashboard-container').show();
var canvas = document.getElementById("mainGraph");
var mainGraph = new Chart(ctx, {
type: 'bar',
data: {
labels: complete_label,
datasets: [{
data: complete_data,
backgroundColor: bar_color ,
}]
},
options: {
legend: {
position: 'top',
display: false
},
responsive:true,
maintainAspectRatio: false,
scales: {
xAxes: [{
ticks: {autoSkip: false}
}]
}
},
});
//end graph 1//
canvas.onclick = function(evt) {
var activePoints = mainGraph.getElementsAtEvent(evt);
if (activePoints[0]) {
var chartData = activePoints[0]['_chart'].config.data;
var idx = activePoints[0]['_index'];
var label = chartData.labels[idx];
var str_label = label.toString()
console.log(str_label)
var value = chartData.datasets[0].data[idx];
if(label == "General,Details"){
$('#general').modal('show');
} else if(label == "Sameness,Difference"){
$('#sameness').modal('show');
} else if(label == "Visual,Auditory"){
$('#visual').modal('show');
} else if(label == "Static,Process"){
$('#static').modal('show');
} else if(label == "Best Scenario,Worst Scenario"){
$('#bestScenario').modal('show');
} else if(label == "Binary,Shades"){
$('#binary').modal('show');
} else if(label == "External,Internal"){
$('#external').modal('show');
} else if(label == "Go Away,Toward"){
$('#goAway').modal('show');
} else if(label == "Things"){
$('#things').modal('show');
} else if(label == "Variety,Routine"){
$('#variety').modal('show');
} else if(label == "Active,Reaction"){
$('#active').modal('show');
} else if(label == "Manager worker"){
$('#manager').modal('show');
} else if(label == "Option,Procedure"){
$('#option').modal('show');
} else if(label == "Perfection,Optimizing"){
$('#perfection').modal('show');
} else if(label == "Sensor,Intuition"){
$('#sensor').modal('show');
} else if(label == "External locus,Internal locus"){
$('#locus').modal('show');
} else if(label == "Strong Will,Compliant"){
$('#will').modal('show');
} else if(label == "In time,Through time"){
$('#time').modal('show');
} else{
$('#modeling').modal('show');
}
}}
;
//graph 2 //
var mainGraph2 = new Chart(ctx2, {
type: 'horizontalBar',
data: {
labels: user_list,
datasets: [{
data: user_dist,
backgroundColor: bar_color ,
}]
},
options: {
legend: {
position: 'top',
display: false
},
responsive:true,
maintainAspectRatio: false,
scales: {
xAxes: [{
ticks: {autoSkip: false,
beginAtZero: true,
min: 0,
max:100,
}
}]
},
annotation: {
annotations: [
{
type: "line",
mode: "vertical",
scaleID: "x-axis-0",
value: getAvg(user_dist),
borderColor: "rgba(216, 138, 138, 1)",
label: {
content: "AVERAGE",
fontFamily:'Ubuntu',
enabled: true,
position: "middle",
fontSize: 10,
backgroundColor: 'rgba(0,0,0,0.5)',
}
}
]
}
},
});
//end graph 2//
//graph 3 //
var mainGraphLine1 = new Chart(ctx3, {
type: 'line',
data: {
labels: info_label,
datasets: [{
data: info_dist,
backgroundColor: 'rgba(102, 187, 158, 0.2)' ,
}]
},
options: {
legend: {
position: 'top',
display: false
},
responsive:true,
maintainAspectRatio: false,
scales: {
xAxes: [{
ticks: {autoSkip: false,
beginAtZero: true,
}
}],
yAxes: [{
ticks: {min: 0, max:100}
}],
},
annotation: {
annotations: [
{
type: "line",
mode: "horizontal",
scaleID: "y-axis-0",
value: getAvg(info_dist),
borderColor: "rgba(216, 138, 138, 1)",
borderWidth: 0.5,
label: {
content: "AVERAGE",
fontFamily:'Ubuntu',
enabled: true,
position: "middle",
fontSize: 8,
backgroundColor: 'rgba(0,0,0,0.5)',
}
}
]
}
},
});
//end graph 3//
//graph 4 //
var mainGraphLine2 = new Chart(ctx4, {
type: 'line',
data: {
labels: motivation_label,
datasets: [{
data: motiv_dist,
backgroundColor: 'rgba(102, 187, 158, 0.2)' ,
}]
},
options: {
legend: {
position: 'top',
display: false
},
responsive:true,
maintainAspectRatio: false,
scales: {
xAxes: [{
ticks: {autoSkip: false,
beginAtZero: true,
}
}],
yAxes: [{
ticks: {min: 0, max:100}
}],
},
annotation: {
annotations: [
{
type: "line",
mode: "horizontal",
scaleID: "y-axis-0",
value: getAvg(motiv_dist),
borderColor: "rgba(216, 138, 138, 1)",
borderWidth: 0.5,
label: {
content: "AVERAGE",
fontFamily:'Ubuntu',
enabled: true,
position: "middle",
fontSize: 8,
backgroundColor: 'rgba(0,0,0,0.5)',
}
}
]
}
},
});
//end graph 4//
//graph 5 //
var mainGraphLine3 = new Chart(ctx5, {
type: 'line',
data: {
labels: action_label,
datasets: [{
data: action_dist,
backgroundColor: 'rgba(102, 187, 158, 0.2)' ,
}]
},
options: {
legend: {
position: 'top',
display: false
},
responsive:true,
maintainAspectRatio: false,
scales: {
xAxes: [{
ticks: {autoSkip: false,
beginAtZero: true,
}
}],
yAxes: [{
ticks: {min: 0, max:100}
}],
},
annotation: {
annotations: [
{
type: "line",
mode: "horizontal",
scaleID: "y-axis-0",
value: getAvg(action_dist),
borderColor: "rgba(216, 138, 138, 1)",
borderWidth: 0.5,
label: {
content: "AVERAGE",
fontFamily:'Ubuntu',
enabled: true,
position: "middle",
fontSize: 8,
backgroundColor: 'rgba(0,0,0,0.5)',
}
}
]
}
},
});
//end graph 5//
//graph 6 //
var mainGraphLine4 = new Chart(ctx6, {
type: 'line',
data: {
labels: behav_label,
datasets: [{
data:behav_dist,
backgroundColor: 'rgba(102, 187, 158, 0.2)',
}]
},
options: {
legend: {
position: 'top',
display: false
},
responsive:true,
maintainAspectRatio: false,
scales: {
xAxes: [{
ticks: {autoSkip: false,
beginAtZero: true,
}
}],
yAxes: [{
ticks: {min: 0, max:100}
}],
},
annotation: {
annotations: [
{
type: "line",
mode: "horizontal",
scaleID: "y-axis-0",
value: getAvg(behav_dist),
borderColor: "rgba(216, 138, 138, 0.8)",
borderWidth: 0.5,
label: {
content: "AVERAGE",
fontFamily:'Ubuntu',
enabled: true,
position: "middle",
fontSize: 8,
backgroundColor: 'rgba(0,0,0,0.5)',
}
}
]
}
},
});
//end graph 6//
}
})
</script>
You can test you django api using postman. You will get the execution time there.
Also if you want to profile your django app you can refer the following link profiling django