Code
Example of my problem: http://jsfiddle.net/x46RQ/
Goal
I want the graph to be a bar graph like so: http://jsfiddle.net/Lbd85/ but obviously with dates as the x axis. If I add my data into that fiddle, it messes up like the one listed above as seen here: http://jsfiddle.net/73G7Z/
Questions
Why are all 3 days provided in the data variable not displaying?
Why are the bars not lined up with their appropriate x-axis ticks?
Why does changing the data and mode to time totally mess up what would otherwise be a functional and accurate bar graph?
Environment
jQuery 1.7.1
jQuery Mobile 1.0.1
Flot 0.7
Thanks
Let me know if any additional information is required.
Part #1, You specified a min y value of 0 in your flot options, and your data point #2 has a value of zero. So it's there but just very small, almost invisible.
Part #2, you have to offset your dates by the users timezone:
Something like this:
var tzOffset = new Date();
tzOffset = tzOffset.getTimezoneOffset()*60*1000;
data.push([(new Date("2012/02/20").getTime()-tzOffset), 1]);
Part #3, Your graph is a mess because you specified a width when in fact the option you were looking for is barWidth and you need to specify the width in terms of time, i.e. milliseconds. See here for how. Something like barWidth: 12*60*60*1000 looks OK.
So in summary, this is what it will look like: http://jsfiddle.net/ncTd3/
Related
I am having problems controlling the Y-Axis range of a highcharts graph. It seems like highcharts likes nice round numbers. When my data passes or is close to certain thresholds, the Y-Axis range can expand a lot which effectively compresses all the plot points downward.
Here is a jsfiddle that illustrates the problem I am having:
https://jsfiddle.net/shannonwrege/z8h5eork
The relevant code for this post is this:
chart.yAxis[0].setExtremes(0, max, true, false);
Keep in mind that I don't know what the data will look like in advance, so I must dynamically modify the Y-Axis range. Right now I am using the setExtremes because of other suggestions I've read on stackoverflow.
The maximum y-value of the data in the first two charts is 99. You'll notice that the y-axis is set at 150 in the first chart where the range is automatically calculated and 100 in the second chart where I specifically set the extreme values. The look of the 2nd chart is what I want. So it seems like setExtremes(0,99,true,false) should do the trick, but it actually doesn't.
In the 3rd chart I changed the data so that the maximum y-value of the data is 101, and I called setExtremes(0,101,true,false). You'll note that the y-axis is now back to 150.
Ideally I want the scale of the graph to be capped on the maximum value to limit the about of extra white space. I want to see all of the data, but I don't necessarily care about the y-axis displaying a maximum band that is greater than the max data value. In this case, I would be happy with the y-axis displaying 100 on the axis and some points over but still visible.
Does anyone know how to make this work?
I ended up using the endOnTick parameter to solve this problem. Adding the following line to the yAxis configuration parameters did exactly what I wanted:
endOnTick: false,
Here's the updated Fiddle showing the results.
https://jsfiddle.net/shannonwrege/z8h5eork/3/
All of the charts look pretty good in my opinion (even the one where the yAxis range was auto calculated).
You will need to read the data and then round up to set the idealMax
var chart,
idealMax = 0; // init the max value
// Read the data to find the highest value
for (i=0;i < (options.series[0].data).length; i++ ){
if (options.series[0].data[i][1] > idealMax) {
idealMax = options.series[0].data[i][1];
}
}
// Round the max to the nearest 10
idealMax = Math.round(idealMax / 10) * 10;
options.yAxis.tickPixelInterval = idealMax/10;
Highcharts.chart('container1', options);
chart = $('#container1').highcharts();
chart.yAxis[0].setExtremes(0, idealMax, true, false);
Updated Fiddle
I've run into a problem using ChartJS 2.2.1 when I tried to build timeline chart (line chart + time option).
Approach 1: Wrong animation
I request new value from server ( in format [time,value] ) every 5 seconds and I want only 10 points on screen, so, when new data come in, I:
remove oldest point from chart
add new point
The problem here is animation - chart not shifts to the left - it's just redraws on the same place.
Approach 2: Bad at all
My solution to get this 'shift' animation is add data to chart, moving min and max time values to keep only 10 values on screen (without removing it):
line_chart.chart.config.data.datasets[0].data.push({x: moment.utc(time).toDate(), y: value});
line_chart.update();
line_chart.config.options.scales.xAxes[0].time.min = line_chart.chart.config.data.datasets[0].data[line_chart.chart.config.data.datasets[0].data.length - onscreen_points].x;
line_chart.config.options.scales.xAxes[0].time.max = moment.utc(time).toDate();
I guess that's not the best idea and I've already had some troubles with this approach.
Is here any other solution?
P.S. In ChartJS 1.0 this 'shift' animation works well with first approach.
Is there any workaround to have tickMarkPlacement set as "between" on a datetime Axis? I am aware is not supported by the API but I was hoping to find some sort of hack/plugin.
You can fudge it with the x axis label's x property.
Example:
http://jsfiddle.net/jlbriggs/3qtZr/36/
[[update after comments:
if you mean that you want the data points to also line up 'between', then there isn't a good easy way.
My approach would be
1) make sure there is only one data point per axis tick, ideally
2) adjust the x value of the data point to push it to the right in a way that corresponds with the label offset
3) adjust tooltip formatters to correct the date for display
or, 4) just go with categories
However, if you can explain why you want to do this, what effect you're going for, perhaps there's more that can be done.
{{further updates:
After playing around a little more, I found another way to fudge the data point placement, though I am unclear whether you need that.
Example here:
http://jsfiddle.net/jlbriggs/3qtZr/39/
It uses the pointPlacement property.
The catch is that the pointPlacement property doesn't work if there is not a columns series present with as many data points as the line series, it seems.
So this method adds and hidden dummy column series in order to make the pointPlacement property affect the line series.
Not elegant, but it beats having to adjust the data values and then re-adjust them in the formatter.
I have a set of data for dates. What value should I provide the X axis values? How do I make Rickshaw display the X data values as dates?
I looked around the docs and examples and cannot find anything.
I've just started using Rickshaw and was in the exact situation.
But, before I go any further, Rickshaw documentation is virtually nonexistent which is very upsetting because the performance of Rickshaw compared to other JS graphing libraries is outstanding.
The best way to find examples is to dig into the source code and example code on their github page try to make sense of things (not the way documentation should be).
That being said, let's try and build a strong base of questions/answers here on StackOverflow!
So, back to the question :) It looks like you've already found your own solution to the question, but I'll provide my solution as well.
Rather than using Rickshaw.Graph.Axis.Time, I've used Rickshaw.Graph.Axis.X and set the tickFormat accordingly.
var data = [ { x: TIME_SINCE_EPOCH_IN_SECONDS, y: VALUE },
{ x: NEXT_TIME_SINCE_EPOCH_IN_SECONDS, y: NEXT_VALUE } ]
var xAxis = new Rickshaw.Graph.Axis.X({
graph: graph,
tickFormat: function(x){
return new Date(x * 1000).toLocaleTimeString();
}
})
xAxis.render();
toLocaleTimeString() can be any of the Javascript date functions, such as toLocaleString(), toLocaleDateString(), toTimeString(), or toUTCString(). Obviously, because the tickFormat takes a function as an argument one can supply their own formatter.
Koliber, I'd be interested to understand your answer if you could provide more detail as well.
Additional to Lars' reply, I found by default Rickshaw is calling
.toUTCString(x.value*1000) //(just ctrl+F to find where =) ).
In my case, I saw different time label on X between Graphite and Rickshaw for this reason, and it works beautifully once I changed it to
.toLocaleString(x.value*1000).
Plus, you may need modify this in two places : Rickshaw.Graph.Axis.Time and the ...HoverDetails
I have finally figured out that the X axis values should be epoch time values. Then, using the code from the examples I was able to show a proper time scale.
I still have a problem because I would like to show the tick marks on weeks on the X axis. However, setting timeUnit to 'week' causes JavaScript errors. It works with other time units though.
None of this worked for me. What worked with angularjs was:
'x' : d3.time.format.iso.parse(date).getTime(), 'y' : 10
I've searched in the official d3.js documentation, as well as, here in stackoverflow to find a way to add custom tickValues to a time scale axis; However, i haven't stumble across any documentation that confirms that something like that is possible.
So in essence, i have a time scale axis and i would like to show specific hours
e.g. i'd like to do something like this :
xHourAxis
.ticks(d3.time.hours, 2)
.tickFormat(d3.time.format('%I %p'))
.tickValues(2, 4, 6, 8, 10, 12) ;
So i want to display tick values every 2 hours, but not including the first (12 am) and the last (12 pm).
Does anyone know if there is any workaround for that?
Nearly there, but your code has two problems: First the tick values must be specified in an array, and second those values should be Javascript date objects. i.e. you just provide an array of dates to tickValues so your code would looks something like this:
xHourAxis
.tickFormat(d3.time.format('%I %p'))
.tickValues([new Date(2000,10,5), new Date(2005,2,7), new Date(2007,11,11)]);
Also, note that you needn't call the ticks() if you are going to later specify custom values.