Related
I am working with a sample here:
var startDate = new Date(Date.UTC(2016, 6, 28, 0, 0, 0, 0));
var endDate = new Date(Date.UTC(2016, 6, 28, 0, 0, 0, 0));
endDate.setHours(startDate.getHours() + 9);
var dataSet = [{"data":[[1469664000000,0]],"color":"#FF0700"},
{"data":[[1469667600000,0]],"color":"#FF0700"},
{"data":[[1469671200000,0]],"color":"#FF0700"},
{"data":[[1469674800000,0]],"color":"#FF0700"},
{"data":[[1469678400000,0]],"color":"#FF0700"},
{"data":[[1469682000000,0]],"color":"#FF0700"},
{"data":[[1469685600000,0]],"color":"#FF0700"},
{"data":[[1469689200000,0]],"color":"#FF7400"},
{"data":[[1469692800000,0]],"color":"#006900"}];
var options = {
series: {
stack: true,
bars: {
show: true
}
},
bars: {
lineWidth: 0,
align: "center",
barWidth: 1,
horizontal: true,
fill: 1,
},
yaxis: {
axisLabel: "MachineName",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 3,
ticks: []
},
xaxis: {
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 3,
//ticks: [[0, "1:00"], [1, "2:00"], [2, "3:00"], [3, "4:00"], [4, "5:00"], [5, "6:00"], [6, "7:00"], [7, "8:00"], [8, "9:00"]],
//labelWidth: 10,
//tickLength: 10,
//tickFormatter: formatXAxis,
//tickSize: 360000,
//minTickSize: 1,
//min: 0,
//max: 10
//mode: "time",
//timeformat: "%H:%M",
//minTickSize: [1, "hour"],
////color: "black",
//min: startDate.getTime(),
//max: endDate.getTime()
}
};
$.plot($("#machineStatus"), dataset, options);
I end up with a graph where the xaxis labels are not anything like they should be. See below
The design is an hourly status of a machine (red = not running, green = running, etc.) So the intent was to have the last 9 hours of runtime showing and put x axis labels for the top of the hour (1:00, 2:00, etc.).
Since this is a horizontal stack of multiple data sets, this appears to really confuse the xaxis tick calculation. I tried setting the min/max to equal the start and end times of the dataset, but I would get no graph.
I stopped using the "time" mode, hoping I could use the ticks array and force a set of ticks and labels, but that doesn't work. I tried the tickFormatter to force calculating the ticks, but that didn't work either.
You can see all the things I've tried on the xaxis and have commented out. I actually don't want the ticks to have any relationship to the actual data. I am testing this graph at the hour and minute level, so theoretically my data sets are either 9 or 540 bits of granular information. I still want the xaxis ticks to stay at a fixed set of 9 values spread evenly. Any ideas how I can do that?
FYI, I apologize for no jsfiddle. I've never been able to get one to work.
Update. Selected answer works! Here's a screenshot of a 540 datapoint to the minute level. The dataset is too big to post. Thanks again Raidri
I got it to work with time mode and a vertical bar chart:
Relevant options:
series: {
stack: true,
bars: {
lineWidth: 0,
align: "left",
barWidth: 3600000,
//horizontal: true,
fill: 1,
show: true,
}
},
...
xaxis: {
min: startDate.valueOf(),
max: endDate.valueOf(),
mode: "time",
timeformat: "%H:%M",
...
Also the values for your datapoints are changed to 1 so the bars here have a height of one.
If you change it to minute values, you have to change the barWidth option accordingly.
See this fiddle for the full example.
I'm using AmCharts to display a chart. It's a floating bar chart displaying sent out surveys to a user. The bars are representing the openFrom to openUntil time, the time window a user has to submit the survey. They're listed in a timeline. I want AmCharts to understand the x-axis has dates as datatype so I can leverage the date functions (relative spacing, showing change of year bold, scrolling in time etc)
The following data is used to plot the chart as seen in the screenshots:
[{
"survey":"Survey DEF",
"openFrom":"05-04-2016",
"openUntil":"04-05-2016",
"status":"Nog niet geopend.", // translates to Not opened yet
"color":"#ededed"
},{
"survey":"Survey DEF",
"openFrom":"01-01-2016",
"openUntil":"31-01-2016",
"status":"Nog niet geopend.",
"color":"#ededed"
},{
"survey":"Survey GHI",
"openFrom":"06-12-2015",
"openUntil":"31-12-2015",
"status":"Ingestuurd op 07-12-2015", // Translates to Submitted at 07-12-2015
"color":"#27ae60"
},{
"survey":"Survey ABC",
"openFrom":"01-12-2015",
"openUntil":"15-12-2015",
"status":"Geopend, nog geen reactie.", // Translates to Opened, not submitted yet
"color":"#e67e22"
},{
"survey":"Survey GHI",
"openFrom":"31-01-2015",
"openUntil":"05-05-2015",
"status":"Geen reactie ontvangen", // Translates to Not submitted
"color":"#c0392b"
}]
Using this code:
var chart = AmCharts.makeChart('chart-container', {
'type': 'serial',
'dataLoader': {
'url': urlToJSONFetchScript
},
'language': 'nl',
'categoryAxis': {
'position': 'right',
'axisAlpha': 0.2,
'gridAlpha': 0.05
},
'valueAxes': [{
'type': 'date',
'minimumDate': '31-01-2015',
'maximumDate': '04-05-2016',
'axisAlpha': 0.2,
'gridAlpha': 0.05
}],
'categoryField': 'survey',
'graphs': [{
'balloonText': '<div style="text-align: left"><strong>[[survey]]</strong><small><br/>[[openFrom]] - [[openUntil]]<br/>[[status]]</small></div>',
'type': 'column',
'dateFormat': 'DD-MM-YYYY',
'openField': 'openFrom',
'valueField': 'openUntil',
'colorField': 'color',
'lineColorField': 'color',
'fillAlphas': 0.65,
'lineAlpha': 0.95
}],
'rotate': true,
'dataDateFormat': 'DD-MM-YYYY'
});
It get's me this chart:
This all looks good, but I'd like to use parseDates zo the x-axis doesn't have string-labels, but relatively spreads the dates and also displaying year changes. When I add 'parseDates': true to categoryAxis the chart rotates and is rendered all wrong. I've been searching in the API documentation for a while but I can't find any solution. What am I missing?
Result with parseDates set to true in categoryAxis options:
If I understand you correctly, the issue is that you need to display all month labels, as well as the year on January.
For this, you will need to set boldPeriodBeginning: true as well as markPeriodChange: true to display year instead of January label.
To make the chart display all months, you'll also need to disable auto grid by setting autoGridCount: false, as well as set gridCount to some larger number, say 25.
Please note that this is all for Value Axis. Enabling parsing of dates for category axis does not make a lot of sense, since you have arbitrary categories,
like "Survey DEF".
'valueAxes': [ {
'type': 'date',
'minimumDate': '31-01-2015',
'maximumDate': '04-05-2016',
'autoGridCount': false,
'gridCount': 25,
'boldPeriodBeginning': true,
'markPeriodChange': true,
'axisAlpha': 0.2,
'gridAlpha': 0.05
} ]
Here's the live chart with the above changes.
As of V3.18 of JavaScript Charts, it is also possible to make the value axis scrollable. To enable that, use valueScrollbar property of the chart. I.e.:
"valueScrollbar": {
"oppositeAxis": false,
"offset": 50,
"scrollbarHeight": 10
}
It's an instance of ChartScrollbar, so you can use any properties available in this class.
I am using a line chart. I feed the data the following:
var scheduled = [[51,1700],[52, 1750],[1,1600],[2,1675]];
var actual = [[51,1320],[52, 1550],[1,1575],[2,1600]];
In the above the first number of each set is the week of the year and I am trying to show the last 4 months of data.
However, when the chart is drawn Flot charts re-sorts the data by the first value (lowest to highest) which creates all kinds of issues. Instead of 4 columns in the series there are now 52, and the lines are quite out of whack.
I don't see anything in the documentation that says this is supposed to happen, nor do I see anything that says I can prevent it. However, for the data to be meaningful, the data must not be re-ordered.
Is there a setting I'm unaware of that can stop this behavior?
Edit : Adding plot code
var plot = $.plot('#scheduled-actual-flot-line', [
{
label: 'Scheduled Hours',
data: scheduled,
lines: { show: true, lineWidth: 2, fill: true, fillColor: { colors: [{ opacity: 0.5 }, { opacity: 0.5 }] } },
points: { show: true, radius: 4 }
},
{
label: 'Actual Hours',
data: actual,
lines: { show: true, lineWidth: 2, fill: true, fillColor: { colors: [{ opacity: 0.5 }, { opacity: 0.5 }] } },
points: { show: true, radius: 4 }
}],
{
series: {
lines: { show: true },
points: { show: true },
shadowSize: 0 // Drawing is faster without shadows
},
colors: ['#afd2f0', '#177bbb'],
legend: {
show: true,
position: 'nw',
margin: [15, 0]
},
grid: {
borderWidth: 0,
hoverable: true,
clickable: true
},
yaxis: { ticks: 4, tickColor: '#eeeeee' },
xaxis: { ticks: 12, tickColor: '#ffffff' }
}
);
Flot takes the x values as numbers and displays / sorts them accordingly. If you don't want that, you can use the category mode (see this example and this fiddle with your data).
xaxis: {
//ticks: 12,
tickColor: '#ffffff',
mode: 'categories'
}
PS: 12 ticks are not possibly with your data, as there are only 4 datapoints defined.
That flot reads all data as numbers by default is described here in the documentation.
Flotr examples use a for loop to create random data, so the first index will always be sequential.
[[51,1700],[52, 1750],[1,1600],[2,1675]];
Your arrays show that flotr must be doing a sort on the array before painting the data sets as lines, bar-graphs or whatever.
I can only suggest you create a timestamp from the months and there's a time setting you can in flotr settings to format the dates as you want.
The other way is replace your anomalous data (months) with sequential indices:
var arr = [[51,1700],[52, 1750],[1,1600],[2,1675]];
for(var i=0; i<arr.length; i++) arr[1][0] = i;
Flot is doing exactly what it should do for a line chart (or any type of x-y graph). It's showing the last two points of your dataset on the left because 1 and 2 are indeed less than 51 and 52. I'm guessing that you're trying to show data that crosses a year boundary. You need to make the first two weeks of the second year later than the last two of the first. You could use actual dates instead of week numbers, in which case Flot would handle it fine. That would also give you more flexibility in labeling the x-axis. But as a quick fix, just add 52 to the second year's data, e.g.:
var scheduled = [[51,1700],[52, 1750],[53,1600],[54,1675]];
var actual = [[51,1320],[52, 1550],[53,1575],[54,1600]];
I am trying to graph a month out in flot (per day) or possibly every other day, have a tick.
To get my time values, i am doing this:
$date = strtotime($rowData[0]); // 2013-01-01
$myData = json_encode(array($date*1000, 1234));
// I Then echo it out as an array into the javascript var.
For some reason, i can change the line: minTickSize: [1, day] to 2 (label every other tick i think) and nothing will change. Also, the time values are not showing up as well? What am i doing wrong?
Here is a JSFIDDLE
Here is an update with every two days...is there a rendering issue? Also, why is Oct 10, the only date shown? : JSFIDDLE UPDATE
Here is what i have as far as the javascript goes:
var myData = [[1380603600000,0],[1380690000000,0],[1380776400000,0],[1380862800000,0],[1380949200000,0],[1381035600000,0],[1381122000000,0],[1381208400000,0],[1381294800000,0],[1381381200000,0],[1381467600000,0],[1381554000000,0],[1381640400000,1],[1381726800000,0],[1381813200000,0],[1381899600000,0],[1381986000000,0],[1382072400000,0],[1382158800000,0],[1382245200000,0],[1382331600000,0],[1382418000000,0],[1382504400000,0],[1382590800000,0],[1382677200000,0],[1382763600000,0],[1382850000000,0],[1382936400000,0],[1383022800000,0],[1383109200000,0],[1383195600000,0]];
var plot = $.plot($(".subsChart"),
[ { data: myData, label: "myData"} ], {
series: {
lines: { show: true,
lineWidth: 2,
fill: true, fillColor: { colors: [ { opacity: 0.5 }, { opacity: 0.2 } ] }
},
points: { show: true,
lineWidth: 2
},
grow: { active: true,
steps: 30
},
shadowSize: 0
},
grid: { hoverable: true,
clickable: true,
tickColor: "#DDD",
borderWidth: 1,
borderColor: "#DDD"
},
colors: ["#FF0000"],
xaxis: {mode: "time", timeformat: "%b %m", ticks: myData, minTickSize: [5, "day"]},
yaxis: {ticks:3, tickDecimals: 0},
tooltip: true,
});
UPDATE
When i remove the ticks: myData option, the labels do show up, but all of them are on the same date? Also, none of the points even land on the dates.
As #Smokie suggested, you need to remove the ticks option. When you provide ticks, Flot skips any tick generation that it would normally do and uses what you provided instead, which in this case is invalid.
Once you do that, you'll notice that you have labels, but they all show Oct. 10. That's because your date format is %b (short month name) %m (month number). I'd guess that what you actually want is %b %d.
Note that you probably won't get a tick for every day because, depending on the size of your window, they wouldn't all fit. That's why minTickSize is a minimum rather than an exact value; Flot will ensure that at least one day (or however many you specify) separates the ticks, but may choose to spread them out further to ensure that they all fit.
I am using Flot to draw some bar charts. How do I configure the zoom so that when a user zooms out, the chart will look like the one at the top and not like the one at the bottom? In other words, I don't want the user to continue zooming out when all of the data for the chart is shown. I also want to restrict the chart from displaying anything below 0 on the X axis. See my code and pictures of the charts below:
<#macro barChart2 var formatFunction ticks="" optionLegend="{ show: false }">
var options = {
yaxis: {
tickFormatter: ${formatFunction}
},
series: {
stack: 0,
bars: {
show: true,
barWidth: 0.9,
align: "center"
}
},
grid : {
hoverable: true
},
xaxis: {
<#if "${ticks}" != "">
ticks: ${ticks}
</#if>
mode: "time",
timeformat: "%b %d, %H:%M %P"
},
pan : {
interactive: true
},
legend: ${optionLegend}
};
var plot${var} = $.plot($("#chart${var}"), data, options);
$("#zoomIn${var}").click(function(e) {
e.preventDefault();
plot${var}.zoom();
});
$("#zoomOut${var}").click(function(e) {
e.preventDefault();
plot${var}.zoomOut();
});
</#macro>
I suggest you take a look at the zoomRange and panRange parameters that you can set with the navigation plugin. You specify those for the axes like:
xaxis: { zoomRange: [0.1, 10], panRange: [-10, 10] },
yaxis: { zoomRange: [0.1, 10], panRange: [-10, 10] }
where zoomRange sets the limit for zooming. In this case, the difference between the min and max will never go below 0.1, and it will never exceed 10. panRange tells the content to stay in a certain range, so in this case, neither axis will pan below -10 or above 10.
I'm not sure how you do this with time series data, but try with javascript timestamps to begin with.