Reactivity Chartjs in Svelte - chart.js

I am having trouble with reactivity Chartjs in Svelte. I wish that chart update eminently when the data for energy changes. What is missing in this code ?
<script lang="ts">
import { Line } from "svelte-chartjs";
import { onMount } from "svelte";
let labels = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
let energy =[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let data = {
labels,
datasets: [
{
label: "Dataset",
data: energy,
borderColor: "rgb(255, 99, 132)",
backgroundColor: "rgba(255, 99, 132, 0.5)"
},
]
};
$:labels,energy,data
onMount(() => {
const interval = setInterval(() => {
rendom();
console.log(energy)
}, 1000);
return () => {
clearInterval(1);
};
})
function rendom() {
let index=Math.round(Math.random()*9);
energy[index]=Math.round(Math.random()*100)
}
</script>
<Line data={data}/>
Answers for my problem.

Looking at the Line Chart Example some imports from chart.js and ChartJS.register() seem to be necessary
The Line component from svelte-chartjs exports a reference to the chart on which .update() can be called after changing the data. The reference can be accessed via a local variable and bind:
Notice that clearInterval() takes the reference to the interval (and maybe change rendom to random as in Math.random())
REPL
<script>
import {
Chart as ChartJS,
Title,
Tooltip,
Legend,
LineElement,
LinearScale,
PointElement,
CategoryScale,
} from 'chart.js';
ChartJS.register(
Title,
Tooltip,
Legend,
LineElement,
LinearScale,
PointElement,
CategoryScale
);
import { Line } from "svelte-chartjs";
import { onMount } from "svelte";
let labels = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
let energy =[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let chartRef
let data = {
labels,
datasets: [
{
label: "Dataset",
data: energy,
borderColor: "rgb(255, 99, 132)",
backgroundColor: "rgba(255, 99, 132, 0.5)"
},
]
};
onMount(() => {
const interval = setInterval(() => {
rendom();
}, 1000);
return () => {
clearInterval(interval);
};
})
function rendom() {
let index=Math.round(Math.random()*9);
energy[index]=Math.round(Math.random()*100)
chartRef.update()
}
</script>
<Line bind:chart={chartRef} data={data}/>

Related

ChartJS horizontal bar with numbers on both scales

I have an issue with Chartjs bar chart. It doesn't display numeric values on both axis.
I hope you can give an advice how to resolve the issue.
I have the following data structures when both scaled are numeric:
{"x": 86, "y": 20},
{"x": 255, "y": 21},
{"x": 207, "y": 34},
The y axis is not a category but a number.
Here's how my chart looks like:
As you can see, there are no values on y axis. Y axis is not even show and the chart looks more like a stacked chart.
Here's how configuration looks like:
config: {
type: "bar",
data: {
datasets: [],
},
plugins: [],
options: {
responsive: true,
indexAxis: "y",
elements: {
bar: {
borderWidth: 2,
},
},
},
scales: {
y: {
position: "left",
ticks: {
color: "blue",
font: 24,
},
},
},
},
This is because chart.js still thinks it needs to be a category scale so you will need to override that. If you do that it shows up fine.
A second thing, to make the ticks bigger you need to specify the size in the font object, the font does not accept a number. For all font properties you can specify there you can read the docs here
var options = {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [{
"x": 86,
"y": 20
},
{
"x": 255,
"y": 21
},
{
"x": 207,
"y": 34
}
],
backgroundColor: 'pink'
}]
},
options: {
indexAxis: "y",
scales: {
y: {
type: 'linear',
ticks: {
color: "blue",
font: {
size: 24
},
},
}
}
}
}
var 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.6.0/chart.js"></script>
</body>

How to display stacked line chartjs

