I use google's chart javascript api to show some data. The data contains "0" / "null" values.
//...
totalpt1.setValue(154, 2, 1310799);
totalpt1.setValue(155, 2, 1313905);
totalpt1.setValue(156, 2, null);
totalpt1.setValue(157, 2, 1320264);
totalpt1.setValue(158, 2, 1323102);
//...
var chart11 = new google.visualization.LineChart(document.getElementById('chart_totalpostthreads'));
chart11.draw(totalpt, {width: 600, height: 340, interpolateNulls:true, legend: 'bottom', title: 'Total Posts'});
The result is this:
I have set interpolateNulls to true. But the graph is still not "smoothed". How can I prevent those single drop outs? I thought this is what the interpolate option was for...
Null and 0 are different values.
You should use:
totalpt1.setValueNull(156, 2);
Related
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
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
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
},
The standard example of the rChartsCalendar works with defaults of the JS calendar as shown in http://kamisama.github.io/cal-heatmap/
The example code below works fine:
dat <- read.csv('http://t.co/mN2RgcyQFc')[,c('date', 'pts')]
library(rChartsCalendar)
r1 <- plotCalMap(x = 'date', y = 'pts',
data = dat,
domain = 'month',
start = "2012-10-27",
legend = seq(10, 50, 10),
itemName = 'point',
range = 7
)
The problem comes when I try to set nested attributes in R, for example to define the position and the offset of the label. In HTML / JS it would be as easy as writing following code, but how can I define from R the values for the offset for the label?
var cal = new CalHeatMap();
cal.init({
itemSelector: "#label-d",
domain: "day",
range: 2,
displayLegend: false,
label: {
position: "right",
width: 46,
offset: {x: 10, y: 30}
}
});
I tried using the method set and passing the json piece as string, but then it gets rendered with the quotes in HTML/JS, which obviously doesn't work
r1$set(label="{position: 'left', width: 110, offset: { x: 20, y: 12 } }")
Update: I got it working using a combination of "c" and "list" as follows:
label= c( list(position = 'left'),list( width = 110),list(offset = list (x=20,y=30))),
It's not very straight away, but I felt like sharing it because it took me a lot of time
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.