C3.js bar plot with dates as x axis - javascript

I'm trying to make a C3 bar plot using the X with dates. I have the data formatted already in consecutive dates aggregated by days.
I've created a fiddle with what I thought will work: https://jsfiddle.net/8aL1stcs/
the plot as such is working fine, here is a version of the fiddle with the X axis commented out: https://jsfiddle.net/8aL1stcs/1/
var elementID = "#myPlot";
var myData = {};
//myData.x = 'x';
//myData.xFormat = "%Y-%m-%d";
myData.type = 'bar';
myX = ["2015-11-20", "2015-11-21", "2015-11-22","2015-11-23", "2015-11-24"];
myY = [1,2,3,4,5];
myX.splice(0,0,'x');
myY.splice(0,0,'New Reports');
myData.columns = [];
//myData.columns.push(myX);
myData.columns.push(myY);
var chart = c3.generate({
bindto: elementID,
data: myData,
size: {
height: 480,
width:400,
},
bar: {
width: {
ratio: 0.5 // this makes bar width 50% of length between ticks
}
// or
//width: 100 // this makes bar width 100px
}
});
Basically I want to mimic this plot here:
For this, I think I need to use some automated way of handling the x-ticks. In other words: I don't want to set the ticks manually.

You missed this in your c3 generate json.
axis: {
x: {
type: 'timeseries',
tick: {
format: "%b-%d"//format in which you want the output
}
},
}
Working code here
Hope this helps!

Related

Plotlyjs ticktext/tickvals not showing xaxis labels

I have been trying to utilize the tickvals/ticktext on plotlyjs to be able to show duplicate values on a graph for the xaxis. It works in the aspect of separating the data (having multiple duplicate values be on the xaxis, but a 1:1 data point) -- the issue that I am having is that no xaxis tick marks or xaxis labels show up for the ticks.
Here is a code pen of my problem:
https://codepen.io/hiquetj/pen/yLeBNjJ
Here is the code for easier reading:
var trace1 = {
y: [1323,1070,849,1312,1214,1264,680,2006,1625,0,1199,1770,1880,708,603,649,1384,732,2312,92,1377,1125,1219,1757,1207,2397,1190,1818,2846,1200,1685,1563,1203,1059,820,4303,812,3640,1924,4185,1269,2263,1140,1210,1638,1362,4915,1594,683,1222],
mode: 'markers'
};
var trace2 = {
y: [5870,1574,1372,2093,1361,1388,615,1927,947,,1040,,,638,546,542,1051,637,4161,289,1103,0,1308,1658,1340,2198,1245,1568,2392,1297,1583,1281,1282,697,482,3633,653,3233,2096,3815,1401,2116,867,1232,1420,1010,4091,478,208,1262],
mode: 'lines'
};
var trace3 = {
y: [1141,1324,424,668,414,407,494,1763,1100,,522,360,108,474,145,621,689,234,154,40,303,364,407,1133,347,1527,358,1745,1223,345,1131,1024,365,754,614,1894,287,5332,363,568,335,1545,1294,383,1255,1107,2090,612,66,390],
mode: 'lines+markers'
};
var data = [ trace1, trace2, trace3 ];
var layout = {
xaxis: {
ticktext: [24346247,24346247,24346247,24346247,24332892,24332892,24332892,24332670,24332670,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24316962,24316962,24316962,24290013,24290013,24290013,24290013,24290013,23738933,23738933,23738933,23738933,23738933,23738933,23738933,23738933,23738933,23738933,23738933,23738933,23738933,23738933],
tickvals: [24346247,24346247,24346247,24346247,24332892,24332892,24332892,24332670,24332670,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24330025,24316962,24316962,24316962,24290013,24290013,24290013,24290013,24290013,23738933,23738933,23738933,23738933,23738933,23738933,23738933,23738933,23738933,23738933,23738933,23738933,23738933,23738933],
},
};
Plotly.newPlot('myDiv', data, layout, {showSendToCloud: true});
Example of x axis labels not showing up through codepen.
If you do not set x values for your traces, they are automatically assigned x values from 0 to n. Your ticktexts will therefore only be visible if your tickval array is [0, 1, 2, 3, ..., n], see this jsFiddle: https://jsfiddle.net/9okdx4b2/

Highcharts: Can I animate changing the order of bars on bar chart?

I want to create a chart like the below.
https://www.reddit.com/r/interestingasfuck/comments/9togwf/the_major_world_economies_over_time/
I created this chart by Highcharts. But, I can't animate changing the order of bars.
function rotate(array, times) {
while (times--) {
var temp = array.shift();
array.push(temp)
}
}
window.data = {
categories: ['Africa', 'America', 'Asia', 'Europe', 'Oceania'],
y_values: [100, 200, 300, 400, 500],
colors: ['#DC4D3A', '#E93D3F', '#83C6C7', '#46D388', '#D1D785']
};
document.getElementById("button").addEventListener("click", function () {
for (var i = 0; i < data['y_values'].length; i++) {
chart.series[0].data[i].update({y: data['y_values'][i]});
chart.series[0].data[i].update({color: data['colors'][i]});
}
chart.xAxis[0].update({categories: data['categories']});
rotate(data['y_values'], 1);
rotate(data['categories'], 1);
rotate(data['colors'], 1);
}, false);
All code I wrote are in JSFiddle.
https://jsfiddle.net/Shinohara/35e8gbyz/
Please anyone can help me?
Highcharts provides animate method for SVG elements, which you can use to achieve the wanted result. You need to animate columns, axis labels and data labels:
document.getElementById("button").addEventListener("click", function() {
var points = chart.series[0].points,
ticks = chart.xAxis[0].ticks;
points[0].graphic.animate({
x: points[1].shapeArgs.x
});
points[1].graphic.animate({
x: points[0].shapeArgs.x
});
points[0].dataLabel.animate({
y: points[1].dataLabel.translateY
});
points[1].dataLabel.animate({
y: points[0].dataLabel.translateY
});
ticks[0].label.animate({
y: ticks[1].label.xy.y
});
ticks[1].label.animate({
y: ticks[0].label.xy.y
});
}, false);
Live demo: https://jsfiddle.net/BlackLabel/ux59vcd6/
API Reference: https://api.highcharts.com/class-reference/Highcharts.SVGElement#animate
It seems there is no native implementation.
The only idea I have it to not display Y axis labels at all. Using SVGRenderer
draw the text and save it as a variable (for further updating)
chart.customText = chart.renderer.text('label name', 100, 100) // label name, X, Y
.attr({
useHTML: true
})
.css({
fontSize: '16px' // and other CSS if necessary
})
.add();
Then you can update x, y or text
chart.customText.attr({
str: 'new text. You can use HTML',
y: 150 // new value
})
Your next step is to do something with Y position. Or even you can try to draw only 1 text with HTML that contains all labels. Then using JS move them as you need.

