highcharts - rangeSelector: change date beyond zoomed time range -
i build chart lazy loading example (http://www.highcharts.com/stock/demo/lazy-loading) having input fields of range selector. when zoom in fine. change selected range using input fields. not able change input values beyond zoomed area despite fact have more data visible in navigator.
in setextremes function doing calculations:
dx.ipfixgraphmodule.prototype.setextremes = function(e) { var fromtime, maxzoom = 30 * 60 * 1000, = new date().gettime(); if (e.min) { fromtime = e.min; } else { fromtime = e.datamin; } fromtime = math.round(fromtime); var diff = - 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; } // refers axis // @see http://api.highcharts.com/highstock#axis.update this.update({ minrange: maxzoom }, false);
};
but values receive in e.min , e.max not original input values corrected displayed time range.
// handle changes in 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 value isn't parsed directly value browser's date.parse method, // yyyy-mm-dd in ie, try parsing 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 timezone offset (#433) if (!defaultoptions.global.useutc) { value = value + new date().gettimezoneoffset() * 60 * 1000; } // validate extremes. if goes beyound data min or max, use // 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 extremes if (value !== undefined) { chart.xaxis[0].setextremes( ismin ? value : xaxis.min, ismin ? xaxis.max : value, undefined, undefined, { trigger: 'rangeselectorinput' } ); } } };
(code taken highstock.src.js around line 21126)
so cannot extend zoom beyond current active selection, navigator displays more data. know way set date beyond zoomed time range?
possible solution
i solved checking navigator range in "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 , override method.
there no default api that. extend highcharts via overriding drawinput function (your second code snippet).
there part of code should comment out or remove - if
clause after:
// validate extremes. if goes beyound 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 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 svg label shows updated date ranges , and records click events // bring in 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 focused, onfocus event doesn't fire (#3713) rangeselector[name + 'input'].focus(); }) .add(inputgroup); inputgroup.offset += datebox.width + (ismin ? 10 : 0); // create html input element. rendered 1x1 pixel set 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 pixel see 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 input box input.onfocus = function () { rangeselector.showinput(name); }; // hide away input box input.onblur = function () { rangeselector.hideinput(name); }; // handle changes in 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 value isn't parsed directly value browser's date.parse method, // yyyy-mm-dd in ie, try parsing 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 timezone offset (#433) if (!defaultoptions.global.useutc) { value = value + new date().gettimezoneoffset() * 60 * 1000; } // validate extremes. if goes beyound data min or max, use // 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 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 selected min , max */ function aftersetextremes(e) { var chart = $('#container').highcharts(); chart.showloading('loading data 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 jsonp handler @ 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 null value end date data = [].concat(data, [ [date.utc(2011, 9, 14, 19, 59), null, null, null, null] ]); // create chart $('#container').highcharts('stockchart', { chart: { type: 'candlestick', zoomtype: 'x' }, navigator: { adapttoupdateddata: false, series: { data: data } }, scrollbar: { liveredraw: false }, title: { text: 'aapl history minute 1998 2011' }, subtitle: { text: 'displaying 1.7 million data points in highcharts stock 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 // }, xaxis: { events: { aftersetextremes: aftersetextremes }, minrange: 3600 * 1000 // 1 hour }, yaxis: { floor: 0 }, series: [{ data: data, datagrouping: { enabled: false } }] }); }); });
Comments
Post a Comment