I am currently using Highcahrts and i need to retrieve my data from an AJAX request, this data should be displayed in the tooltip and i need to send a request as soon as i hover on the series.
I want to display the tooltip when the request ends(i assume that my req is not problematic) so i should i use a promise of course but I don't know what object to attach it a onmouseover event.
I tried looking for it on HC docs and other sources and did not find a thing, hope I could get some help here.
You can call a request in the mouseOver event, store data in a point and fnally call the tooltip's refresh method. Example:
plotOptions: {
series: {
point: {
events: {
mouseOver: function() {
if (!this.dynamicData) {
fetch('https://api.npoint.io/3755b440b66a037c9499')
.then(data => data.json())
.then(data => {
if (this.state === 'hover') {
this.dynamicData = data;
this.series.chart.tooltip.refresh(this);
}
}).catch(function(error) {
console.log('Request failed', error);
});
}
}
}
}
}
},
tooltip: {
formatter: function() {
if (this.point.dynamicData) {
return this.point.dynamicData.data;
}
return 'Loading...';
}
}
Live demo: http://jsfiddle.net/BlackLabel/nt2u937m/
API Reference:
https://api.highcharts.com/highcharts/tooltip.formatter
https://api.highcharts.com/highcharts/plotOptions.series.point.events.mouseOver
https://api.highcharts.com/class-reference/Highcharts.Tooltip#refresh
Related
I am new to high charts.
Below is my partial code in a function when creating a mapChart, what it does is that it only show the matching region (with cur_state) as red and others as blue.
chart: {
backgroundColor: null,
map: 'countries/au/au-all',
events: {
load: function () {
// place1
this.series[0].data = this.series[0].data.map((el) => {
// place2
if (el['hc-key'] == region_dict[cur_state][1]) {
el.color = "#ff0000";
return el;
}
el.color = "blue"
return el
})
this.update({
series: [{
data: this.series[0].data
}]
})
}
}
},
When the value of cur_state is changed, I recall the function which contains the map graph, hoping that the corresponding region has color update.
This is the first time I call the function:
This is after second time I call the function, the coloring and hovering effect are gone:
After testing, I realised that both place1 and place2 are executed when the chart is firstly created, and only place1 is executed when the chart is re-created.
My other part of code has similar structure as this: https://jsfiddle.net/gh/get/library/pure/highslide-software/highcharts.com/tree/master/samples/mapdata/countries/au/au-all
How can I achieve the expected outcome?
Thanks for helping
The best solution in your case seems to be to use render event and change the color on the SVG level. Example:
chart: {
...,
events: {
render: function() {
this.series[0].points.forEach(function(point) {
if (point['hc-key'] == state) {
point.graphic.attr({
fill: 'red'
});
}
});
}
}
}
Live demo: https://jsfiddle.net/BlackLabel/x69pLcyo/
API Reference:
https://api.highcharts.com/highcharts/chart.events.render
https://api.highcharts.com/class-reference/Highcharts.SVGElement#attr
I'm using Highcharts to create organization charts as in provided example : https://jsfiddle.net/vegaelce/7rb6esqt/
Is it possible to add a "collapse" feature as in the Google organization chart ? In the following example https://jsfiddle.net/vegaelce/kb2gted4 when you double clic on "Mike" or "Jim" cell, it collapse all the cells above. I need to reproduce an equivalent mode with Highcharts, do you have an idea to do that ? (in Google API, the collapse mode is enabled via
allowCollapse:true
Thanks
There is no such built-in functionality in Highcharts, but you can add it by using click event and show/hide methods. Example:
plotOptions: {
series: {
point: {
events: {
click: function() {
const operateChildren = (point, operation) => {
point.linksFrom.forEach(link => {
link.graphic[operation]();
link.toNode.graphic[operation]();
operateChildren(link.toNode, operation);
});
};
if (this.linksFrom && this.linksFrom[0]) {
if (this.linksFrom[0].graphic.visibility === 'hidden') {
operateChildren(this, 'show');
} else {
operateChildren(this, 'hide');
}
}
}
}
}
}
},
tooltip: {
formatter: function(tooltip) {
if (this.point.graphic.visibility !== 'hidden') {
return tooltip.defaultFormatter.call(this, tooltip);
}
return false;
}
}
Live demo: https://jsfiddle.net/BlackLabel/dp03gq6a/
API Reference:
https://api.highcharts.com/class-reference/Highcharts.SVGElement#show
https://api.highcharts.com/class-reference/Highcharts.SVGElement#hide
I have a chart with multiple data series. How do I change it so that when I click on the legend it hides all other data points and only shows the data series I clicked on?
Many thanks
Return false from the legendItemClick event callback function to prevent the default legend behaviour and use hide and show methods on the relevant series.
plotOptions: {
series: {
events: {
legendItemClick: function() {
this.chart.series.forEach(s => {
s !== this ? s.hide() : s.show()
}, this);
return false;
}
}
}
}
Live demo: http://jsfiddle.net/BlackLabel/tzLbxr20/
API Reference:
https://api.highcharts.com/highcharts/plotOptions.series.events.legendItemClick
https://api.highcharts.com/class-reference/Highcharts.Series#show
https://api.highcharts.com/class-reference/Highcharts.Series#hide
Situation:
My tooltips show up on my page. Opening my fancybox works. Doing the ajax post from that fancybox works.
But my tooltips don't work in that fancybox. And they don't work after my ajax post.
I tried to reinitialize TipTip with the callbacks of fancybox.
EDIT
Title changes
So I found a way to let it run on the second hover after post but not on first hover.
I also found some explanations here but it still didn't fix my problem. Probably doing it wrong.
EDIT 2
Tootip in fancybox working use afterShow only.
Changes
added this in $(function () { so that it calls this function instead of initTipTip.
$(".tooltip").live('mouseover', function () {
$(this).tipTip();
});
Code of my function that does the post thing and closes my fancybox.
var reservation = MakeReservation();
var oldDateSplit = $("#resDate").val().split('/');
var newDateSplit = $("#dateEditReservation").val().split('/');
var oldDate = new Date(oldDateSplit[2], oldDateSplit[1] - 1, oldDateSplit[0]);
var newDate = new Date(newDateSplit[2], newDateSplit[1] - 1, newDateSplit[0]);
var time = $("#txtTime");
$.ajax({
url: ResolveUrl('~/Reservation/CheckSettings'),
data: "JSONString=" + reservation + "&hasJavaScriptMethod=" + true
}).done(function (data) {
if (data.length == 0 || oldDate.getTime() == newDate.getTime()) {
$.fancybox.close();
var id = $("#reservationId").val();
$("#reservationList").load(ResolveUrl('~/Reservation/reservationList',
function () { initTipTip(); }));
$("#reservationDetail").load(ResolveUrl('~/Reservation/DetailInfo',
function () { initTipTip(); }), { reservationId: id });
$("#reservationList").on("hover", " .tooltip", function () { $(this).tipTip(); });
}
else {
$(".errorDiv").removeClass("hidden");
$(".errorDiv").html(data);
$(".btnReservations").removeAttr('disabled');
}
});
NEW
$(".tooltip").live('mouseover', function () {
$(this).tipTip();
});
}
Still the same as before the edit.
Code initialization for TipTip
function initTipTip () {
$(".tooltip").tipTip();
}
Code of fancybox
function openFancy() {
$("a.inline").fancybox({
'type': 'ajax',
'afterShow': function () {
return initTipTip();
}
});
$("a.inlineBlockedDate").fancybox({
'type': 'ajax',
'ajax': { cache: false },
'afterShow': function () {
return initTipTip();
}
});
}
I found the solution for this.
So I used my .live in $(function(){ like in my question but I did not use ".tooltip" here but the table itself. I also use initTipTip here instead of $(this).tipTip();
So this solves the Tooltip from TipTip.
Explanation: This is because the tooltip.live only gets triggered on first hover and not when the table 'refreshes'. So now you add that event on that refresh of the table
Correct me if I'm wrong here.
So no need for any other .tiptip stuff or InitTipTip then in $(function(){
$("#reservationList").live('mouseover', function () {
initTipTip();
});
I hope your problem gets solved with this question.
Is it possible to work with combobox as with usual jquery-ui ajax autocomplete field?
What I need?
I want there will be some default options and when user try to put any letters it must connect to the server to find requested information (as usual remote json autocomplete).
Is it possible at all?
Here's a heavily modified version of the jQueryUI example (gist):
$.widget("ui.combobox", {
_create: function() {
var _self = this
, options = $.extend({}, this.options, {
minLength: 0,
source: function(request, response) {
if (!request.term.length) {
response(_self.options.initialValues);
} else {
if (typeof _self.options.source === "function") {
_self.options.source(request, response);
} else if (typeof _self.options.source === "string") {
$.ajax({
url: _self.options.source,
data: request,
dataType: "json",
success: function(data, status) {
response(data);
},
error: function() {
response([]);
}
});
}
}
}
});
this.element.autocomplete(options);
this.button = $("<button type='button'> </button>")
.attr("tabIndex", -1)
.attr("title", "Show All Items")
.insertAfter(this.element)
.button({
icons: {
primary: "ui-icon-triangle-1-s"
},
text: false
})
.removeClass("ui-corner-all")
.addClass("ui-corner-right ui-button-icon")
.click(function() {
if (_self.element.autocomplete("widget").is(":visible")) {
_self.element.autocomplete("close");
return;
}
_self.element.autocomplete("search", "");
_self.element.focus();
});
}
});
Usage:
$("input_element_selector").combobox({
initialValues: ['array', 'of', 'values'],
source: /* <-- function or string performing remote search */,
/* any other valid autocomplete options */
});
Example: http://jsfiddle.net/Jpqa8/
The widget uses the supplied initialValues array as the source when the length of the search is "0" (this happens when the user clicks the dropdown button).
Supply a source parameter (function or string) that performs the remote search. You can also use any other options you would usually use with the autocomplete widget.