I'm using c3 chart for js. My code is below:
c3.generate({
bindto:'#someChart',
data: {
columns: [
data
]
},
axis: {
x : {
type: 'categories',
categories:categories,
tick:{
count: 12
}
}
},
point:{
show:false
}
});
I have one problem. On x axis is showed only first and last value(12th).
It's a known bug in c3 where if the tick is due to occur at a fractional x value (i.e. the number of ticks means it should pop up say every 2.06666 categories) then it doesn't render --> https://github.com/c3js/c3/issues/1638
There's a fix that's offered there to run before you generate your chart -->
c3.chart.internal.fn.categoryName = function (i) {
var config = this.config, categoryIndex = Math.ceil(i);
return i < config.axis_x_categories.length ? config.axis_x_categories[categoryIndex] : i;
};
But I find while it now shows the right number of ticks, it often still doesn't line up the labels and ticks nicely to the data points (they're positioned partway in between).
On that point, it's better, if you can, to set the number of ticks (-1) to divide without a fraction into the number of data points (-1) you're wanting to show and they'll both avoid your initial issue and line up nicely.
e.g. (datapoints - 1)/(no.of.ticks - 1) == whole number
Related
I am creating a chart.js line graph with -y-axis values up to almost a million. and the values on the y axis are
0
100000
200000
300000
400000 and so on. This can be tiresome to read and I want to change it for those numbers to strings that say 100k 200k 300k while still maintaining the same value as before just showing different values on the page.
Is this possible?
Thank You
Use this example from their documentation, instead of returning a dollar sign + value return: (value/1000 + 'K')
options: {
scales: {
yAxes: [{
ticks: {
// Include a K in the ticks
callback: function(value, index, values) {
return (Number.parseInt(value)/1000) + 'K';
}
}
}]
}
}
https://www.chartjs.org/docs/latest/axes/labelling.html#creating-custom-tick-formats
I am new to dygraph and I have one issue: while creating dygraph using Javascript negative values of the y-axis are displayed above the x-axis 0 value.
Here is my code :
g6 = new Dygraph(document.getElementById('smooth-line'),
functionData,
{
labels: ['Year', 'First','Second'],
series: {
First: {
plotter: smoothPlotter,
color: '#26a69a ',
strokeWidth: 2
},
Second: {
plotter: smoothPlotter,
color: '#e57373 ',
strokeWidth: 2
}
},
legend: 'always',
gridLineColor: '#ddd',
//valueRange: [1.0, 30.0],
//yRangePad :[-20.0,20.0]
});
}
and the output of this code is:
Output of the code
As in the image x-axis is below to -ve values of y-axis so how to set position of x-axis at the 0 value of y-axis?
First a comment. Posting examples that are not self-contained takes a lot longer to troubleshoot.
This link: http://jsfiddle.net/yLytg398/1/ provides a reasonable approximation to your code that can be tested.
You actually had the solution already in your code, valueRange is what you need. You can even use valueRange: [0, null] to automatically calculate the upper bound.
Correction: I just realized that you actually wanted to have the x axis with labels moved into the middle of the graph, my solution does not address this, but for your example picture it still works, because valueRange can set the lower end of the y range to zero, so that the x axis is at y = 0.
I have this now:
I need to draw graph of this function:
-3.6 * Math.exp(-3.5 * Math.pow(x, 2)) * Math.sign(Math.cos(31 * x - 7));
I decided to use HighchartJS. There are no problems with it, but I am not sure, that it is correct to approximate function (highchartJS does this).
You can find my results here, on jsFiddle.
You can see, that values of the graph are "jumping" with some amplitude, highchartJS approx it and I am getting continious line. Actually, graph of my function differs from this result. You can see that here, for example.
Also, you can see the result on image below:
Line is interrupting. The question is how I can get same result with highchartJS (or maybe I should use another library?) ?
If graph is not running on Chrome try this, please
Firs of all, you are using Math.sign method which is not part of official standards (just draft). Simply add your method to get working example in chrome:
Math.sign = function(x){
if( +x === x ) {
return (x === 0) ? x : (x > 0) ? 1 : -1;
}
return NaN;
}
Now, The problem is that Highcharts connects all points with lines. In your case better solution is to use scatter type - since you have enough points to display expected result: http://jsfiddle.net/q2kSf/22/
$('#container').highcharts({
series: [{
type: 'scatter',
name: 'Values',
data: data,
marker: {
radius: 2
}
}]
});
I'm creating a combochart with google's visualization library. I'm charting a store's traffic and revenue over the course of a day. I have set my draw options to
var options = {
seriesType: "bars",
series:{0:{targetAxisIndex:0},1:{targetAxisIndex:1}},
vAxes:{0:{title: "Revenue"},1:{title: "Traffic"}},
hAxis: {title: "Time", showTextEvery: 1},
};
which sets up the Revenue on a different Y-axis than the traffic. A sample of the data might look like this:
var data = [
// Time Revenue Traffic
['10:00-10:30', '132.57', '33'],
['10:30-11:00', '249.23', '42'],
['11:00-11:30', '376.84', '37'],
[... etc ..]
];
the problem I'm having is that Traffic values will always be positive whereas Revenue could be a negative number if there were returns. If that happens my Revenue axis will start at a negative value like -50 while Traffic starts at 0 and the horizontal baselines don't line up. I would like to have it so that even if Revenue has values less than 0 it's 0 axis will line up with the Traffic 0 axis.
Here's an example to show what's happening. See how the Traffic 0 axis is on the same level as the Revenue's -50 axis. I would like to know how to raise the Traffic baseline to the same level as the Revenue 0 axis.
I have a method that I am reasonably certain will always produce axis values with the same 0 point (I haven't proved that it can't produce axes with different 0 points, but I haven't encountered any).
To start off, get the range of the two date series (for our purposes, column 1 is "revenue" and column 2 is "traffic"):
var range1 = data.getColumnRange(1);
var range2 = data.getColumnRange(2);
For each series, get the max value of the series, or 1 if the max is less than or equal to 0. These values will be used as the upper bounds of the chart.
var maxValue1 = (range1.max <= 0) ? 1 : range1.max;
var maxValue2 = (range2.max <= 0) ? 1 : range2.max;
Then calculate a scalar value relating the two upper bounds:
var scalar = maxValue2 / maxValue1;
Now, calculate the lower bounds of the "revenue" series by taking the lower of range1.min and 0:
var minValue1 = Math.min(range1.min, 0);
then multiply that lower bound by the scalar value to get the lower bound of the "traffic" series:
var minValue2 = minValue1 * scalar;
Finally, set the vAxis minValue/maxValue options for each axis:
vAxes: {
0: {
maxValue: maxValue1,
minValue: minValue1,
title: 'Revenue'
},
1: {
maxValue: maxValue2,
minValue: minValue2,
title: 'Traffic'
}
}
The net result is that positive and negative proportions of each series are equal (maxValue1 / (maxValue1 - minValue1 == maxValue2 / (maxValue2 - minValue2 and minValue1 / (maxValue1 - minValue1 == minValue2 / (maxValue2 - minValue2), which means the chart axes should end up with the same positive and negative proportions, lining up the 0's on both sides.
Here's a jsfiddle with this working: http://jsfiddle.net/asgallant/hvJUC/. It should work for any data set, as long as the second data series has no negative values. I'm working on a version that will work with any data sets, but this should suffice for your use case.
I have a Google Chart with a continuous date-time X axis. My data comes in short bursts, with long delays between the bursts. I'd like to make the Chart have a non-continuous X axis, but still have the auto-generated timestamps during the samples. Is that possible?
Basically, say I have 3 samples, each which have 300 datapoints, recorded across 10 second intervals, but with hour gaps between them. I'd like to have my chart show the 30 seconds of data at a zoom level where it can be distinguished. Am I stuck?
Edit: Per #jmac's suggestion, here is an example of what the data looks like:
1360096658270, 10.228335
1360096658274, 10.308437
1360096658277, 10.294770
[...]
1360096673968, 9.014943
1360096673969, 8.971434
1360096673970, 9.041739
1360096673971, 9.097484
^^-- 15 seconds
<--- (~10 days)
1360989176509, 9.856928
1360989176513, 9.852907
1360989176517, 9.861740
1360989176523, 9.820416
1360989176527, 9.871401
Method 1: Multiple Charts
This is probably the simplest in concept (though still a hassle).
Summary:
Split data in to groups (eliminate the gaps)
Create a separate chart for each group
Eliminate the vAxis labels for every chart past the first
Create a consistent vAxis min/max value
Use CSS to line the charts up side to side
Details:
If you have a static data set, you can just split it by hand. If it isn't static, then you have to write some javascript to split up your data. I can't really help you here since I don't know how your data works.
As far as setting up the charts, I'll leave that up to you. I don't know how you want them formatted, so again I can't really help you with the current info.
To create a consistent axis value for all charts, you need to use some basic math in a javascript function to assign the same numbers to each vAxis max/min value. Here is a sample:
// Take the Max/Min of all data values in all graphs
var totalMax = 345;
var totalMin = -123;
// Figure out the largest number (positive or negative)
var biggestNumber = Math.max(Math.abs(totalMax),Math.abs(totalMin));
// Round to an exponent of 10 appropriate for the biggest number
var roundingExp = Math.floor(Math.log(biggestNumber) / Math.LN10);
var roundingDec = Math.pow(10,roundingExp);
// Round your max and min to the nearest exponent of 10
var newMax = Math.ceil(totalMax/roundingDec)*roundingDec;
var newMin = Math.floor(totalMin/roundingDec)*roundingDec;
// Determine the range of your values
var range = newMax - newMin;
// Define the number of gridlines (default 5)
var gridlines = 5;
// Determine an appropriate gap between gridlines
var interval = range / (gridlines - 1);
// Round that interval up to the exponent of 10
var newInterval = Math.ceil(interval/roundingDec)*roundingDec;
// Re-round your max and min to the new interval
var finalMax = Math.ceil(totalMax/newInterval)*newInterval;
var finalMin = Math.floor(totalMin/newInterval)*newInterval;
Method 2: Multiple Series
As long as the people viewing your data understand they are different sets, then there's no reason the axis needs to say the exact date/time as long as they can easily figure that out elsewhere.
Summary:
Separate your data in to different series for each 'sequence'
Artificially shorten the gaps between sequences (if they are 15 seconds each, then have a 5 second gap between series, or just start every 15 seconds)
Format each different series with a name labeling when the run started/ended
Details:
Again, you will have to split your data manually or create javascript to do it, but what you want to do is to move each set of numbers in to its own column, like so:
1360096658270, 10.228335, null
1360096658274, 10.308437, null
1360096658277, 10.294770, null
[...]
1360096673968, 9.014943, null
1360096673969, 8.971434, null
1360096673970, 9.041739, null
1360096673971, 9.097484, null
^^-- 15 seconds
<--- (~10 days)
1360989176509, null, 9.856928
1360989176513, null, 9.852907
1360989176517, null, 9.861740
1360989176523, null, 9.820416
1360989176527, null, 9.871401
This will make each series be a different color (and have a different label in the legend/on mouseover), so you can see the difference between runs, but also get a nice tooltip saying "This data was gathered from X to Y" so that if the time the data was taken is important, it's still in there (albeit not on the X axis).
These are the easiest ways.
Method 3: Manually Editing the X-Axis Labels
The third way is the most flexible but also takes the most work. You can create a custom javascript function to manipulate the X-axis labels in SVG. More details on this here by #jeffery_the_wind:
/*
*
* The following 2 functions are a little hacky, they have to be done after calling the "draw" function
* The bubble chart originally displays only numbers along the x and y axes instead of customer or product names
* These 2 functions replace those numbers with the words for the customers and products
*
*/
for ( var i = -2; i < products.length + 1; i ++ ){
$('#customer_product_grid svg text[text-anchor="start"]:contains("'+i+'")').text(function(j,t){
if (t == i){
if (i >= products.length || i < 0){
return " ";
}
return products[i];
}
});
}
for ( var i = -2; i <= customers.length + 3; i ++ ){
$('#customer_product_grid svg text[text-anchor="end"]:contains("'+i+'")').text(function(j,t){
if (i >= customers.length + 1 || i <= 0){
return " ";
}else if (t == i){
return customers[i-1];
}
});
}
Google's documentation on customizing axes describes how to do what you're asking. You can change the type of your column to a string and populate with formatted Date strings.