If there is a large amount of statistical data, such as currency quotes (and other data related to financial topics), the consumption of something (water, etc.), generally speaking, any data that can be presented in one way or another in as a pair of "date - value", it is convenient to present them in graphical form. Since the data can be collected for a sufficiently long period of time, it makes sense to represent them as a pair of graphs: a “master” chart, on which all points will be displayed, and a “details” graph, where points will be displayed for the required period. In this article I will try to tell you how to build a graph of this type using the standard tools of the HighCharts libraries and jQuery UI.
The solution given below is, in principle, a bicycle, since With the advent of the new product from the developers HighCharts, which was called HighStock, the need for implementation in a similar way disappears. However, HighStock is still in beta.
How will it look like

In the figure above, 4 zones are highlighted that correspond to what will be necessary to implement:
- Details chart
- Schedule "master"
- Display period
- Scrollbar for dragging period
First look
Obviously, HighCharts will be used to display charts, and jQuery UI Silder for sliders. HTML markup is nothing but 4 consecutive DIVs, which are arranged according to the list above. Since JS is not so simple, the main problem here is the synchronization of actions of the scrollbar, slider and graphics "details." There are no difficulties in creating and updating graphs, you can easily understand the configuration using the documentation. Of the principal features, it is worth noting that on the "master" graphic, it is necessary to leave only the X axis and the captions to it, and to hide the remaining service elements.
')
Sliders
Sliders are created as follows:
function createSlider() { var sliderId = "#" + _sliderContainerId; $(sliderId).slider({ range: true, min: _minDate, max: _maxDate, values: [_minDate, _maxDate], stop: onSliderStop, slide: onSliderSlide }); $(sliderId + " > .ui-widget-header").addClass(_sliderRangeClass); $(sliderId + " > .ui-slider-handle").addClass(_sliderHandleClass); $(sliderId).show(); createScrollbar(); } function createScrollbar() { var scrollId = "#" + _scrollbarContainerId; $(scrollId).slider({ min: _minDate, max: _maxDate, slide: onScrollbarSlide, stop: onScrollbarStop }); $(scrollId + " > .ui-slider-handle").addClass(_scrollbarHandleClass); $(scrollId).show(); }
The limit values ​​of the slider and the scrollbar are the same: the left border corresponds to the minimum date, the right border - the maximum.
The range slider (number 3 in the figure) allows you to change the right and left borders of the displayed period. In parallel with the change of borders, the width of the slider No. 4, which is used as a scrollbar, should also change. For these purposes, the appropriate handlers are assigned to the
slide event. Updating of the schedule should be assigned to the
stop event of the sliders in order to avoid brakes due to constant redrawing when using any of the sliders.
Since the graph number 3 is a range-slider, when you update, you only need to set the left and right borders, jQuery will perfectly cope with the rest. In the case of a scrollbar, the handle size has to be changed manually, since standardly this possibility is not provided (and indeed, why?). When this is necessary to do the following:
scrollbar.css("margin-left", -1 * width / 2 - 1);
This measure will allow not to leave the scrollbar handle visually half a case per container. In addition, because this slider takes a single value corresponding to the middle of the handle, then the value of the scrollbar will be equal to the position of the left edge plus half its width. Also, when using a scrollbar, you need to monitor whether it has reached the right or left edge, and stop it in this case (using
preventDefault ).
Given the above, in my case the handlers looked like this:
function updateSlider(from, to) { _from = from; _to = to; var $slider = $("#" + _sliderContainerId); $slider.slider("values", 0, from); $slider.slider("values", 1, to); } function updateScrollbar(from, to) { var range = to - from; var $scrollbar = $("." + _scrollbarHandleClass); var width = $("." + _sliderRangeClass).width(); $scrollbar.width(width); $scrollbar.css("margin-left", -1 * width / 2 - 1); $scrollbar.attr("range", range); $("#" + _scrollbarContainerId).slider("value", from + range / 2); } function onSliderSlide(event, ui) { var from = _from = ui.values[0]; var to = _to = ui.values[1]; var fromDate = new Date(from).toUTCString(); var toDate = new Date(to).toUTCString(); updateScrollbar(from, to); } function onSliderStop(event, ui) { updateChart(ui.values[0], ui.values[1]); } function onScrollbarSlide(event, ui) { var value = ui.value; var range = $("." + _scrollbarHandleClass).attr("range") * 1; var minReached = value - _minDate < range / 2; var maxReached = _maxDate - value < range / 2; if (minReached) { updateSlider(_minDate, _minDate + range); event.preventDefault(); return; } if (maxReached) { updateSlider(_maxDate - range, _maxDate); event.preventDefault(); return; } updateSlider(value - range / 2, value + range / 2); } function onScrollbarStop(event, ui) { var value = ui.value; var range = $("." + _scrollbarHandleClass).attr("range") * 1; updateChart(value - range / 2, value + range / 2); }
results
In the end, following the instructions, you can create something like this:
demo . With the help of CSS, the appearance can be made almost anywhere. It is easy to add things to the resulting graphic, such as dynamic loading and updating, data comparison, etc.
References:
- Highcharts
- jQuery UI
- Highstock