I try to display stacked line chart but it doesn't work.
Could you advise where I should change with the following code?
window.onload=function(){
var ctx = document.getElementById("myChart").getContext("2d");
var data = {
labels: {{subcategories|tojson}},
datasets: [
{
1st_sample_dataset
},
{
2nd_sample_dataset
}
]
},
options = {
scales: {
yAxes: [{
stacked: true
}]
}
};
new Chart(ctx).Line(data, {
onAnimationComplete: function () {
var sourceCanvas = this.chart.ctx.canvas;
var targetCtx = document.getElementById("myChartAxis").getContext("2d");
targetCtx.canvas.width = copyWidth;
targetCtx.drawImage(sourceCanvas, 0, 0, copyWidth, copyHeight, 0, 0, copyWidth, copyHeight);
}
});
}
And this is actual display.
From your code I presume you're using an old version of chart.js.
new Chart(ctx).Line(data, {
...
Charts are now created in a different way.
var myChart = new Chart(ctx, {
type: 'line',
...
If you switch to version 2.9.3., it works fine as the following code sample illustrates.
new Chart(document.getElementById('myChartAxis'), {
type: 'line',
data: {
labels: ['A', 'B', 'C', 'D'],
datasets: [
{
label: 'WARNINGS',
data: [1, 2, 3, 2],
borderColor: 'rgb(255, 159, 64)',
backgroundColor: 'rgba(255, 159, 64, 0.2)'
},
{
label: 'ERRORS',
data: [1, 2, 1, 3],
borderColor: 'rgb(255, 99, 132)',
backgroundColor: 'rgba(255, 99, 132, 0.2)'
}
]
},
options: {
scales: {
yAxes: [{
stacked: true
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<canvas id="myChartAxis" height="90"></canvas>

How to create a dynamic chart using ember-vega

Im trying to create a vega chart in an ember octane app but in doing so im able to render the chart once, but from then on, even if the values change, the chart doesn't get rerendered
the code im using is
component.ts
#tracked
model!: any;
get chartData() {
const data = this.model.data;
return {
table: data.map((datum: any) => {
return {
...datum
};
})
};
}
chart.hbs
{{vega-vis spec=this.spec data=this.chartData}}
why isn't it not working, but at the same time
doing set(this,"dataSource",this.model.data) works
dataSource: computed(function() {
return emberArray([
{"category": "A", "amount": 28},
{"category": "B", "amount": 55},
{"category": "C", "amount": 43},
{"category": "D", "amount": 91},
{"category": "E", "amount": 81},
{"category": "F", "amount": 53},
{"category": "G", "amount": 19},
{"category": "H", "amount": 87}
]);
}),
data: computed('dataSource.{[],#each.amount}', function () {
const dataSource = get(this, 'dataSource');
return {
table: dataSource.map((datum) => {
// return a copy because Vega Vis will mutate the dataset.
return {
...datum
};
})
};
})

ChartJS with Dynamic Colors

I saw your post regarding,
Instead of just "Stock" at the left, is there anyway to put a separate label for each bar, eg 18, 82, 22, 80 going down the y-axis?
Below is the link which I'm referring ...
ChartJS bar chart with legend which corresponds to each bar
You are looking for something like the following:
var chart = new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: [18, 82, 22, 80],
datasets: [{
data: [1, 2, 3, 4],
backgroundColor: ['#ff6384', '#36a2eb', '#ffce56', '#4bc0c0', '#9966ff'],
borderColor: ['#ff6384', '#36a2eb', '#ffce56', '#4bc0c0', '#9966ff']
}]
},
options: {
scales: {
xAxes: [{
ticks: {
beginAtZero: true
}
}]
},
legend: {
labels: {
generateLabels: function(chart) {
var labels = chart.data.labels;
var dataset = chart.data.datasets[0];
var legend = labels.map(function(label, index) {
return {
datasetIndex: 0,
text: label,
fillStyle: dataset.backgroundColor[index],
strokeStyle: dataset.borderColor[index],
lineWidth: 1
}
});
return legend;
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="ctx"></canvas>

vAxis weird number order

Anyone know why my google chart is displaying the numbers on the left in such a strange order?
Here is an image of the problem:
And here is the code I'm using:
<script type="text/javascript">
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Ad', 'Views', 'Conversions', 'Appointments'],
["green", "9", "2", "2"],["logo", "18", "8", "1"],["maps", "8", "2", "0"],["resign", "14", "9", "1"],["scanimage", "1", "0", "0"], ]);
var options = {
chart: {
title: ''
}
};
var chart = new google.charts.Bar(document.getElementById('ad_chart'));
chart.draw(data, options);
}
</script>
The axis type is determined by the values in the data.
String values result in a Discrete axis, Numbers Continuous...
google.charts.load('44', {'packages': ['corechart', 'bar']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
// Number data (Continuous)
var data0 = google.visualization.arrayToDataTable([
['Ad', 'Views', 'Conversions', 'Appointments'],
["green", 9, 2, 2],
["logo", 18, 8, 1],
["maps", 8, 2, 0],
["resign", 14, 9, 1],
["scanimage", 1, 0, 0]
]);
// String data (Discrete)
var data1 = google.visualization.arrayToDataTable([
['Ad', 'Views', 'Conversions', 'Appointments'],
["green", "9", "2", "2"],
["logo", "18", "8", "1"],
["maps", "8", "2", "0"],
["resign", "14", "9", "1"],
["scanimage", "1", "0", "0"]
]);
var options = {
chart: {
title: ''
}
};
var chart0 = new google.charts.Bar(document.getElementById('ad_chart0'));
chart0.draw(data0, options);
var chart1 = new google.charts.Bar(document.getElementById('ad_chart1'));
chart1.draw(data1, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="ad_chart0"></div>
<div id="ad_chart1"></div>