Highcharts does not load my data properly - highcharts
I've tried several types of outputs. What I already have is:
JSON Output:
["[Date.UTC(2015,6,13,16,41,05), 3]","[Date.UTC(2015,7,15,16,41,05), 1]","[Date.UTC(2015,8,18,16,41,05), 4]","[Date.UTC(2015,9,28,16,41,05), 3]","[Date.UTC(2015,10,20,16,41,05), 1]","[Date.UTC(2015,10,28,16,41,05), 5]","[Date.UTC(2015,11,13,16,41,05), 1]","[Date.UTC(2015,11,21,16,41,05), 2]","[Date.UTC(2015,11,24,16,41,05), 1]","[Date.UTC(2015,11,25,16,41,05), 2]","[Date.UTC(2015,11,28,16,41,05), 1]","[Date.UTC(2016,0,03,16,41,05), 2]","[Date.UTC(2016,0,09,16,41,05), 4]","[Date.UTC(2016,0,14,16,41,05), 6]","[Date.UTC(2016,0,17,16,41,05), 3]","[Date.UTC(2016,0,18,16,41,05), 3]","[Date.UTC(2016,0,20,16,41,05), 2]","[Date.UTC(2016,0,21,16,41,05), 2]","[Date.UTC(2016,0,22,16,41,05), 2]","[Date.UTC(2016,0,23,16,41,05), 1]","[Date.UTC(2016,0,24,16,41,05), 5]","[Date.UTC(2016,0,25,13,41,05), 1]","[Date.UTC(2016,0,25,16,41,00), 1]","[Date.UTC(2016,0,25,16,41,05), 1]","[Date.UTC(2016,0,27,16,41,05), 1]","[Date.UTC(2016,0,28,16,41,05), 1]","[Date.UTC(2016,0,29,16,41,05), 1]","[Date.UTC(2016,1,09,16,41,05), 1]","[Date.UTC(2016,1,10,16,41,05), 2]","[Date.UTC(2016,1,11,16,41,05), 3]","[Date.UTC(2016,1,15,16,41,05), 2]","[Date.UTC(2016,1,18,16,41,05), 1]","[Date.UTC(2016,1,21,16,41,05), 1]","[Date.UTC(2016,1,23,16,41,05), 1]","[Date.UTC(2016,1,24,16,41,05), 1]","[Date.UTC(2016,1,25,16,41,05), 1]","[Date.UTC(2016,1,26,16,41,05), 1]","[Date.UTC(2016,1,28,16,41,05), 1]","[Date.UTC(2016,2,01,16,41,05), 1]","[Date.UTC(2016,2,02,16,41,05), 1]","[Date.UTC(2016,2,05,16,41,05), 1]","[Date.UTC(2016,2,12,16,41,05), 1]","[Date.UTC(2016,2,21,16,41,05), 1]","[Date.UTC(2016,3,25,16,41,05), 1]","[Date.UTC(2016,4,05,16,41,05), 2]","[Date.UTC(2016,4,11,16,41,05), 1]","[Date.UTC(2016,4,12,16,41,05), 1]","[Date.UTC(2016,4,24,16,41,05), 1]","[Date.UTC(2016,4,25,16,41,05), 1]","[Date.UTC(2016,5,01,16,41,05), 1]","[Date.UTC(2016,5,12,16,41,05), 1]","[Date.UTC(2016,5,25,10,41,05), 1]","[Date.UTC(2016,5,25,16,41,05), 1]","[Date.UTC(2016,6,01,10,41,05), 1]","[Date.UTC(2016,6,01,16,41,05), 1]","[Date.UTC(2016,6,02,16,41,05), 1]","[Date.UTC(2016,6,25,16,21,05), 1]","[Date.UTC(2016,6,25,16,41,05), 1]","[Date.UTC(2016,7,13,16,41,05), 1]","[Date.UTC(2016,7,28,16,41,05), 1]","[Date.UTC(2016,8,20,16,41,05), 3]","[Date.UTC(2016,8,29,16,41,05), 2]","[Date.UTC(2016,9,01,14,20,18), 1]","[Date.UTC(2016,9,09,14,20,18), 1]","[Date.UTC(2016,9,10,14,20,18), 1]","[Date.UTC(2016,9,28,14,20,18), 2]","[Date.UTC(2016,9,30,14,20,18), 2]","[Date.UTC(2016,10,01,13,44,29), 1]","[Date.UTC(2016,10,06,08,26,18), 2]","[Date.UTC(2016,10,10,13,44,29), 1]","[Date.UTC(2016,10,13,13,44,29), 2]","[Date.UTC(2016,10,14,19,13,42), 4]","[Date.UTC(2016,10,15,23,27,39), 3]","[Date.UTC(2016,11,06,19,04,06), 3]","[Date.UTC(2016,11,08,10,49,28), 3]","[Date.UTC(2016,11,10,23,01,44), 1]","[Date.UTC(2016,11,14,21,27,44), 1]","[Date.UTC(2016,11,15,23,27,44), 2]","[Date.UTC(2016,11,15,23,27,53), 3]","[Date.UTC(2016,11,18,18,06,28), 1]","[Date.UTC(2016,11,21,20,06,28), 3]","[Date.UTC(2016,11,23,20,06,20), 5]","[Date.UTC(2016,11,29,20,18,18), 3]","[Date.UTC(2017,0,03,20,06,32), 3]"]
That looks OK!
The works I've done on PHP is:
header("Content-type: text/json");
if($callback == 'cart-filling') {
// Count cart rows
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query
->select('*')
->from($db->quoteName('#__product_shoppingcart'))
->where($db->quoteName('date') . $scope);
$db->setQuery($query);
$results = $db->loadObjectList();
$ret = array();
foreach($results as $result) {
//$x = date_format($date, 'Y-m-d H:i:s');
$date = new DateTime($result->date);
$month = date_format($date, 'm');
$monthInt = (int) $month-1;
$date_part1 = date_format($date, 'Y');
$date_part2 = $monthInt;
$date_part3 = date_format($date, 'd');
$date_part4 = date_format($date, 'H');
$date_part5 = date_format($date, 'i');
$date_part6 = date_format($date, 's');
$formatted_date = (int) $date_part1 . ',' . (int) $date_part2 . ',' . (int) $date_part3 . ',' . (int) $date_part4 . ',' . (int) $date_part5 . ',' . (int) $date_part6;
/*
$date = new DateTime($result->date);
$x = date_format($date, "Y-m-d H:i:s");
*/
$x = $formatted_date;
$y = $result->qty;
//array_push($ret, array($x, $y));
//extract $row;
//$x = 'Date.UTC(' . $x . ')'; // convert from Unix timestamp to JavaScript time
$data[] = "[Date.UTC($x), $y]";
}
}
// Returning JSON string regarding the given callback and dtae
echo json_encode($data);
My AJAX call says:
function cartFilling() {
var url = 'components/com_product/views/reports/callback.php?callback=cart-filling&date='+date_scope;
jQuery.getJSON(url, function (data) {
Highcharts.chart('cartFilling', {
chart: {
zoomType: 'x'
},
title: {
text: 'Shopping Cart Filling Actions'
},
subtitle: {
text: document.ontouchstart === undefined ?
'Click and drag in the plot area to zoom in' : 'Pinch the chart to zoom in'
},
xAxis: {
type: 'datetime'
},
yAxis: {
title: {
text: 'Carts Filled'
},
type: 'number'
},
legend: {
enabled: false
},
plotOptions: {
area: {
fillColor: {
linearGradient: {
x1: 0,
y1: 0,
x2: 0,
y2: 1
},
stops: [
[0, Highcharts.getOptions().colors[0]],
[1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]
]
},
marker: {
radius: 2
},
lineWidth: 1,
states: {
hover: {
lineWidth: 1
}
},
threshold: null
}
},
series: [{
type: 'area',
name: 'Cart Filling',
data: data
}]
});
});
}
So, "data" already is:
[Date.UTC(2015,6,13,16,41,5), 3],[Date.UTC(2015,7,15,16,41,5), 1],[Date.UTC(2015,8,18,16,41,5), 4],[Date.UTC(2015,9,28,16,41,5), 3],[Date.UTC(2015,10,20,16,41,5), 1],[Date.UTC(2015,10,28,16,41,5), 5],[Date.UTC(2015,11,13,16,41,5), 1],[Date.UTC(2015,11,21,16,41,5), 2],[Date.UTC(2015,11,24,16,41,5), 1],[Date.UTC(2015,11,25,16,41,5), 2],[Date.UTC(2015,11,28,16,41,5), 1],[Date.UTC(2016,0,3,16,41,5), 2],[Date.UTC(2016,0,9,16,41,5), 4],[Date.UTC(2016,0,14,16,41,5), 6],[Date.UTC(2016,0,17,16,41,5), 3],[Date.UTC(2016,0,18,16,41,5), 3],[Date.UTC(2016,0,20,16,41,5), 2],[Date.UTC(2016,0,21,16,41,5), 2],[Date.UTC(2016,0,22,16,41,5), 2],[Date.UTC(2016,0,23,16,41,5), 1],[Date.UTC(2016,0,24,16,41,5), 5],[Date.UTC(2016,0,25,13,41,5), 1],[Date.UTC(2016,0,25,16,41,0), 1],[Date.UTC(2016,0,25,16,41,5), 1],[Date.UTC(2016,0,27,16,41,5), 1],[Date.UTC(2016,0,28,16,41,5), 1],[Date.UTC(2016,0,29,16,41,5), 1],[Date.UTC(2016,1,9,16,41,5), 1],[Date.UTC(2016,1,10,16,41,5), 2],[Date.UTC(2016,1,11,16,41,5), 3],[Date.UTC(2016,1,15,16,41,5), 2],[Date.UTC(2016,1,18,16,41,5), 1],[Date.UTC(2016,1,21,16,41,5), 1],[Date.UTC(2016,1,23,16,41,5), 1],[Date.UTC(2016,1,24,16,41,5), 1],[Date.UTC(2016,1,25,16,41,5), 1],[Date.UTC(2016,1,26,16,41,5), 1],[Date.UTC(2016,1,28,16,41,5), 1],[Date.UTC(2016,2,1,16,41,5), 1],[Date.UTC(2016,2,2,16,41,5), 1],[Date.UTC(2016,2,5,16,41,5), 1],[Date.UTC(2016,2,12,16,41,5), 1],[Date.UTC(2016,2,21,16,41,5), 1],[Date.UTC(2016,3,25,16,41,5), 1],[Date.UTC(2016,4,5,16,41,5), 2],[Date.UTC(2016,4,11,16,41,5), 1],[Date.UTC(2016,4,12,16,41,5), 1],[Date.UTC(2016,4,24,16,41,5), 1],[Date.UTC(2016,4,25,16,41,5), 1],[Date.UTC(2016,5,1,16,41,5), 1],[Date.UTC(2016,5,12,16,41,5), 1],[Date.UTC(2016,5,25,10,41,5), 1],[Date.UTC(2016,5,25,16,41,5), 1],[Date.UTC(2016,6,1,10,41,5), 1],[Date.UTC(2016,6,1,16,41,5), 1],[Date.UTC(2016,6,2,16,41,5), 1],[Date.UTC(2016,6,25,16,21,5), 1],[Date.UTC(2016,6,25,16,41,5), 1],[Date.UTC(2016,7,13,16,41,5), 1],[Date.UTC(2016,7,28,16,41,5), 1],[Date.UTC(2016,8,20,16,41,5), 3],[Date.UTC(2016,8,29,16,41,5), 2],[Date.UTC(2016,9,1,14,20,18), 1],[Date.UTC(2016,9,9,14,20,18), 1],[Date.UTC(2016,9,10,14,20,18), 1],[Date.UTC(2016,9,28,14,20,18), 2],[Date.UTC(2016,9,30,14,20,18), 2],[Date.UTC(2016,10,1,13,44,29), 1],[Date.UTC(2016,10,6,8,26,18), 2],[Date.UTC(2016,10,10,13,44,29), 1],[Date.UTC(2016,10,13,13,44,29), 2],[Date.UTC(2016,10,14,19,13,42), 4],[Date.UTC(2016,10,15,23,27,39), 3],[Date.UTC(2016,11,6,19,4,6), 3],[Date.UTC(2016,11,8,10,49,28), 3],[Date.UTC(2016,11,10,23,1,44), 1],[Date.UTC(2016,11,14,21,27,44), 1],[Date.UTC(2016,11,15,23,27,44), 2],[Date.UTC(2016,11,15,23,27,53), 3],[Date.UTC(2016,11,18,18,6,28), 1],[Date.UTC(2016,11,21,20,6,28), 3],[Date.UTC(2016,11,23,20,6,20), 5],[Date.UTC(2016,11,29,20,18,18), 3],[Date.UTC(2017,0,3,20,6,32), 3]
In addition,
I've tried serialize these ways as well:
data: [data]
and
data: ([data])
The most funny part is, when I insert the generated data manually for "data:" it works. But when I call its var it does nothing. Wasted 4 days of mine!
What's wring with me? What's going on here? I'm tired of waiting, asking wrong questions, getting wrong answers and receiving negative points for my questions :( Please somebody expert in Highcharts respond otherwise I do something so bad with this Laptop!
Thank you
Related
Highcharts - Indicator's data not showing in line chart
I am fetching data from an endpoint I display the data in a highchart There are several indicators that can be selected. For each of them another yAxis is added below the main one. My series data are of this format : series: [ { data: [], id: 'prices', step: this.hasStep, name: this.$props.title, fillColor: 'rgba(127,183,240,0.2)', }, { visible: false, type: 'column', id: 'volume', name: 'Volume_hardcoded', //linkedTo: 'prices', data: this.volumeSeries, }, ], I save the data in the following way (don't pay attention in the logic, it works fine): if (this.selectedTimeSpan.tickInterval === 1) { for (let i = 0; i < prices.length; i++) { let xData = null; this.selectedTimeSpan.getIntradayData ? (xData = Math.floor(new Date(prices[i].time).getTime())) : (xData = Math.floor(new Date(prices[i].date).getTime())); priceSeries[i] = { x: xData, open: prices[i].first, high: prices[i].high, low: prices[i].low, close: prices[i].last, y: prices[i].last, volume: prices[i].tradingVolume, }; this.volumeSeries[i] = { x: xData, y: prices[i].tradingVolume, }; } } else { let j = 0; for ( let i = 4; i < prices.length; i += this.selectedTimeSpan.tickInterval ) { priceSeries[j] = { x: Math.floor(new Date(prices[i].date).getTime()), open: prices[i].first, high: prices[i].high, low: prices[i].low, close: prices[i].last, y: prices[i].last, volume: prices[i].tradingVolume, }; this.volumeSeries[j] = { x: Math.floor(new Date(prices[i].date).getTime()), y: prices[i].tradingVolume, }; j++; } } When I select these indicators (they are based on the volume), I am getting this result.(You can see a blank space below the main chart.) Instead when i swap to OHLC or candlestick my main series (series[0]) it looks works fine and it looks like this. Any idea why is that happening? I haven't touched the tooltip settings at all (in case it was there a problem). I am struggling 2 days now with it can't really figure it out. Any help would be appreciated a lot. If you need more information feel free to comment so I can provide. Thanks in advance. Chris.
Fixed, there's a flag that can be used called usedOhlcData in series object. (series[0] in my case]. We just set it to true. series:[{ data:[], useOhlcData:true, ...} ,{ ... }]
Sankey Diagram unable to deliver using the json output
Using data from database I am trying to simulate the sankey diagram working JSFiddle. I am assembling my data using the below code // sdata.php <?php $con = sqlsrv_connect($server, $options); if (!$con){die('Could not connect: ' . sqlsrv_error());} $sql_query = "select * from test_data"; $result = sqlsrv_query($con, $sql_query); $series = array(); $series['type'] = 'sankey'; $series['name'] = 'Gendata'; $series['keys'] = '[\'from\',\'to\',\'weight\']'; while($r = sqlsrv_fetch_array($result)) { $series1 = array(); $series1[] = $r['PARENT']; $series1[] = $r['CHILD']; $series1[] = $r['DGEN']; $series['data'][] = $series1; } $result = array(); array_push($result,$series); print json_encode($result, JSON_NUMERIC_CHECK); sqlsrv_close($con); ?> My JSON looks like [{ "type":"sankey", "name":"Gendata", "keys":"['from','to','weight']", "data":[ ["GROUP","COAL",24.46], ["GROUP","GAS",11.96],["GROUP","HYDRO",19.36], ["HYDRO","HYD",19.36], ["COAL","ER2",22.4],["GAS","NR",19] ] }] My Chart rending code looks like $(document).ready(function() { var options = { chart: { renderTo: 'container', showAxes: true }, yAxis: [{ lineWidth: 1, tickPositions: [0, 1, 2, 3] }], title: { text: 'Sankey Diagram' }, series: [] } $.getJSON("sdata.php", function(resp) { console.log(resp); options.series[0] = resp[1]; //option 1 to assign the data in series //options.series.push.resp; //option 2 to push the data in series chart = new Highcharts.Chart(options); }); }); but I am failing. I am unable to find the error I am missing Kindly help me. Let me know if I can be of any further information.
From the code you have posted here, the error is your keys assignment. You have: "keys":"['from','to','weight']", But it needs to be: "keys": ['from','to','weight'], That is, the array should not be surrounded by quotes, because then it will be interpreted as a string. In your PHP that would mean: $series['keys'] = '[\'from\',\'to\',\'weight\']'; Needs to be: $series['keys'] = ['from', 'to', 'weight']; Working example: https://jsfiddle.net/ewolden/aeh02djx/
On scroll chart max value of data is not coming properly using highchart?
I am using highstock for scroll bar, for first time max value is coming properly but on scroll its not coming fine. I set max value to 10 and when I am scrolling only 9 is showing. Here is code, I am using: this.xAxis = { title: { text: (this.Entities[0] && this.Entities[0].EntityType && this.Entities[0].EntityType in window.dashboardconfig.constants.statusOrder) ? window.dashboardconfig.constants.statusOrderText[this.Entities[0].EntityType] : '' }, categories: _.map(this.Entities, function (sn) { return sn.EntityName; }), min: 0, max: (this.Entities.length >= 10) ? 9 : null, scrollbar: { enabled: true, }, var series = [{ name: (slotName in window.dashboardconfig.constants.statusOrder) ? window.dashboardconfig.constants.statusOrderText[slotName] : Resources.EventCode_5035, data: _.map(this.Entities, function (entity) { return entity.SlotValues.length >= index + 1 ? entity.SlotValues[index] : null; }), index: (slotName in window.dashboardconfig.constants.statusOrder) ? window.dashboardconfig.constants.statusOrder[slotName] : 0, color: window.dashboardconfig.constants.statusColor[slotName] }]; this.series = _.sortBy(series, function (item) { return item.index; }).reverse(); Here 10 recoreds are coming in graph But on scroll only 9 is coming I don't know where I am doing wrong.Can please tell me what I is wrong.
get tickpositions highcharts
I have a highcharts scatter plot for which I'm trying to fetch the x and y tickPositions in freemarker template, specifically the first and last one. Such as that I would get something as [-10,-10] (bottom left corner) at the intersection of the x-y axis and [30,40] (top right corner) at the intersection of the opposite sides, where xAxis ticks are [-10,0,10,20,30] and yAxis ticks are [-10,0,10,20,30,40] I want these points so that I'll be able to plot a diagonal line across the scatter plot from bottom lower corner to top right corner. The line series should look like: series: [ { type : 'line', <#--diagonal line--> data :[[-10,-10], [30,40]], // to be calculated dynamically lineWidth: 0.5, marker : { enabled : false } }, { color: 'rgb(0,85,152)', data: [[2,3],[6,7],[8,9]] } ] The problem at present is I'm unable to get [-10,-10], [30,40] data points. Is it even possible is what I'm wondering. Any help is much appreciated!
You have the getExtremes() function on an axis. For example: var extremes = $('#container').highcharts().yAxis[0].getExtremes(); Here is the doc, and here is a demo fiddle Is this what you were trying to achieve ? Edit After your fiddle example, I understand better your need. Here is the updated fiddle var chart = $('#container').highcharts(); var extremeY = chart.yAxis[0].getExtremes(); var extremeX = chart.xAxis[0].getExtremes(); var lineSeries = { type: 'line', data: [ [extremeX.min, extremeY.min], [extremeX.max, extremeY.max] ], lineWidth: 0.5, lineColor: 'rgb(0,0,0)', marker: { enabled: false } }; chart.addSeries(lineSeries); I created an object with the properties of the line series. And using min and max (not dataMin and dataMax) properties from the object returned by getExtremes() you obtain the desired result. Edit 2 You could put this code in the load event of the chart. It is a callback called after the chart finished loading. And here you can use this to refer to the chart : $('#container').highcharts({ chart: { events: { load: function() { var extremeY = this.yAxis[0].getExtremes(); var extremeX = this.xAxis[0].getExtremes(); var lineSeries = { type: 'line', data: [ [extremeX.min, extremeY.min], [extremeX.max, extremeY.max] ], lineWidth: 0.5, lineColor: 'rgb(0,0,0)', marker: { enabled: false } }; this.addSeries(lineSeries); } }, //... }); Here is the new updated fiddle
Since you need only a diagonal path, then you could add it using renderer Example: http://jsfiddle.net/cr7gq4st/ function diagonal() { var chart = this, ren = chart.renderer, diag = chart.diag, attrs = { 'stroke-width': 0.5, stroke: '#000', zIndex: 1 }, topR = { x: chart.plotLeft + chart.plotWidth, y: chart.plotTop }, bottomL = { x: chart.plotLeft, y: chart.plotTop + chart.plotHeight }, d = 'M ' + bottomL.x + ' ' + bottomL.y + ' L ' + topR.x + ' ' + topR.y; if( !diag ) { //if doesn't exist, then create chart.diag = ren.path().attr(attrs).add(); } chart.diag.attr({d:d}); }
rangeSelector: change date beyond zoomed time range
I build a chart like the lazy loading example (http://www.highcharts.com/stock/demo/lazy-loading) but with having the input fields of the range selector. When I zoom in everything is fine. Now I would like to change the selected range by using the input fields. But I am not able to change the input to values beyond the zoomed area despite the fact I have more data visible in my navigator. In the setExtremes function I am doing some calculations: DX.IPFixGraphModule.prototype.setExtremes = function(e) { var fromTime, maxZoom = 30 * 60 * 1000, now = new Date().getTime(); if (e.min) { fromTime = e.min; } else { fromTime = e.dataMin; } fromTime = Math.round(fromTime); var diff = now - fromTime; // -1 month = max 1 week zoom if (diff >= 2592000000) { maxZoom = 7 * 24 * 60 * 60 * 1000; } // -1 week = max 12 hour zoom else if (diff >= 604800000) { maxZoom = 12 * 60 * 60 * 1000; } // this refers to axis // #see http://api.highcharts.com/highstock#Axis.update this.update({ minRange: maxZoom }, false); }; But the values I receive in e.min and e.max are not the original input values but already corrected to the displayed time range. // handle changes in the input boxes input.onchange = function () { var inputValue = input.value, value = (options.inputDateParser || Date.parse)(inputValue), xAxis = chart.xAxis[0], dataMin = xAxis.dataMin, dataMax = xAxis.dataMax; // If the value isn't parsed directly to a value by the browser's Date.parse method, // like YYYY-MM-DD in IE, try parsing it a different way if (isNaN(value)) { value = inputValue.split('-'); value = Date.UTC(pInt(value[0]), pInt(value[1]) - 1, pInt(value[2])); } if (!isNaN(value)) { // Correct for timezone offset (#433) if (!defaultOptions.global.useUTC) { value = value + new Date().getTimezoneOffset() * 60 * 1000; } // Validate the extremes. If it goes beyound the data min or max, use the // actual data extreme (#2438). if (isMin) { if (value > rangeSelector.maxInput.HCTime) { value = UNDEFINED; } else if (value < dataMin) { value = dataMin; } } else { if (value < rangeSelector.minInput.HCTime) { value = UNDEFINED; } else if (value > dataMax) { value = dataMax; } } // Set the extremes if (value !== UNDEFINED) { chart.xAxis[0].setExtremes( isMin ? value : xAxis.min, isMin ? xAxis.max : value, UNDEFINED, UNDEFINED, { trigger: 'rangeSelectorInput' } ); } } }; (Code taken from highstock.src.js around line 21126) So I cannot extend my zoom beyond the current active selection, but the navigator displays more data. Does anyone know a way to set a date beyond the currently zoomed time range? Possible Solution I solved it by checking the navigator range in the "afterSetExtremes" Event. DX.IPFixGraphModule.prototype.afterSetExtremes = function(e) { if (e.trigger === 'rangeSelectorInput') { var fromValue = this.stockchart.rangeSelector.minInput.value, toValue = this.stockchart.rangeSelector.maxInput.value, fromTime = parseDateTime(fromValue), toTime = parseDateTime(toValue), navigatorAxis = this.stockchart.get('navigator-x-axis'), maxValue = navigatorAxis.dataMax, minValue = navigatorAxis.dataMin; if (fromTime < minValue) { fromTime = minValue; } if (toTime > maxValue) { toTime = maxValue; } this.stockchart.xAxis[0].setExtremes(fromTime, toTime); } else { var fromTime, toTime; if (e.min) { fromTime = e.min; } else { fromTime = e.dataMin; } fromTime = Math.round(fromTime); if (e.max) { toTime = e.max; } else { toTime = e.dataMax; } toTime = Math.round(toTime); this.settings.afterSetExtremes({startTimestamp: fromTime, endTimestamp: toTime}); } }; Or see solution below and override the method.
There is no default API for that. Extend Highcharts via overriding drawInput function (your second code snippet). There is a part of code that you should comment out or remove - the if clause after: // Validate the extremes. If it goes beyound the data min or max, use the // actual data extreme (#2438). Example: http://jsfiddle.net/epL7awo4/1/ $(function () { (function (H) { H.wrap(H.RangeSelector.prototype, 'drawInput', function (proceed) { var name = arguments[1], merge = H.merge, createElement = H.createElement, PREFIX = 'highcharts-', ABSOLUTE = 'absolute', PX = 'px', extend = H.extend, pInt = H.pInt, UNDEFINED; //drawInput: function (name) { var rangeSelector = this, chart = rangeSelector.chart, chartStyle = chart.renderer.style, renderer = chart.renderer, options = chart.options.rangeSelector, defaultOptions = H.getOptions(), lang = defaultOptions.lang, div = rangeSelector.div, isMin = name === 'min', input, label, dateBox, inputGroup = this.inputGroup; // Create the text label this[name + 'Label'] = label = renderer.label(lang[isMin ? 'rangeSelectorFrom' : 'rangeSelectorTo'], this.inputGroup.offset) .attr({ padding: 2 }) .css(merge(chartStyle, options.labelStyle)) .add(inputGroup); inputGroup.offset += label.width + 5; // Create an SVG label that shows updated date ranges and and records click events that // bring in the HTML input. this[name + 'DateBox'] = dateBox = renderer.label('', inputGroup.offset) .attr({ padding: 2, width: options.inputBoxWidth || 90, height: options.inputBoxHeight || 17, stroke: options.inputBoxBorderColor || 'silver', 'stroke-width': 1 }) .css(merge({ textAlign: 'center', color: '#444' }, chartStyle, options.inputStyle)) .on('click', function () { rangeSelector.showInput(name); // If it is already focused, the onfocus event doesn't fire (#3713) rangeSelector[name + 'Input'].focus(); }) .add(inputGroup); inputGroup.offset += dateBox.width + (isMin ? 10 : 0); // Create the HTML input element. This is rendered as 1x1 pixel then set to the right size // when focused. this[name + 'Input'] = input = createElement('input', { name: name, className: PREFIX + 'range-selector', type: 'text' }, extend({ position: ABSOLUTE, border: 0, width: '1px', // Chrome needs a pixel to see it height: '1px', padding: 0, textAlign: 'center', fontSize: chartStyle.fontSize, fontFamily: chartStyle.fontFamily, top: chart.plotTop + PX // prevent jump on focus in Firefox }, options.inputStyle), div); // Blow up the input box input.onfocus = function () { rangeSelector.showInput(name); }; // Hide away the input box input.onblur = function () { rangeSelector.hideInput(name); }; // handle changes in the input boxes input.onchange = function () { var inputValue = input.value, value = (options.inputDateParser || Date.parse)(inputValue), xAxis = chart.xAxis[0], dataMin = xAxis.dataMin, dataMax = xAxis.dataMax; // If the value isn't parsed directly to a value by the browser's Date.parse method, // like YYYY-MM-DD in IE, try parsing it a different way if (isNaN(value)) { value = inputValue.split('-'); value = Date.UTC(pInt(value[0]), pInt(value[1]) - 1, pInt(value[2])); } if (!isNaN(value)) { // Correct for timezone offset (#433) if (!defaultOptions.global.useUTC) { value = value + new Date().getTimezoneOffset() * 60 * 1000; } // Validate the extremes. If it goes beyound the data min or max, use the // actual data extreme (#2438). /* if (isMin) { if (value > rangeSelector.maxInput.HCTime) { value = UNDEFINED; } else if (value < dataMin) { value = dataMin; } } else { if (value < rangeSelector.minInput.HCTime) { value = UNDEFINED; } else if (value > dataMax) { value = dataMax; } }*/ // Set the extremes if (value !== UNDEFINED) { chart.xAxis[0].setExtremes( isMin ? value : xAxis.min, isMin ? xAxis.max : value, UNDEFINED, UNDEFINED, { trigger: 'rangeSelectorInput' }); } } }; //}, }); }(Highcharts)); /** * Load new data depending on the selected min and max */ function afterSetExtremes(e) { var chart = $('#container').highcharts(); chart.showLoading('Loading data from server...'); $.getJSON('http://www.highcharts.com/samples/data/from-sql.php?start=' + Math.round(e.min) + '&end=' + Math.round(e.max) + '&callback=?', function (data) { chart.series[0].setData(data); chart.hideLoading(); }); } // See source code from the JSONP handler at https://github.com/highslide-software/highcharts.com/blob/master/samples/data/from-sql.php $.getJSON('http://www.highcharts.com/samples/data/from-sql.php?callback=?', function (data) { // Add a null value for the end date data = [].concat(data, [ [Date.UTC(2011, 9, 14, 19, 59), null, null, null, null] ]); // create the chart $('#container').highcharts('StockChart', { chart: { type: 'candlestick', zoomType: 'x' }, navigator: { adaptToUpdatedData: false, series: { data: data } }, scrollbar: { liveRedraw: false }, title: { text: 'AAPL history by the minute from 1998 to 2011' }, subtitle: { text: 'Displaying 1.7 million data points in Highcharts Stock by async server loading' }, rangeSelector: { buttons: [{ type: 'hour', count: 1, text: '1h' }, { type: 'day', count: 1, text: '1d' }, { type: 'month', count: 1, text: '1m' }, { type: 'year', count: 1, text: '1y' }, { type: 'all', text: 'All' }], inputEnabled: true, selected: 4 // all }, xAxis: { events: { afterSetExtremes: afterSetExtremes }, minRange: 3600 * 1000 // one hour }, yAxis: { floor: 0 }, series: [{ data: data, dataGrouping: { enabled: false } }] }); }); });