How to change x-Axes label position in Chart.js

Is it possible to change the label position, like padding or margin in CSS?
I would like to have the labels above the x-Axes.
You can change the xAxes label positions with the following steps:
Add .getContext("2d") to the call that gets the ctx canvas object:
var ctx = document.getElementById("gescanntePackzettelChart").getContext("2d");
Hide the current xAxes ticks:
xAxes: [{
ticks: {
display: false
}
}
Add an animation to the options config, and use the canvas fillText() method to create new labels:
animation: {
duration: 1,
onComplete: function() {
var controller = this.chart.controller;
var chart = controller.chart;
var xAxis = controller.scales['x-axis-0'];
var numTicks = xAxis.ticks.length;
var xOffsetStart = xAxis.width / numTicks;
var halfBarWidth = (xAxis.width / (numTicks * 2));
xAxis.ticks.forEach(function(value, index) {
var xOffset = (xOffsetStart * index) + halfBarWidth;
var yOffset = chart.height - 20;
ctx.fillText(value, xOffset, yOffset);
});
}
}
For xOffset, to figure out the correct position, take the xAxis width and divide it by the number of tick labels. This will tell you how wide each bar is. Then, multiply that number by the current index to position the label in front of the correct bar. Finally, add add the width of half a bar to center the labels in the bar.
For the yOffset, start with the chart's height and subtract however much you want to move the labels up.
Working JSFiddle: https://jsfiddle.net/m5tnkr4n/124
Building on #Tot-Zam's response, it's possible to use the ChartJs scale object's methods to define the context pixel coordinates easier. You also don't need to define a ctx object - it is already accessible using the this.chart object.
animation: {
duration: 0,
onComplete: function() {
let chart = this.chart;
let controller = chart.controller;
let axis = controller.scales['x-axis-0'];
let yOffset = chart.height - 5;
axis.ticks.forEach(function(value, index) {
let xOffset = axis.getPixelForValue(value);
chart.ctx.fillText(value, xOffset, yOffset);
})
}
}
Working repl: https://repl.it/#lunarplasma/ChartJs-custom-axis-labels

NVD3 lineChart Conditional Area Color Based On Y Axis

I'm trying to have positive Y values fill with blue and negatives with red. Here is what my graph looks like: Image of Current Graph.
I'm currently adding the color to my dataset in app.js:
if(displayData["VARIANCE"] >= 0){
ctvar.push({
x: Date.now(), y: displayData["VARIANCE"], color:"#0000ff"
});
}else{
ctvar.push({
x: Date.now(), y: displayData["VARIANCE"], color:"#ff0000"
});
}
The dataset is passed to my jade template file as ctvv where I set all the graph settings in js:
function myData() {
return [
{
key: "Cycle time Variance",
values: ctvv,
area: true
}
];
}
nv.addGraph(function() {
var chart = nv.models.lineChart();
chart.xAxis.axisLabel("Time").tickFormat(function(d) {
return d3.time.format('%H:%M')(new Date(d));
});
chart.lines.scatter.xScale(d3.time.scale());
chart.yAxis.axisLabel("Seconds").tickFormat(d3.format("d")).ticks(5);
chart.yDomain([-60,60]);
d3.select("svg").datum(myData()).transition().duration(0).call(chart);
nv.utils.windowResize(
function() {
chart.update();
}
);
return chart;
});
I've tried setting the chart colors using the ctvv and also a plain array of colors.

Remove axis on IDD chart

I'm trying to visualize a time series using IDD. How can I remove the X axis that indicates float values from the chart and leave only time stamps?
Here is my code:
var timeSeriesChart = InteractiveDataDisplay.asPlot("chart");
var timeSeriesData = JSON.parse('{\
"times":["2016-03-28 16:00","2016-03-28 17:00","2016-03-28 18:00"],\
"time_locations":[0.6,1.2,1.8],\
"values":[3.0, 4.0, 5.0]}');
timeSeriesChart.polyline("Time series",
{
y: timeSeriesData.values,
x: false,
stroke: "rgb(89,150,255)",
thickness: 3
});
timeSeriesChart.addAxis("bottom", "labels", {
labels: timeSeriesData.times,
ticks: timeSeriesData.time_locations
});
see the chart
Try
var numAxis = timeSeriesChart.getAxes("bottom");
numAxis[0].remove();
To remove existing axis before adding your labeled axis.
And after you add your labeled axis, attach grid lines to this new axis:
var gridLines = $('#chart > div[data-idd-plot="grid"]');
var grid = timeSeriesChart.get(gridLines[0]);
grid.xAxis = timeAxis.axis;

Categories