How to pass degree Celsius as symbol to YAxis title - canvasjs

How can I pass degree Celcius symbol for yAxis
I have tried all kinds
1. °
2. U+00B0 - unicode
3. ° - html code
but all of them get printed as given and do not print the degree symbol.

You can use suffix property to add suffix in axis labels to do this.
var chart = new CanvasJS.Chart("chartContainer", {
axisY: {
suffix: " °C"
},
data: [{
type: "spline",
yValueFormatString: "#0.## °C",
dataPoints: [
{ x: new Date(2017,6,24), y: 31 },
{ x: new Date(2017,6,25), y: 31 },
{ x: new Date(2017,6,26), y: 29 },
{ x: new Date(2017,6,27), y: 29 },
{ x: new Date(2017,6,28), y: 31 },
{ x: new Date(2017,6,29), y: 30 },
{ x: new Date(2017,6,30), y: 29 }
]
}]
});
chart.render();
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<div id="chartContainer" style="height: 300px; width: 100%;"></div>

Related

Change grid color in C3.js

How can I achieve this grid and label colors. I can find some answers on label colors but nothing on changing the grid color to the one shown in the screenshot, instead of the default black one.
Just in case you need my working code:
var chart = c3.generate({
bindto: '#chart',
data: {
x: 'x',
columns: [
['x', ...xAxis],
['total', ...yAxis],
],
type: 'bar',
colors: {
total: d3.rgb(40,162,245)
},
empty: { label: { text: "No Data Available" }}
},
axis: {
x: {
tick: {
culling: {
max: 31,
},
},
},
y: {
tick: {
format: (x) => x / 1000 + 'k',
},
},
},
grid: {
y: {
show: true,
color: '#fff'
},
},
})
Try to use selector .c3 path, .c3 line:not([stroke-width="10"]) for lines, and tspan for text.
.c3 line[stroke-width="10"] is used for legend squares, it needs be excluded.
Also see How to get rounded corner in c3js bar charts
const xAxis = [10, 20, 40];
const yAxis = [2000, 1420, 1000];
var chart = c3.generate({
bindto: '#chart',
data: {
x: 'x',
columns: [
['x', ...xAxis],
['total', ...yAxis],
],
type: 'bar',
colors: {
total: d3.rgb(40,162,245)
},
empty: { label: { text: "No Data Available" }}
},
axis: {
x: {
tick: {
culling: {
max: 31,
},
},
},
y: {
tick: {
format: (x) => x / 1000 + 'k',
},
},
},
grid: {
y: {
show: true,
color: '#fff'
},
},
})
.c3 path, .c3 line:not([stroke-width="10"]) {
stroke: gold !important;
}
tspan {
stroke: green !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.16.0/d3.min.js" integrity="sha512-FHsFVKQ/T1KWJDGSbrUhTJyS1ph3eRrxI228ND0EGaEp6v4a/vGwPWd3Dtd/+9cI7ccofZvl/wulICEurHN1pg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.7.20/c3.min.js" integrity="sha512-+IpCthlNahOuERYUSnKFjzjdKXIbJ/7Dd6xvUp+7bEw0Jp2dg6tluyxLs+zq9BMzZgrLv8886T4cBSqnKiVgUw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.7.20/c3.min.css" integrity="sha512-cznfNokevSG7QPA5dZepud8taylLdvgr0lDqw/FEZIhluFsSwyvS81CMnRdrNSKwbsmc43LtRd2/WMQV+Z85AQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<div id="chart">

How do I dynamically update the coordinates for nodes in a D3 forceSimulation?

I am trying to update the position of a node, based on a click event.
I can see that the data is updated in console, however the x,y coordinates aren't updating. I was expecting the forceSimulation to update the x,y coordinates as soon as the data changed.
Obviously, I have misunderstood how this works. But if you could state where exactly I was wrong in my intuition, that would really help me out. My thought process was that the force simulation would update the the forceX and forceY coordinates based on the foci_dict.
In console : {name: "b", age: 27, index: 0, x: 45.46420808466252, y: 54.94672336907456, …}
The object was updated, however the coordinates didn't update.
<html>
<body>
<canvas id="bubbles" width="1500" height="500"></canvas>
<button onClick="changeMe()"> clicck me </button>
</body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var height = 500;
var width = 1500;
var canvas = d3.select("#bubbles");
var ctx = canvas.node().getContext("2d");
var r = 5;
var data = [
{ name: "a", age: 27 },
{ name: "a", age: 21 },
{ name: "a", age: 37 },
{ name: "b", age: 23 },
{ name: "b", age: 33 },
{ name: "c", age: 23 },
{ name: "d", age: 33 }
];
var foci_points = {
'a': { x: 50, y: 50 },
'b': { x: 150, y: 150 },
'c': { x: 250, y: 250 },
'd': { x: 350, y: 350 }
};
var simulation = d3.forceSimulation()
.force("x", d3.forceX(function(d){
return foci_points[d.name].x;
}))
.force("y", d3.forceY(function(d){
return foci_points[d.name].y;
})
)
.force("collide", d3.forceCollide(r+1))
.force("charge", d3.forceManyBody().strength(10))
.on("tick", update);
simulation.nodes(data);
function update() {
ctx.clearRect(0, 0, width, height);
ctx.beginPath();
data.forEach(drawNode);
ctx.fill();
}
function changeMe(){
data[0].name="b";
console.log(data);
}
function drawNode(d) {
ctx.moveTo(d.x, d.y);
ctx.arc(d.x, d.y, r, 0, 2 * Math.PI);
}
update();
</script>
</html>
There are two issues you have to address:
The forces will not update automatically just because the underlying data has changed. You have to programmatically re-initialize the forces by calling force.initialize(nodes). Given your code this could be somewhat along the following lines:
simulation.force("x").initialize(data); // Get the x force and re-initialize.
simulation.force("y").initialize(data); // Get the y force and re-initialize.
By the time you click the button the simulation will have cooled down or even stopped. To get it going again you have to reheat it by setting alpha to some value greater than alphaMin and by restarting the simulation run.
simulation.alpha(1).restart(); // Reheat and restart the simulation.
These actions can best be done in your changeMe() function.
Have a look at the following snippet for a running demo:
var height = 500;
var width = 1500;
var canvas = d3.select("#bubbles");
var ctx = canvas.node().getContext("2d");
var r = 5;
var data = [{
name: "a",
age: 27
},
{
name: "a",
age: 21
},
{
name: "a",
age: 37
},
{
name: "b",
age: 23
},
{
name: "b",
age: 33
},
{
name: "c",
age: 23
},
{
name: "d",
age: 33
}
];
var foci_points = {
'a': {
x: 50,
y: 50
},
'b': {
x: 150,
y: 150
},
'c': {
x: 250,
y: 250
},
'd': {
x: 350,
y: 350
}
};
var simulation = d3.forceSimulation()
.force("x", d3.forceX(function(d) {
return foci_points[d.name].x;
}))
.force("y", d3.forceY(function(d) {
return foci_points[d.name].y;
}))
.force("collide", d3.forceCollide(r + 1))
.force("charge", d3.forceManyBody().strength(10))
.on("tick", update);
simulation.nodes(data);
function update() {
ctx.clearRect(0, 0, width, height);
ctx.beginPath();
data.forEach(drawNode);
ctx.fill();
}
function changeMe() {
data[0].name = "b";
simulation.force("x").initialize(data);
simulation.force("y").initialize(data);
simulation.alpha(1).restart();
}
function drawNode(d) {
ctx.moveTo(d.x, d.y);
ctx.arc(d.x, d.y, r, 0, 2 * Math.PI);
}
update();
<script src="https://d3js.org/d3.v4.min.js"></script>
<body>
<button onClick="changeMe()"> clicck me </button>
<canvas id="bubbles" width="1500" height="500"></canvas>
</body>

canvasjs in decimal format with suffix is not working properly

I use canvasJS to make a line graph report, the issue now is it didn't show properly in tooltip using yValueFormatString.
my goal is to display the value:
{
type:"stepLine",
name: "title",
showInLegend: true,
connectNullData: true,
yValueFormatString: "##.## %",
dataPoints: [
{ x: new Date(2019, 1, 20), y: 12.78 },
{ x: new Date(2019, 1, 19), y: 12.79 },
{ x: new Date(2019, 1, 18), y: 12.80 },
]
}
in tooltip, it shows
1278 %
1279 %
1280 %
I think there's something wrong with it, I wanted to display like:
12.78 %
12.79 %
12.80 %
any idea?
According to documentation, "%" Multiplies a number by 100 i.e. 12.78("##.## %") => 1278%. Instead setting yValueFormatString to "##.#0 '%'" should work fine in this case.
Here is an example:
var chart = new CanvasJS.Chart("chartContainer", {
data: [{
type:"stepLine",
name: "title",
showInLegend: true,
connectNullData: true,
yValueFormatString: "##.#0 '%'",
dataPoints: [
{ x: new Date(2019, 1, 20), y: 12.78 },
{ x: new Date(2019, 1, 19), y: 12.79 },
{ x: new Date(2019, 1, 18), y: 12.80 },
]
}]
});
chart.render();
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<div id="chartContainer" style="width: 100%; height: 260px"></div>

Set the y axis spacing in c3

I have the following chart and I want to make the y axis spacing integers only (when the data to display is low, I get decimals: 0.1, 0.2...). Anyone can help?
var Presence = c3.generate({
bindto: '#presence',
data: {
url: 'ranking.csv',
x:'AC_YEAR',
types: {
Number_students: "bar",
Ranking: 'spline'
},
axes:{
Number_students: "y",
Ranking: "y2"
}
},
axis: {
y: {
label: {
text:"Students",
position: "outer-middle"
},
tick: {
outer: false}
},
y2: {
inverted:true,
show: true,
label: {
text:"Ranking position",
position: "outer-middle"
},
tick: {
outer: false
}
},
x: {
label: {
text:"Year",
position: "outer-center"
},
tick: {outer: false}
}
},
size: {
height: 400,
width: 800
},
});
The csv file looks like this:
AC_YEAR,Number_students,Ranking
2011,1,103
2012,2,30
2014,1,178
2015,1,188
But the csv is changing over time and sometimes the Number of students is 100. So that is why I do not want to fix values on the y axis, only avoid having floats when the Number of students is low (1 or 2)
Thanks in advance!
Set the y tick formatting function to return blanks on non-whole numbers
y: {
label: {
text:"Students",
position: "outer-middle"
},
tick: {
format: function (d) {
return Math.abs(Math.round(d) - d) < 0.001 ? d : "";
},
outer: false
}
},

change type of labels of x-axis in column chart

I am using 2 chart of canvasjs plugin piechart and columnchart.
In piechart labels of the elements are so fine it uses all the spaces into content free but column chart if one label is length is big it skipped. But I dont want it to skip.
so this is my question, is there any way using labels(X-Axis only) in column chart(barchart) like just like in piechart ?
Thank you.
Note: I parse it, change it etc. everything comes up another problem if I interrupt the plugin itself so I need though solution.
Charts automatically skips label when they are too close to avoid overlapping. You can override this behavior by setting interval to 1.
Refer Axis X Interval for more detail.
Here is an example:
var chart = new CanvasJS.Chart("chartContainer",
{
axisX:{
title: "Axis X with interval 1",
interval: 1
},
data: [
{
type: "column",
dataPoints: [
{ x: 1, y: 71 },
{ x: 2, y: 55 },
{ x: 3, y: 50 },
{ x: 4, y: 65 },
{ x: 5, y: 95 },
{ x: 6, y: 68 },
{ x: 7, y: 28 },
{ x: 8, y: 34 },
{ x: 9, y: 14 },
{ x: 10, y: 14 },
{ x: 11, y: 71 },
{ x: 12, y: 55 },
{ x: 13, y: 50 },
{ x: 14, y: 65 },
{ x: 15, y: 95 },
{ x: 16, y: 68 },
{ x: 17, y: 28 },
{ x: 18, y: 34 },
{ x: 19, y: 14 }
]
}
]
});
chart.render();
<script src="http://canvasjs.com/assets/script/canvasjs.min.js"></script>
<br/>
<div id="chartContainer" style="height: 360px; width: 100%;"></div>

Resources