Highcharts tooltipRefresh check for hovered item - javascript

In Highcharts, I am currently using tooltipRefresh to run a function that renders dynamic content within the current tooltip.
For example, I am using:
chart: {
events: {
tooltipRefresh: function (e) {
createTableChartGauge();
}
}
}
I only want createTableChartGauge() to be run if the hovered data is a specific colour. I tried logging e that is passed through the tooltipRefresh function, although that just contains all chart data and nothing specific to the hovered data set.
How can I detect what element is currently be hovered so that I can render specific content per type?

You have access to this.hoverPoint, which contains actual point. So run your method only when colors match:
chart: {
events: {
tooltipRefresh: function (e) {
if(this.hoverPoint.color === "#eefffe") {
createTableChartGauge();
}
}
}
},

Related

getSelectedPoints array delay problem in HighCharts

I need to access to getSelectedPoints array on click event but there is a delay i get the previous selected points and to solve that now i am using setTimeout function as shown code below but this is not a solving; Because i can not expect when points are selection finished.
I have seen this question
HighCharts Multiple Point selection - access/update getSelectedPoints array immediately after point select
but it's solve the problem in JQuery and old version of hightcharts that has select event and it's deprecated in new versions of hightcharts. I need answer to be in javascript and hightcharts v8.
plotOptions: {
series: {
events: {
click: function(event) {
var chart = new Highcharts.Chart(this.divElement.nativeElement,this.options);
chart.getSelectedPoints().forEach(point=>{
setTimeout(()=>{
// do something here
},500);
});
}
}
}
Where have you found the information that the select event is deprecated? It's not true, the event is fully supported - API: https://api.highcharts.com/highcharts/series.line.point.events.select
And the demo which shows how to get the array of selected points:
https://jsfiddle.net/BlackLabel/uq4nrtky/
point: {
events: {
select: function() {
var selectedPoints = chart.getSelectedPoints()
selectedPoints.push(this);
console.log(selectedPoints)
}
}
}

Filtering Tooltip in Kendo

I have a tooltip in Kendo UI which I'm trying to filter cells based on their column name, because the standard td:nthchild won't work (users can move columns around). I want to engage the tooltip based on if someone hovers over MY COLUMN NAME'S CELLS. How do I accomplish that in the filter field? Or should I do it in the show function?
this.$el.kendoTooltip({
filter: "th:contains('MY COLUMN NAME')",
show: function (e) {
if (this.content.text().length > 0) {
this.content.parent().css("visibility", "visible");
}
},
hide: function(e) {
this.content.parent().css("visibility", "hidden");
},
content: function (e) {
var target = e.target;
return $(target).siblings().first().text();
}
});
Like this ?
this.$el.kendoTooltip({
filter: "thead th:contains('ColumnA')"
});
Demo
UPDATE
As you want to show the tooltip on the row cell based on the column's title, you can't use filter parameter for that, it is meant to be used to filter only the target element, which is not your case. You will need some programming there, e.g:
show: function(e) {
let index = this.target().index(), // Get hovered element's column index
columns = grid.getOptions().columns, // Get grid's columns
column = columns[index]; // Get current column
// If target TD is not under 'ColumnA', prevent tooltip from being showed
if (column.title != "ColumnA") {
this.hide();
}
}
Demo
Thanks to kendo, you can't prevent their own events, so using hide() works but the tooltips still opens blinking before it is hidden again, it's possible to catch it opening. Tried using e.preventDefault() and return false that would a reasonable way to say "cancel the widget showing" but with no luck. This was the best I could do.

Ag-grid-Enterprise expand/collapse all row using button? Very slow crashing FF and Edge

I created a button to expand all the rows in ag-grid (Enterprise) having 150 rows in the grid. It is working fine in Chrome but it is showing an alert in the latest FF and Edge, saying the web page is making your browser slow. Any better approach to expand all the row? It is taking almost 10-15 second
HTML
<button (click)="expandAll(expand)">Expand/Collapse</button>
JavaScript
this.columnDefs = [
{
headerName: "",
field: "",
cellRenderer: "group",// for rendering cell
suppressMenu: true,
suppressSorting: true
}
]
// This is how I am creating fullrow width
this.gridOptions = <GridOptions>{
isFullWidthCell: function (rowNode) {
var rowIsNestedRow = rowNode.flower;
return rowIsNestedRow;
},
fullWidthCellRendererFramework: AgGridInventorRowComponent,
doesDataFlower: function (dataItem) {
return true;
}
public expandAll(value:boolean) {
if(value) {
this.gridOptions.api.forEachNode((node) =>{
node.setExpanded(true);
});
} else {
this.gridOptions.api.forEachNode((node) =>{
node.setExpanded(false);
});
}
}
As per the documentation:
Calling node.setExpanded() causes the grid to get redrawn. If you have many nodes you want to expand, then it is best to set node.expanded=true directly, and then call api.onGroupExpandedOrCollapsed() when finished to get the grid to redraw the grid again just once.
So i modified my code like below:
this.gridOptions.api.forEachNode(node => {
node.expanded = true;
});
this.gridOptions.api.onGroupExpandedOrCollapsed();
Ag-gridDocumentation page inside Group Api
I'm supposing that you are using the row grouping feature, and that you meant that there are 150 grouped rows that are able to be expanded.
Currently your code is getting executed for every single row of data... not just the ones that are able to be expanded. So supposing you have 50 rows or so of data in each group, your calling the setExpanded function 7500 times. You can limit this to just calling the setExpanded on the grouped rows by putting in a check before calling setExpanded:
public expandAll(value:boolean) {
this.gridOptions.api.forEachNode((node) =>{
if (node.group)
node.setExpanded(value);
});
}
testing it on this example, it took roughly 2 seconds for 110 row groups and 5 seconds for 511 row groups in firefox
The API has expandAll and collapseAll:
api.expandAll();
api.collapseAll();
Note that due to the crappy architecture of AG Grid the expansion state (along with row selection etc) is lost if the row data changes or the grid is re-mounted/re-rendered. You should use deltaRowDataMode but make sure you give your rows a unique ID to help prevent this (though this option of course can cause some hard to debug bugs which I have reported).
Also if you want to restore the user expansion in this case you have no choice but to iterate and expand/collapse individual nodes.
Also they don't seem to work on a master-detail (enterprise feature) grid...
I hope this would help, the performance seems to be fine. Took reference from -
https://github.com/ag-grid/ag-grid/issues/2179
But it is always better to check if the groups are present are not. That increases the performance and expanding is much much faster.
this.gridApi.forEachNode((node) => {
if(node?.group) {
node.setExpanded(true)
}
})
I have an update as a complete solution.
Please see this example that I created o Plnkr.
Basically you can use the following code blocks to expand and collapse the tree data on the grid:
At first, imports, definitions and assignments:
import { GridApi } from 'ag-grid-community';
then:
gridApi!: GridApi; // variable
constructor() {}
onGridReady(params: GridReadyEvent) {
this.gridApi = params.api;
// other codes...
}
expand() {
this.gridApi.expandAll();
}
collapse() {
this.gridApi.collapseAll();
}
However if you want to collapse and expand a specific node level groups, you can use the following examples:
collapse2ndLevel() {
this.gridApi.forEachNode((node) => {
if (node.level === 1) {
node.setExpanded(false);
}
});
}
expand2ndLevel() {
this.gridApi.forEachNode((node) => {
if (node.level < 2 && node.isExpandable) {
node.setExpanded(true);
}
});
}
collapse3rdLevel() {
this.gridApi.forEachNode((node) => {
if (node.level === 2 && node.isExpandable) {
node.setExpanded(false);
}
});
}
expand3rdLevel() {
this.gridApi.forEachNode((node) => {
if (node.level < 3 && node.isExpandable) {
node.setExpanded(true);
}
});
}
Please check out this example that I created o Plnkr.
I use server-side row model and single decision for me it is purgeServerSideCashe() after update data. https://www.ag-grid.com/archive/23.2.0/javascript-grid-server-side-model-grouping/#example-purging-caches. It closes all expanded rows

Hiding points in HighCharts on click

I got a HighChart with several 2 series.
Now I want certain points in series 1 to be disabled when I click a link.
This is my code so far:
$('.remove').click(function () {
var chart = $('#plot').highcharts(),
series = chart.series[0];
if (series.data.length) {
chart.series[0].data[0].remove();
}
});
The problem is, that after removing this point, [0] changes to another value and after clicking it again, it goes on and on with deleting.
I just want the points to disappear, this is possible with visible:
visible Since 1.2.0 Read only. The series' visibility state as set by
series.show(), series.hide(), or the initial configuration.
But I just don't manage to implement it the right way in my onClick event.
If I understand you well, you need to keep "place" where the point was? If yes, you can try to use point.update() function and set null value.
Example: http://jsfiddle.net/gd4q4jo0/1/
I solved clicks on a link to delete points like this:
$('.remove').click(function () {
var series = chart.series[0];
var id = $(this).data('id');
if (series.data.length) {
// disable point in graph
chart.series[0].data[id-1].update(
{
y:null
});
}
// delete used tablerow
$(this).closest("tr").fadeOut(50);
});
And I managed to expulse points onClick on the graph with an event, it's working like this:
series: [{
name: 'time',
data: data: [[1, 129386],[2, 123966],[3, 123162],[4, 123245],[5, 124314],[6, 123946],[7, 124156],[8, 123367],[9, 124460],[10, 123366],[11, 123182],[12, 123915],[13, 124627],[14, 123142],[15, 124044],[16, 124346],[17, 123156],[18, 124356],[19, 123511],[20, 124239],[21, 123252],[22, 125169],[23, 125027],[24, 123508],[25, 124065],[26, 122719],[27, 124199],[28, 122968],[29, 124132],[30, 124052],[31, 124383],[32, 123265],[33, 124083],[34, 123855],[35, 124284],[36, 123719],[37, 123213],[38, 124245],[39, 123079],[40, 123721]],
events: {
// if point gets clicked, it'll be deleted
click: function(event) {
console.log(event.point);
var pointId = event.point.x;
$("#hidden-points-table").fadeIn(1000);
$('#hidden-elements').append(pointId + ", ");
event.point.update(
{
y: null
});
// deleting the table row
$("[data-id='"+pointId+"']").closest("tr").fadeOut(50);
}
}
}
Since it was hard to find solutions, I hope this will help some people with it.
This page was really helpful, too.

Trying to auto expand tree grid to the 3rd level with jqGrid

We are currently having a difficult time trying to auto expand a jqGrid treegrid to the 3rd level of the tree so that all children are visible. The current data set is thousands or rows deep and we were forced to dynamically load each node when requested to be expanded, which requires reloading the grid. Expanded node ids are saved in an array as a saved tree state so that the nodes can be re-expanded when the tree is redisplayed. This goes through the process of loading each node from the database as the expansion happens. AS each node is dynamically loaded and expended gridComplete and loadComplete events are handled as expected.
We are trying to trigger the 3rd level expansion by utilizing the save tree state and the existing logic to break out the tree appropriately within the existing logic. The problem we are experiencing is that the tree cannot expand out fast enough in order to be processed, and we can never break the tree apart completely.
Here is the function to iterate through the parents to capture the appropriate ids to expand:
function ExpandGridLevel(level) {
if (ExpandGridLevels == false) {
ExpandTotalLevels = level;
ExpandLevelCurrent = 0;
ExpandGridLevels = true;
}
if (!TreeExpandState) {
TreeExpandState = new Array();
}
$(".treeclick", "#Grid").each(function () {
if ($(this).hasClass("tree-plus")) {
var id = $(this).parents("tr").attr("id");
var rowLevel = $("#MaGrid").getLocalRow(id);
if (rowLevel.level == ExpandLevelCurrent) {
TreeExpandState.push(id);
$(this).removeClass("tree-plus");
$(this).addClass("tree-minus");
}
}
});
$(this).trigger("reloadGrid");
$("#Grid").jqGrid("setGridParam", { datatype: "local" });
ExpandLevelCurrent++;
RefreshGrid();
}
Our gridComplete and loadComplete sections of code:
loadComplete: function (data) {
$("#Grid").jqGrid("setGridParam", { datatype: "local" });
if (TreeExpandState.length == 0) {
setTimeout(function () { ExpandGridLevel (ExpandTotalLevels); }, 3000);
}
}
gridComplete: function () {
if (TreeExpandState) {
var rowId = TreeExpandState.shift();
ExpandNode(rowId);
}
}
Is what we are trying to do possible with jqGrid? If so, how do we know when the tree expansion is truly complete and we can reiterate over the expended grid to begin the expansion of the next level of parents?

Categories

Resources