In the following code, if I choose scatter3d instead of scatter, all parameter tickformat and title inside xaxis are completely ignored, and it is impossible to format anything under any axis.
Any suggetion would be appreciated.
Failing 3D Plot with outrageous date format
Working Plot with proper HH:MM:SS Format
function setup_plot(){
type='scatter';
var x=[],x0=new Date();
for (i=0;i<5;i++){
x[i]=new Date();
x[i].setTime(x0.getTime()+i*12*3600000);
}
var trace = [
{
type: type,
mode: 'lines',
x: x,
y: [1.0,1.0,1.0,1.0,1.0],
z: [2.6,1.2,6.3,4.8,4.7]
},
{
type: type,
mode: 'lines',
x: x,
y: [2.0,2.0,2.0,2.0,.0],
z: [3.1,2.6,4.8,3.8,1.7]
}
];
var layout = {
title: "Failing Plot",
xaxis:{
title:'Dates',
tickformat: '%H:%M:%S',
tickformatstops: [
{
dtickrange: [1000,60000],
value: '%H:%M:%S'
},
{
dtickrange: [60000,3600000],
value: '%H:%M:%S'
},
{
dtickrange: [3600000,86400000],
value: '%H:%M:%S'
},
{
dtickrange: [86400000,604800000],
value: '%d'
}
]
}
};
Plotly.newPlot('plot',trace,layout);
}
For 3d charts, axis layouts have to be provided within a scene, so
const layout = {
scene: {
xaxis: {
title: 'Dates',
...
}
}
}
See https://plotly.com/javascript/3d-axes/
Related
Trying to use plotly js to make a plot of dates, but for some reason it is showing time and date.
How can I remove time from this plot? Thanks!
x = ["2023-02-13", "2023-02-14"];
y = [3, 4];
var trace1 = {
type: "scatter",
mode: "lines",
name: '',
x: x,
y: y,
line: {color: '#17BECF'}
}
var layout = {
xaxis: {
type: 'date',
},
title: '',
};
var data = [trace1];
Plotly.newPlot('plotDiv', data, layout);
We can specify the tickformat in the xaxis of the layout with tickformat: '%b %d, %Y' to avoid including the time. And to avoid having the same date repeat on multiple ticks for the same day, we can also set the distance between ticks to be 1 day using dtick: 86400000.0 (which will be in units of seconds according to the documentation).
The codepen can be viewed here.
var layout = {
xaxis: {
type: 'date',
tickformat: '%b %d, %Y',
dtick: 86400000.0
},
title: '',
};
I am trying to make a chart which has years along the x-axis and dollar amounts along the y-axis. I finally got close to what I'm looking for, but I found that because the x coordinates are numbers, ChartJS is putting commas in them which looks really strange for years.
After some digging, I used the callbacks. options.plugin.tooltip.callbacks.label worked to let me remove commas in the tooltips, but when I use options.scales.x[0].ticks.callback to try to fix the labels on the bottom, not only does it not work, but I don't see the console.log statement in their ever being printed so it seems it's not even calling the callback. I've tried several variations of how to do the callback based on what I found online and on Stack Overflow which I think correspond to the different ways ChartJS did this in different versions. (I'm on version 3.5.1.)
Then, I realized that... none of the options under options.scales appear to have any effect. I change the min, the title, the tick settings (color to red, callback, etc.) and it has no effect. (This also explains why I was having trouble when using the line chart and had to switch to scatter; apparently type: 'linear' wasn't being picked up nor did it do anything different when I set it to type: 'date' or whatever the exact working was for that.)
Meanwhile, the other options like options.showLine or options.elements do have an effect and I'm seeing the chart and not getting any errors in the console. So, it is picking up the options, just ignoring everything I have in options.scales.
Here is the relevant code:
// Sample data added to make this example self-contained
// This is my internal data format
let data = {
"Series1": [ {x: 2001, y: 100 }, {x: 2002, y: 110 }, {x: 2003, y: 107 }, ],
"Series2": [ {x: 2001, y: 107 }, {x: 2002, y: 102 }, {x: 2004, y: 95 }, ],
}
// Define data //////////////////////////////////////////////////////
// I convert data to format ChartJS wants and add a few options
let datasets = [];
for(let label in data) {
let c = colorIterator.next().value
datasets.push({
label: label,
data: data[label],
backgroundColor: c,
borderColor: c,
});
}
// Define options //////////////////////////////////////////////////////
let chartConfig = {
type: 'scatter',
data: { datasets: datasets, },
options: {
title: { display: false },
indexAxis: 'x', responsive: true, maintainAspectRatio: false,
showLine: true,
elements: {
line: { display: true, tension: 0, borderWidth: 1, fill: false, },
point: { radius: 3 }
},
interaction: { mode: 'x', },
scales: {
x: [{
type: 'linear',
min: 1995, max: (new Date()).getFullYear()+1, stepSize: 1,
title: { display: true, text: 'Year' },
ticks: {
display: true,
major: { enabled: true },
color: 'red',
callback: function(value, index, ticks) {
console.log(value);
return Chart.Ticks.formatters.numeric.apply(this, [value, index, ticks])
.replace(",","");
}
}
}],
y: [{
title: { display: true, text: '$' },
ticks: {
display: true,
color: 'red',
},
}],
},
plugins: {
tooltip: {
callbacks: {
label: function(context) {
let label = context.dataset.label || '';
if(label) {
let x = context.label.replace(",","");
let y = context.formattedValue;
return 'Year ' + x + ' "' + label + '": $' + y;
} else { return 'x'; }
},
},
},
},
}
};
// MAKE CHART //////////////////////////////////////////////////////
let mainChart = new Chart(document.getElementById(c.id), chartConfig);
As described in the docs the scales are not arrays. All the scales are objects in the scale object.
So you will need to change your code to this:
options: {
scales: {
x: {
// x options
},
y: {
// y options
},
}
}
I was wondering how can you achieve the following:
I'm using a Date format of year and month ( i.e 2022-01), but Plotly is not providing an option to have a simple date value for the x Axis, Chart.JS actually allows you to define the date by month, so what is happening is that if you zoom in to one month, then you can see days and even hours, so how do I change that?
Secondly, is there a way to control how the X-axis is displayed?, for example perhaps when you have more than one year is better to show quarters, but as you zoom in for a 1-year period, then I would like to see every month display?, but I don't want to have more granularity, I would like to have only the month display in the graph
https://jsfiddle.net/60ucqz8w/
var Deals = {
x: ['2021-10', '2022-01', '2022-03', '2022-04', '2022-05', '2022-07', '2022-09'],
y: [11241, 234021, 26544, 28856, 70463, 28856, 155019],
name: 'Deals',
type: 'bar',
marker: {
color: 'rgb(0,131,117)',
}
};
var Leads = {
x: ['2022-03', '2022-04', '2022-05', '2022-06', '2022-07', '2022-08', '2022-11', '2023-01', '2023-02'],
y: [7255, 5155, 61950, 63000, 5155, 19845, 20905, 5155, 15750],
name: 'Leads',
type: 'bar',
marker: {
color: 'rgb(160,220,210)',
}
};
var Cumulative = {
x: ['2021-10', '2022-01', '2022-03', '2022-04', '2022-05', '2022-07', '2022-09'],
y: [11241, 245262, 271806, 300662, 371125, 399981, 555000],
name: 'Cumulative Deals',
type: 'line',
marker: {
color: 'rgb(0,131,117)',
}
};
var data = [Deals,Leads,Cumulative];
var layout = {
title: "Sales Forecast",
barmode: 'stack',
xaxis: {
autorange: true,
rangeselector: {
buttons: [{
step: 'all'
},
{
count: 1,
label: 'YTD',
step: 'year',
stepmode: 'todate'
},
{
count: 6,
label: '6m',
step: 'month',
stepmode: 'todate'
}]},
rangeslider: { },
type: 'date',
tickfont:{
size: 14
},
},
yaxis: {
tickfont:{size: 14}
}
};
Plotly.newPlot('DivBarChart', data,layout);```
You code was mostly right the only thing that needed fixing is the scrollZoom: true. The code won't work unless you put scrollZoom: true because the function won't be active unless specified. You need this so you can enable it for your graph. You need to select the timeframe using you mouse. Click and drag to see your timeframe.
var Deals = {
x: ['2021-10', '2022-01', '2022-03', '2022-04', '2022-05', '2022-07', '2022-09'],
y: [11241, 234021, 26544, 28856, 70463, 28856, 155019],
name: 'Deals',
type: 'bar',
marker: {
color: 'rgb(0,131,117)',
}
};
var Leads = {
x: ['2022-03', '2022-04', '2022-05', '2022-06', '2022-07', '2022-08', '2022-11', '2023-01', '2023-02'],
y: [7255, 5155, 61950, 63000, 5155, 19845, 20905, 5155, 15750],
name: 'Leads',
type: 'bar',
marker: {
color: 'rgb(160,220,210)',
}
};
var Cumulative = {
x: ['2021-10', '2022-01', '2022-03', '2022-04', '2022-05', '2022-07', '2022-09'],
y: [11241, 245262, 271806, 300662, 371125, 399981, 555000],
name: 'Cumulative Deals',
type: 'line',
marker: {
color: 'rgb(0,131,117)',
}
};
var data = [Deals, Leads, Cumulative];
var layout = {
title: "Sales Forecast",
barmode: 'stack',
};
Plotly.newPlot('DivBarChart', data, layout, {
scrollZoom: true
});
<div class="col-sm-4">
<div id='DivBarChart' class="container"></div>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</div>
See scroll and zoom in or plotly.js docs for more information.
i added this code
scales:
{
xAxes:
[{
type: 'time',
time:
{
unit: 'month',
displayFormats: { month: 'MM' },
max: '2017-10-09 18:43:53',
min: '2017-10-02 18:43:53'
}
}]
},
to the options but it does not work. Any ideas what i'm making wrong?
FIDDLE ->
https://jsfiddle.net/o473y9pw/
Since you wish to use time for x-axis, your labels array should be an array of date/time string (labels array is correspondent to x-axis).
You would also need to set the parser property (to parse the date/time correctly), and x-axis' ticks source to data (to properly generate x-axis ticks).
UPDATE
If you only have a min and max date then, you can create a nice little plugin to populate the labels (date) array dynamically, as such :
plugins: [{
beforeInit: function(chart) {
var time = chart.options.scales.xAxes[0].time, // 'time' object reference
// difference (in days) between min and max date
timeDiff = moment(time.max).diff(moment(time.min), 'd');
// populate 'labels' array
// (create a date string for each date between min and max, inclusive)
for (i = 0; i <= timeDiff; i++) {
var _label = moment(time.min).add(i, 'd').format('YYYY-MM-DD HH:mm:ss');
chart.data.labels.push(_label);
}
}
}]
note: moment.js is used to make calculations easier.
ᴡᴏʀᴋɪɴɢ ᴇxᴀᴍᴘʟᴇ ⧩
( for demonstration purposes, I've changed the time unit to day )
$(document).ready(function() {
new Chart(document.getElementById("chartBox"), {
type: 'line',
data: {
datasets: [{
data: [12, 19, 3, 5, 2, 3, 32, 15],
label: "",
borderWidth: 2,
borderColor: "#3e95cd",
fill: false,
pointRadius: 0
}]
},
options: {
scales: {
xAxes: [{
type: 'time',
time: {
parser: 'YYYY-MM-DD HH:mm:ss',
unit: 'day',
displayFormats: {
day: 'ddd'
},
min: '2017-10-02 18:43:53',
max: '2017-10-09 18:43:53'
},
ticks: {
source: 'data'
}
}]
},
legend: {
display: false
},
animation: {
duration: 0,
},
hover: {
animationDuration: 0,
},
responsiveAnimationDuration: 0
},
plugins: [{
beforeInit: function(chart) {
var time = chart.options.scales.xAxes[0].time, // 'time' object reference
timeDiff = moment(time.max).diff(moment(time.min), 'd'); // difference (in days) between min and max date
// populate 'labels' array
// (create a date string for each date between min and max, inclusive)
for (i = 0; i <= timeDiff; i++) {
var _label = moment(time.min).add(i, 'd').format('YYYY-MM-DD HH:mm:ss');
chart.data.labels.push(_label);
}
}
}]
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/moment#latest/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.0/Chart.min.js"></script>
<canvas id="chartBox"></canvas>
The dataset should be an array of objects with properties x for time and y for value.
$(document).ready(function() {
var data = [{
x: new moment().add(-10, "months"),
y: Math.random() * 100
},
{
x: new moment().add(-8, "months"),
y: Math.random() * 100
},
{
x: new moment().add(-6, "months"),
y: Math.random() * 100
},
{
x: new moment().add(-4, "months"),
y: Math.random() * 100
},
{
x: new moment().add(-2, "months"),
y: Math.random() * 100
},
{
x: new moment().add(-0, "months"),
y: Math.random() * 100
},
];
new Chart(document.getElementById("chartBox"), {
type: 'line',
data: {
datasets: [{
data: data,
borderColor: "#3e95cd",
fill: false
}]
},
options: {
scales: {
xAxes: [{
type: 'time'
}]
},
legend: false
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.0/Chart.bundle.min.js"></script>
<canvas id="chartBox"></canvas>
Fiddle
If the xAxis label is in date format use this code
time:
{
format: 'MM',
unit: 'month',
displayFormats: { month: 'MM' },
max: '2017-10-09 18:43:53',
min: '2017-10-02 18:43:53'
}
If the xAxis label is as what u used numerals use
time:
{
format: 'MM',
unit: 'month',
parser:'MM',
displayFormats: { month: 'MM' },
max: '2017-10-09 18:43:53',
min: '2017-00-02 18:43:53'
}
You might want to change a few things.
Your data should include time data.
If you set scale unit to be month, your min max should be more than one month to see the actual scales.
Here's simplified working example.
https://jsfiddle.net/f2xmkkao/
C3 graph overlap x-axis labels which is in date time format. I have googled this query but didn't get any solution for it.Is it possible that c3 only shows couple of date time rather then showing altogether which result in overlap x-axis labels
var data = {
x: 'x',
xFormat:'%Y-%m-%d/%H:%M',
empty: {
label: {
text: "No Data"
}
},
columns: [
['x', '{$dateArray}'],
['Attack', {$data}],
],colors: {
Attack: '#67b7dc',
},
types: {
Attack: 'area'
}};
var chart = c3.generate({bindto: '#chart1',
size: {
height: 630,
},
data: data,
grid: {
x: {
show: true
},
y: {
show: true
}
},
tooltip: {
format: {
value: function (value, ratio, id) {
var format = value+' Gbps [ IP: '+destIp[value]+' ]';
return format;
}
}
},
zoom: {
enabled: true
},
subchart: {
show: true
},axis: {
x: {
type: 'timeseries',
tick: {
format: '%b %d, %H:%M',
rotate: 90,
multiline: false
}
},
y: {
tick: {
format: function (d) {
return d.toFixed(3);
}
},
label: {
text: 'Attack Size ( Gbps )',
position: 'outer-middle'
}
}
}
});
Use c3.js chart config tick.count, set it to desired integer value like 2,3 or 4.
Use c3.js Timeseries Chart exmaple to play with this config.
Problem without tick.count:-
Problem solved with tick.count config:-