I have to render series data for current month/quarter/year data using morris.js charts. The series has data points on daily basis and I see a repeating days on the x-axis.
jsfiddle
I also tried turning off parseTime and using xLabelFormat as suggested on few posts on SO using the code below but output has duplicate values for days:
Morris.Line({
element: element,
data: [
{"day":"2017-10-01 11:40:09","uniqueUsers":"180","sessions":"213"},
{"day":"2017-10-01 12:40:09","uniqueUsers":"217","sessions":"213"},
{"day":"2017-10-02 11:40:09","uniqueUsers":"539","sessions":"635"},
{"day":"2017-10-03 11:40:09","uniqueUsers":"684","sessions":"826"},
{"day":"2017-10-04 07:40:09","uniqueUsers":"1095","sessions":"1229"},
{"day":"2017-10-04 10:40:09","uniqueUsers":"822","sessions":"987"},
{"day":"2017-10-04 11:40:09","uniqueUsers":"568","sessions":"836"},
{"day":"2017-10-05 11:40:09","uniqueUsers":"335","sessions":"385"}
],
xkey: 'day',
xlabels: 'day',
xLabelFormat: function (x) {
var d = new Date(x.label.slice(0, 10) + "T" + x.label.slice(11, x.label.length));
return d.getDate() + ' ' + months[d.getMonth()];
},
ykeys: ['uniqueUsers', 'sessions'],
labels: ['Unique users', 'User sessions'],
pointSize: 2,
hideHover: 'auto',
lineColors: ['rgb(156, 39, 176)', 'rgb(121, 85, 72)', 'rgb(0, 188, 212)', 'rgb(255, 152, 0)'],
xLabelAngle: 50,
//dateFormat: function (d) {
// var ds = new Date(d);
// return ds.getDate() + ' ' + months[ds.getMonth()];
//},
behaveLikeLine: true,
parseTime: false
});
How can I remove duplicate values on x-axis?
these are not redundant values, these are dates formatted automatically by Morris.js.
Therefore, you have 2 choices:
either do not parse the dates, and just display the value of "day", by setting parseTime to false
or you change date format on x-axis, by setting xLabels to hour
You can read more about these settings in the documentation.
Related
I am using Chart.Js "2.8.0" and chartjs-plugin-annotation "0.5.7" to display boxes based on timestamp intervals
I am trying to show something like this:
based on timstamp intervals, but cannot find something from their docs.
The result is...:
code examples:
annotations.push({
type: 'box',
id: `status-${index}`,
xScaleID: `x-axis-${index}`,
yScaleID: `y-axis-${index}`,
backgroundColor: 'rgba(188, 170, 164, 0.2)',
borderWidth: 0,
xMin: data.linkedTime, // timestamp
xMax: data.unlinkedTime, // timestamp - can be null(till present)
label: {
enabled: true,
fontSize: 12,
drawTime: 'afterDraw',
content: data.name,
xAdjust: 0,
yAdjust: 0,
position: 'top'
}
});
chart xaxis (using dayjs let labels = items.map(({ time }) => this.$dayjs.unix(time));):
xAxes: [
{
type: 'time',
time: {
unit: 'day',
unitStepSize: 1,
displayFormats: {
day: 'MMM DD'
}
}
}
],
My guess is that i should format the xMin/xMAx values accordingly to xaxis (daysjs stuff), tried something('Oct 31' or this.$dayjs.unix(timestamp)) but it doesn't work... i guess i am missing something
Chart.js uses timestamps defined as milliseconds since the epoch. Source
Use .valueOf() to get timestamp in milliseconds from dayjs. Source
xMin: dayjs(...).valueOf(),
xMax: dayjs(...).valueOf(),
I have an array of actual values, it should be just a line and an array of threshold values it should be the second line. When the actual value-line crossed through the threshold line the color of this part of the line should be changed.
var chart = c3.generate({
point: {
r: 5
},
data: {
x: 'x',
columns: [
['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04'],
['actual value', 230, 120, 300, 50],
['threshold', 130, 280, 100, 250],
],
type: 'spline',
regions: {
'threshold': [{'style': 'dashed'}]
},
},
axis: {
x: {
type: 'timeseries',
tick: {
format: '%Y-%m-%d'
}
}
}
});
I'm not sure how it is done in c3, but as you mentioned d3 in your question, you would use a threshold scale in d3.
See this example from blocks:
var colorThresholdScale = d3.scaleThreshold()
.domain([0.11, 0.22, 0.33, 0.50])
.range(["#fee5d9", "#fcae91", "#fb6a4a", "#de2d26", "#a50f15"]);
The range in a threshold scale always has one more value than the domain.
If the given value is less than the first value in the domain, then the first value in the range is output:
colorThresholdScale(0.02); // "#fee5d9"
If the input value is greater than the nth value in the domain, and less than the n + 1th value in the domain, then the n + 1th value in the range is output:
colorThresholdScale(0.25); // "#fb6a4a"
If the input value is greater than the last value in the domain, then the last value in the range is output:
colorThresholdScale(0.6); // "#a50f15"
I'm using HighChart and when the data is load, the ordinate of the charts display a 'k' after the number for the thousands but I would like do not display the 'k'.
Example : 1 500k -> 1 500.
If you want to change this for all charts, use lang.numericSymbols: https://jsfiddle.net/BlackLabel/t3hporya/
Snippet:
Highcharts.setOptions({
lang: {
numericSymbols: ['']
}
});
Highcharts.chart('container', {
series: [{
data: [0.029, 71.5, 1.06, 1292, 14400, 1.760, 135, 1480, 0.0216, 0.194, 9.56, 54.4]
}]
});
You can provide your own format using the format parameter
yAxis: { // can be xAxis too
labels: {
format: function() {
return value.substr(0, 1) + ' ' + value.substr(1);
}
}
}
I am using C3 bar charts now I am facing problem with X-Axis tick. I am taking value of X-Axis dynamically.
See below code:
chart = c3.generate({
bindto: '#port_range_to_port_range',
data: {
x: 'x',
columns: [
['x','Ho Chi Minh City', 'Tanjung Priok (Jakarta)', 'Chennai', 'Chennai', 'Chennai'],
['Your lowest rate', 530, 800, 900, 525, 190],
['Benchmark rate', 241, 890, 254, 100, 149],
['Lowest rate on route',200, 859, 256, 365, 410],
],
type: 'bar'
},
axis: {
x: {
type: 'category' // this needed to load string x value
},
y: {
tick: {
format: d3.format("$,")
}
}
},
legend: {
show: false
}
});
You can see the above I have used "Chennai" three times in X-axis. See below for more
columns: [
['x','Ho Chi Minh City', 'Tanjung Priok (Jakarta)', 'Chennai', 'Chennai', 'Chennai'],
So problem is, when graph will plot then these duplicate value is not displaying, This (Chennai) is displaying only one time and rest times its printing the numbers. See attached graph
As we figured out in comments above, since 0.4.11 c3.js starts to group same categories into one.
Fast workaround is either use previous version, or add extra spaces to category name to make them actually differ but stay visually identical:
columns: [['x',
'Ho Chi Minh City',
'Tanjung Priok (Jakarta)',
'Chennai',
'Chennai ', // <-- here
'Chennai ' // <-- and here
],
If you want to do it dynamically, more appropriate solution may be adding index to repeating categories:
columns: [['x', ... some dynamic data ]
.map(function(category, i, arr){
var prev = arr.slice(0, i);
var count = prev.reduce(function(sum, item) {
if (item === category) return sum + 1;
else return sum;
}, 0);
if (count != 0) return category + '-' + count;
else return category;
})
]
// will give you
// [['x', 'Ho Chi Minh City', 'Tanjung Priok (Jakarta)',
// 'Chennai', 'Chennai-1', 'Chennai-2']]
See updated fiddle
I used Morris.js to build the following chart:
http://jsbin.com/uqawig/441/embed?js,output
The xLabel have problems when I reduce the length down to 2 as:
Morris.Line({
element: 'line-example',
data: [
{ y: '2006', a: 100, b: 90 },
{ y: '2007', a: 75, b: 65 }
],
xkey: 'y',
ykeys: ['a', 'b'],
labels: ['Series A', 'Series B']
});
xLabel show as 2006-03 2006-05 2006-07 2006-09 2006-11 2007-01
I want xLabel to show only the years like 2006 2007.
I searched a lot but didn't found any solutions.
Any ideas?
Set the parseTime parameter to false in your Morris configuration:
parseTime: false
Reference: Morris Line & Area Charts
parseTime: Set to false to skip time/date parsing for X values, instead treating them as an equally-spaced series.