how to make the vAxis and hAxis number in integer - javascript

Here is my code:
var rawdata='".$performances."';
var mydata=jQuery.parseJSON(rawdata);
if(mydata){
var realData=[];
realData=[
['Activities', 'Performance'],
];
for (x in mydata)
{
var a=parseFloat(mydata[x]['activities']);
var b=parseFloat(mydata[x]['performance']);
realData[x]=[a,b];
}
var data = google.visualization.arrayToDataTable(realData);
var options = {
title: 'Overall Performance',
legend: { position: 'top', maxLines: 3 },
hAxis: {title: 'Activities'},
vAxis: {title: 'Performance'}
};
var chart = new google.visualization.LineChart(document.getElementById('chart_div_line'));
chart.draw(data, options);
And the output is:
I want to change the current x axis value to be integer: 1,2,3,4,...., how can I do it?
Thanks in advance.

There are a couple different approaches you can take to fix this. The first is to set the axis range and gridline count so that the chart defaults to showing integer values, eg:
vAxis: {
viewWindow: {
min: 0,
max: 2
},
gridlines: {
count: 3
}
}
Generally, if min and max are integers and (max - min) / (count - 1) is an integer, then the gridlines (and hence axis labels) will fall on integer values. This approach works best with the y-axis when you know the range of valid values for your chart; you can use it for the x-axis too, but I don't see it used very often.
The other approach is to use the h/vAxis.ticks option to specify the locations of gridlines and labels. The ticks option takes an array of values or objects. Values specify the location of a gridline. Objects have v and f properties; the v property specifies the location of the gridline and the f property specifies the label to use. Any values or objects without a specified f property will generate an axis label according to the axis format option.
hAxis: {
ticks: [1, 2, 3, 4]
}
or:
hAxis: {
ticks: [{v: 1, f: 'one'}, {v: 2, f: 'two'}, {v: 3, f: 'three'}, {v: 4, f: 'four'}]
}
You can mix and match objects and values in the array however you like. This approach works equally well with both the x and y axes.
You can take one approach with one axis and the other approach with the other axis, but if you mix them on the same axis, be aware that the ticks option overrides gridlines.count, and if you place a tick mark outside the range of the viewWindow settings, you will not see it.

Try:
var a=parseFloat(mydata[x]['activities'].toFixed());
var b=parseFloat(mydata[x]['performance'].toFixed());
toFixed() will convert your number to a string; you are using parseFloat(), so the string would be converted back to a number.

Related

Reversed bullet chart in Highcharts

I started working with highcharts. Now a problem I am facing is that the bulletcharts can’t be used for a dataset that is in descending order.
For example say we want to plot the ranking of a few companies. In this case the ranking is better the lower it gets. So a Rank 10 is better than a Rank 15 and so on.
In this case I want my graph to get reversed. The target would be lets say 10. The min value would start from say 100 to 0. So you can see how this isnt possible.
P.S: I know the
reverse: true/false
property. But that simply flips the graph and I don’t want that/need that.
Thanks world.
You can add a second y-axis with the same extremes as the first one, but reversed. Next, hide the first y-axis, calculate mocked y and target values and finally, set a custom formatter function for tooltip to show original values.
const MAX = 300;
const TARGET = 50;
const Y = 25;
Highcharts.chart('container1', {
chart: {
inverted: true,
type: 'bullet',
},
yAxis: [{
visible: false,
min: 0,
max: MAX
}, {
min: 0,
max: MAX,
reversed: true,
...
}],
tooltip: {
formatter: function(tooltip) {
const point = this.point;
return `<span style='color: ${this.color}'>●</span> ${this.series.name}: <b>${point.originalY}</b>. Target: <b>${point.originalTarget}</b><br/>`
}
},
series: [{
data: [{
y: MAX - Y,
target: MAX - TARGET,
originalY: Y,
originalTarget: TARGET
}]
}]
});
Live demo: https://jsfiddle.net/BlackLabel/ve8hosd3/
API Reference: https://api.highcharts.com/highcharts/tooltip.formatter

Highcharts with custom scaling in upper regions

I would like to know how to achieve a custom scale for a chart in Highcharts. I want to display a boxplot which has very high whiskers. The normal values to display are between 500 and 1000 but there are some anomalies which are about 6000 on y-axis. This is causing the whole chart to be squeezed and the scaling is so small that you can't determine the boxplots correctly. I would like to increase the tick-size between 1000 and 6000 to decrease the heigt of the chart.
Highcharts provides breaks functionality that seems to be ideal for your case: https://api.highcharts.com/highcharts/yAxis.breaks
Another approach is to change the yAxis type to logarithmic: https://api.highcharts.com/highcharts/yAxis.type
EDIT
The discussion in the comments section reveals that the OP needs rather custom y axis formatting than breaks functionality.
Here's how to approach this issue:
The problem here is that axes in Highcharts can only have either constant or logarythmic scales. Your example shows irregular scale - the values are not in constant or logarythmic order ([0, 3, 10, 30, 150]).
Here's what I've done to mimic that kind of look and behaviour:
I set tickPositions to [0, 1, 2, 3, 4] - these are the actual values that appear on the chart. As you can see the distance between all these numbers is constant: 1.
Then I used formatter to display corresponding number from ranges array for each label.
yAxis: {
tickPositions: [0, 1, 2, 3, 4],
labels: {
formatter: function() {
return ranges[this.pos];
}
}
},
Before I passed the data to the chart constructor I converted all the values so that they're between 0 and 4:
series: [{
data: [2, 120].map(function(val) {
var range = findRange(val);
var y = range.index + (val - range.low) / (range.high - range.low);
return {
y: y,
originalValue: val
};
})
}]
Finally I used originalValue property in tooltip.format string to print to the user the number before the conversion.
tooltip: {
pointFormat: "<span style='color:{point.color}'>\u25CF</span> {series.name}: <b>{point.originalValue}</b><br/>"
},
This example is simplified to the line series case but can be easily adjusted to boxplot series. The code serves only for the example purposes and should be improved - it's easy to cause an error within it.
Live working demo: https://jsfiddle.net/kkulig/ytjz1jej/
API references:
https://api.highcharts.com/highcharts/tooltip.pointFormat
https://api.highcharts.com/highcharts/yAxis.tickPositions
https://api.highcharts.com/highcharts/xAxis.labels.formatter

C3 Bar Graph x-axis labels are too congested

I have created a Bar graph using C3 JS plugin, The graph is working fine but the problem is with the x-axis labels looks too congested like as shown below
Working JSFiddle
My Code is as given below
var chart = c3.generate({
bindto: "#chart",
data: {
x : 'x',
columns: [
['x', "2016-04-01","2016-04-08","2016-04-15","2016-04-22","2016-04-29","2016-05-06","2016-05-13","2016-05-20","2016-05-27","2016-06-03","2016-06-10","2016-06-17","2016-06-24","2016-07-09","2016-07-10","2016-07-11","2016-07-12","2016-07-13","2016-07-15","2016-07-16","2016-07-17","2016-07-18","2016-07-19","2016-07-20","2016-07-21","2016-07-22","2016-07-23","2016-07-24","2016-07-25","2016-07-26","2016-07-27","2016-07-28","2016-07-29","2016-07-30","2016-07-31","2016-08-01","2016-08-02","2016-08-03","2016-08-04","2016-08-05","2016-08-06","2016-08-07","2016-08-08","2016-08-09","2016-08-10","2016-08-11","2016-08-12","2016-08-13","2016-08-14","2016-08-15","2016-08-16","2016-08-17","2016-08-18","2016-08-19","2016-08-20","2016-08-21","2016-08-22","2016-08-23","2016-08-24","2016-08-25","2016-08-26","2016-08-27","2016-08-28","2016-08-29","2016-08-30","2016-08-31","2016-09-01","2016-09-02","2016-09-03","2016-09-04","2016-09-05","2016-09-06","2016-09-07","2016-09-08","2016-09-09","2016-09-10","2016-09-11","2016-09-12","2016-09-13","2016-09-14","2016-09-15","2016-09-16","2016-09-17","2016-09-18","2016-09-19","2016-09-20","2016-09-21","2016-09-22","2016-09-23","2016-09-24","2016-09-25","2016-09-26","2016-09-27","2016-09-28","2016-09-29","2016-09-30","2016-10-01","2016-10-02","2016-10-03","2016-10-04","2016-10-05","2016-10-06","2016-10-07","2016-10-08","2016-10-09","2016-10-10","2016-10-11","2016-10-12","2016-10-13","2016-10-14","2016-10-15","2016-10-16","2016-10-17","2016-10-18","2016-10-19","2016-10-20","2016-10-21","2016-10-22","2016-10-23","2016-10-24","2016-10-25","2016-10-26","2016-10-27","2016-10-28","2016-10-29","2016-10-30","2016-10-31","2016-11-01","2016-11-02","2016-11-03","2016-11-04","2016-11-09"],
['pv1', 2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2748,2748,2694,2694,2694,2694,2694,2694,2694,2668,2668,2668,2668,2576,2572,2572,3043,3084,3084,3084,3084,3084,3156,3521,3521,3550,3542,3542,3573,3580,3629,3579,3584,3542,2757,2791,2696,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3414,3414,3414,3414,3414,3414,3414,3414,3414,3414,3414,3414,3414,3369,3376,3371,3373,3371,3379,3363,3373,3347,3348,3382,3402,3410,3434,2579,2579,2369],
['pv2', 1750,1750,1750,1750,1825,1850,1975,2150,2375,2425,2475,2500,2500,2087,2087,2087,2087,2091,2087,1767,1767,1767,1633,1498,1498,1642,1637,1633,1609,1841,1713,1702,1862,1888,1888,1888,1949,1976,1977,2014,2014,2014,1946,1966,1973,2224,2252,2318,2318,2318,2327,2373,2513,2535,2543,2534,2539,2823,2849,2990,3142,3142,3108,2513,2687,2678,2856,2860,2861,2862,2866,2869,2870,2875,2874,2874,2874,2879,2885,2886,2883,2889,2896,2895,2899,2903,2909,2911,2913,2913,2913,2916,2922,2933,2937,2943,2942,2943,2947,1811,1826,1837,1840,1840,1841,1843,1511,1854,1853,1851,1852,1853,1849,1852,1874,1857,1883,1886,1888,1904,1903,1924,1947,2060,2068,2068,2082,1582,1344,836,839,788]
],
type: 'bar'
},
axis: {
x: {
type: 'category',
tick: {
rotate: -60,
multiline: false
},
height: 130
}
}
});
Can anyone please tell me some solution for this
What I did to solve it
I have used timeseries type instead of category type, after that the label issue got resolved but the graph was been plottted with more white spaces for the month of march like as shown below
Working JSFiddle
You can use c3's tick count setting for this, so here we say 20 labels.
However there is an added gotcha in that ticks that now resolve to a fractional category value won't show - i.e. the 2nd equally spaced tick out of 20 may be the 2.6667th element in the x category axis - so you need to have a little format function that adjusts for this, otherwise you just get the end and start labels. (Or you could figure out a tick count that divides into your data count + 1 as a whole number.)
tick: {
format: function (x) {
var cats = this.api.categories();
return cats[Math.round(x)];
},
count: 20,
rotate: -60,
multiline: false
},
http://jsfiddle.net/fz0t10yb/7/
One of the possible solution could be to use x-axis labels at required indexes only & leaving others blank.
['x', "2016-04-01","","","","2016-04-29","","","",...]
['pv1', 2500,2500,2500,2500,2500,2500,2500,2500,...]
['pv2', 1750,1750,1750,1750,1825,1850,1975,2150,...]
You can position labels so that it would capture the date and at same time it looks good also.

Google Visualisation - column chart interval issue (duplicate intervals)

I'm using the following code to generate the above google chart:
var data = google.visualization.arrayToDataTable([
['Date', 'Tickets'],
['11/05/15',1],
['10/05/15',0],
['09/05/15',0],
['08/05/15',0],
['07/05/15',0],
['06/05/15',0],
['05/05/15',0],
['04/05/15',0],
]);
var columnChartOptions = {
title: "",
legend: { position: 'none' },
width: '100%',
height: '100%',
colors: ["#27ae60", "#2980b9", "#e67e22", "#e74c3c", "#e74c3c"],
chartArea: { left: '8%', top: '8%', width: "85%", height: "70%" },
vAxis: {
minValue: 1,
format:'#'
},
new google.visualization.ColumnChart(document.getElementById('ticket-history-graph')).
draw(data,columnChartOptions);
However it produces the following wrong interval counts:
What changes do I need to make to the vAxis definition to correct this? I've tried varying min and max values to no avail. I must also add that when higher numbers are used this is not a problem, it's only with lower counts.
Your problem is the format:'#', which is the reason why you get two zeros and three ones (as you round to zero decimals, and the graph tries to present the values [0, 0.25, 0.5, 0.75, 1] which are rounded to [0, 0, 1, 1, 1], therefore duplicates them).
My suggestion is that you check out the property vAxis.gridlines.count documentation.
I made a fiddle, where I check if the maxValue in the graph is 1 or 2, if so I specify the gridlines to either the count of 2 or 3, and if it's neither 1 or 2, it uses googles own automatic generation.
Check and see if you follow how I've done: jsfiddle
Remember to try and change some values to higher/lower to see how it works.
//Get all distinct ticketsales, sorted ascending by default, so you have to get the last value to get the highest one.
var maxValue = data.getDistinctValues(1)[data.getDistinctValues(1).length - 1]
// Specify gridCount to null, so if it doesn't enter any of the if's below, it will still be null
var gridCount = null
//check if the highest value is 1 or 2 else leave gridCount to null
if (maxValue == 1) {
gridCount = 2
}
if (maxValue == 2) {
gridCount = 3
}
Aswell as the addition to the columnChartOptions:
vAxis: {
gridlines: {
//specify the amount of gridlines to var gridCount, if it's still specified as null, it will use googles automatic generation.
count: gridCount
},

How to show only integers (no decimals) in chart API x/y-axis labels

I'm using a column chart with the Google Chart JS Api. I'm displaying some values (total orders by day) that can only be represented as integers.
Everything is working great, except that when one of the charts I'm displaying has values that are too low, like 1 or 2, it starts to show decimals on the y-axis. The decimals look silly b/c it's impossible to have "half" an order (which is what I'm counting), and I'd like to hide this if possible.
use the option
vAxis: {format: '0'}
as in
chart.draw(data, {
width: 800,
height: 480,
orientation: 'horizontal',
vAxis: {format: '0'}
}
);
I don't have enough rep to reply to Ian Hunter's post directly, but what that does is format the label, but doesn't set the grid lines to the same value as the label, which can have undesirable results. So let's say you have these grid lines:
10
7.5
5
2.5
0
When you format the label to only show integers it shows this:
10
8
5
3
0
But then your data on the graph doesn't tie-in with the y-scale labels. E.g If you have a value of 3 it actually shows above the '3' labels because the '3' label is actually 2.5
Unfortunately, the only solution I could think of was to monitor the min/max ranges of the data shown in the graph, and then apply some logic to set the min/max according to how many y-scale labels I have, such that they would divide with no remainders.
So in the case above, I'd set it to
vAxis: {
viewWindow:{
max:12,
min:0
}
}
This would give grid lines of
12
8
6
4
0
No decimals, and no problems with the data not correlating with the labels on the graph.
Adding {format : 0} converts the float ticks to integers but the actual values on the bars appear incorrectly.
The main issue is Google Charts API assumes you want 5 gridlines mostly which may not work out to give you integer tick values.
Adding this gave me nice round tick values -
gridlines: { count: -1}
source - https://groups.google.com/forum/#!topic/google-visualization-api/4qCeUgE-OmU
if you want only the integer values to be shown, you should take to account that google charts wants to show you at least 5 gridlines. Presuming all of them should be integer give the graph following:
vAxis: { title: 'Orders Count',
minValue: 4,
viewWindow:{min:0}, /*this also makes 0 = min value*/
format: '0',
},
The easiest way is to edit the left vertical axis, with Min as 0, and Max as a multiple of 5 (5, 10, 15 etc) as appropriate to your expected maximum.
This issue will be resolved if you use vAxis: {gridlines: { count: 4}}
In my case I have values ranging from 0 to 600.
if $value is smaller than 12: use the max value for vAxis.gridlines.count
if $value is greater than 12: use the default nr of gridlines (4)
In this way you only display 'whole numbers'.
You'll need to dynamically generate the javascript off course.
Code Example:
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Fase', 'Closed', 'Open'],
<?php
$max = 0; // needed to determine the number of gridlines?
$data = array();
foreach($projectExecutions as $key => $pe){
$totals = countOpenIssuesInProjectExecution($pe);
$open = $totals['open'];
$closed = $totals['closed'];
$data[] = "['". $FASE[$pe['fase_id']] . "', " . $closed . ", ". $open . "]\r\n";
// What are the Max values vor Open & Closed Defects
if($open > $max ){ $max = $open; }
if($closed > $max ){ $max = $closed; }
}
$nrOfGridLines = ($max >= 12 ? 4 : $max+1); // Calculate the number of gridlines
echo implode(",",$data);
?>
]);
var options = {
legend: { position: 'bottom' }
,title: "Evolution Defects: Open -VS- Closed"
,colors:['#00a160','red']
,isStacked: true
,vAxis: {textPosition: 'in', minValue:0,viewWindow: { min: 0 }, gridlines: {count: <?php echo $nrOfGridLines; ?>} }
};
var chart = new google.visualization.AreaChart(document.getElementById('chart_defects'));
chart.draw(data, options);
}
I'm using the following code:
google.charts.setOnLoadCallback(function(){
var data = new google.visualization.DataTable();
data.addColumn('string', 'Y');
data.addColumn('number', 'X');
var max = 0; //Or something like Int.MinValue
for (var i = 0;i< arr.length;i++) {
max = (arr[i]>max)? arr[i]:max; //calculate max value
data.addRow("<<some calculation>>");
}
var options = {
height: 300,
vAxis: {
gridlines: { count: max+1}, //+1 is importent for the origingridline
viewWindow:{
min: 0,
max: max
},
}
};
var chart = new google.visualization.ColumnChart(document.getElementById("<< div_id >>"));
chart.draw(data, options);
}
Just calculate your maximum value and then set gridlines.count to this value
I'm using the Guava Multiset as my data. Cagy79's trick is the only one that I was able to get working. I also tried generating my own lines using an IntStream, but still had fractional numbers for some of the graphs. As mentioned above, just setting the format will create a graph where the hover over value and the gridline differ.
Multiset items = TreeMultiset.create();
Items added using .add and .addAll
Make sure the items are sorted:
occurrences = Multisets.copyHighestCountFirst(items);
String option = "hAxis : { title : 'Count', gridlines : { count:" +
((max >=12) ? 4 : max+1)
+ } }")
I prefer the gridlines: { count: -1 } option, but you can always explicitly specify the values you want with ticks. Cool thing about this is they don't even have to be evenly spaced - you could do [1, 10, 100, 200, 500, 1000] if you wanted:
options: { vAxis: { ticks: [1,2,3,4,5,6,7,8,9,10] } }
Depending upon your data you may want to hardcode this or use thresholds.
For anyone that are also searching for the answer, you can see the answer to this question here, which use options format.
Can't get Google Charts Axis to format in decimal

Categories

Resources