Highlight area programmatically - Chart.js - charts

I'm using Chart.js (doughnut chart) and I would like to ask if is there any choice to highlight area programmatically? I mean - when I click on a button, then the specific area will be highlighted.
Thanks for your reply.

Just loop through the doughnut segments, match based on label and swap / restore the fill color.
function highlight(label) {
myDoughnutChart.segments.forEach(function (segment, i) {
if (segment.label == label) {
if (segment.fillColor == segment.highlightColor)
segment.restore(["fillColor"]);
else
segment.fillColor = segment.highlightColor;
myDoughnutChart.render();
}
})
}
Fiddle - http://jsfiddle.net/35of1Lzg/
I've disabled tooltips and the tooltip highlight by setting tooltipEvents = [], but if you want them back you can always remove it from the options, but then hover / mouseout and the button click will do the same thing.
To popup the tooltip too when highlighting use this
function highlight(label) {
myDoughnutChart.segments.forEach(function (segment) {
if (segment.label == label) {
if (segment.fillColor == segment.highlightColor)
segment.restore(["fillColor"]);
else
segment.fillColor = segment.highlightColor;
myDoughnutChart.render()
}
})
var activeSegements = [];
myDoughnutChart.segments.forEach(function (segment) {
if (segment.fillColor === segment.highlightColor) {
activeSegements.push(segment)
}
});
myDoughnutChart.showTooltip(activeSegements, true)
}
http://jsfiddle.net/jdr5381e/

FYI the fiddles are no longer working, you'll need to replace the links to the Chart.min.js
I used these to get them working: https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.1.1/Chart.js

Related

Highcharts tooltip refresh not working correctly

I am trying to show the tooltip across multiple charts when the user hovers over any one of the charts.
series: {
point: {
events: {
mouseOver: function() {
syncTooltip(this.series.chart.container, this.x);
}
}
}
}
function syncTooltip(container, p) {
_.each(totalCharts, (chartType) => {
let chartContainer = $('#'+chartType);
let chart = chartContainer.highcharts();
if (chart && chart.tooltip && container.id != chart.container.id) {
//I am fetching all points in chart.series whose 'x' value matches with the function parameter 'p'
var points = process(chart.series);
if(points.length > 0) {
chart.tooltip.refresh(points);
}
}
});
}
The points array is getting populated correctly. However the charts tooltips are not showing up correctly. Even the highlighted points in the charts are showing up wrong.
In the above image, I added labels for each data point (x and y coordinates separated by a space).
In the second chart, point three is highlighted whereas point two should be the one highlighted to be in sync with first chart

ChartJS: Custom tooltip always displaying

Im using ChartJS to create a graph on my website.
Im trying to create a custom tooltip. According to the documentation, this should be easy:
var myPieChart = new Chart(ctx, {
type: 'pie',
data: data,
options: {
tooltips: {
custom: function(tooltip) {
// tooltip will be false if tooltip is not visible or should be hidden
if (!tooltip) {
return;
}
}
}
}
});
My problem is that the tooptip is never false and because of this my custom tooltip is always displayed.
Please see this JSFiddle (line 42 is never executed)
Question: Is it a bug that tooltip is never false, or am I missing something?
The custom tooltip option is used for when you want to create/style your own tooltip using HTLM/CSS outside of the scope of the canvas (and not use the built in tooltips at all).
In order to do this, you must define a place outside of your canvas to contain your tooltip (e.g. a div) and then use that container within your tooltips.custom function.
Here is an example where I used a custom tooltip to display the hovered pie chart section percentage in the middle of the chart. In this example I'm generating my tooltip inside a div with id "chartjs-tooltip". Notice how I interact with this div in my tooltips.custom function to position and change the value.
Also, the correct way to check if the tooltip should be hidden is to check it's opacity. The tooltip object will always exist, but when it should not be visible, the opacity is set to 0.
Chart.defaults.global.tooltips.custom = function(tooltip) {
// Tooltip Element
var tooltipEl = document.getElementById('chartjs-tooltip');
// Hide if no tooltip
if (tooltip.opacity === 0) {
tooltipEl.style.opacity = 0;
return;
}
// Set Text
if (tooltip.body) {
var total = 0;
// get the value of the datapoint
var value = this._data.datasets[tooltip.dataPoints[0].datasetIndex].data[tooltip.dataPoints[0].index].toLocaleString();
// calculate value of all datapoints
this._data.datasets[tooltip.dataPoints[0].datasetIndex].data.forEach(function(e) {
total += e;
});
// calculate percentage and set tooltip value
tooltipEl.innerHTML = '<h1>' + (value / total * 100) + '%</h1>';
}
// calculate position of tooltip
var centerX = (this._chartInstance.chartArea.left + this._chartInstance.chartArea.right) / 2;
var centerY = ((this._chartInstance.chartArea.top + this._chartInstance.chartArea.bottom) / 2);
// Display, position, and set styles for font
tooltipEl.style.opacity = 1;
tooltipEl.style.left = centerX + 'px';
tooltipEl.style.top = centerY + 'px';
tooltipEl.style.fontFamily = tooltip._fontFamily;
tooltipEl.style.fontSize = tooltip.fontSize;
tooltipEl.style.fontStyle = tooltip._fontStyle;
tooltipEl.style.padding = tooltip.yPadding + 'px ' + tooltip.xPadding + 'px';
};
Here is the full codepen example.
I hope that helps clear things up!

How to add row selection checkbox for ag-grid

Is there a way to have row selection checkbox for each row without configuring a special column for it? I mean to add propertie for my gridOptions and to see checkbox near each row, then to get all selected rows?
All the documentation I read is showing how to do it by adding it to specific column.
Thanks,
You can still have row selection without having a checkbox column - you can either simply have selection based on row selection, or have a column render with a checkbox in it (with a custom cell renderer).
Take a look at the Selection Documentation for more information about row selection, and at the Cell Rendering Documentation about cell rendering
I know it is too late to answer on this post. But It may help someone who look for solution still. It works with checkbox selection on each row (click anywhere on the row to select checkbox), shift/control and toggle selection. Here I have given only necessary code.
vm.gridOptions = {
appSpecific : {},
onRowClicked : onRowClicked,
onGridReady : function() {
let api = vm.gridApi = vm.gridOptions.api;
}
};
function toggleSelect(row) {
row.node.setSelected(!row.node.isSelected(), false);
}
function onRowClicked(row) {
var appSpecific = vm.gridOptions.appSpecific;
var lastSelectedRow = appSpecific.lastSelectedRow;
var shiftKey = row.event.shiftKey;
// if not modifier keys are clicked toggle row
if (!shiftKey) {
toggleSelect(row);
} else if (lastSelectedRow !== undefined) {
if (shiftKey) {
var startIndex, endIndex;
// Get our start and end indexes correct
if (row.rowIndex < lastSelectedRow.rowIndex) {
startIndex = row.rowIndex;
endIndex = lastSelectedRow.rowIndex;
}
else {
startIndex = lastSelectedRow.rowIndex;
endIndex = row.rowIndex;
}
// Select all the rows between the previously selected row and the
// newly clicked row
for (var i = startIndex; i <= endIndex; i++) {
vm.gridApi.selectIndex(i, true, true);
}
}
}
// Store the recently clicked row for future use
appSpecific.lastSelectedRow = row;
getSelection(); // Implement functionality to get selected rows
}

Display values outside of pie chart in chartjs

When I hover on pie chart, the values are displayed in tooltip. However, I want to display values outside of pie chart. I want to make chart like this image:
How to do this?
I was able to get something similar working using chart.js v2.3.0 using both the plugin API and extending chart types API. You should be able to take this as a starting point and tweak it to your needs.
Here is how it looks after being rendered.
Note, this requires digging deep into chart.js internals and could break if they change the way tooltips are positioned or rendered in the future. I also added a new configuration option called showAllTooltips to enable selectively using the plugin on certain charts. This should work for all chart types, but I am currently only using it for pie, doughnut, bar, and line charts so far.
With that said, here is a working solution for the image above.
Chart.plugins.register({
beforeRender: function (chart) {
if (chart.config.options.showAllTooltips) {
// create a namespace to persist plugin state (which unfortunately we have to do)
if (!chart.showAllTooltipsPlugin) {
chart.showAllTooltipsPlugin = {};
}
// turn off normal tooltips in case it was also enabled (which is the global default)
chart.options.tooltips.enabled = false;
// we can't use the chart tooltip because there is only one tooltip per chart which gets
// re-positioned via animation steps.....so let's create a place to hold our tooltips
chart.showAllTooltipsPlugin.tooltipsCollection = [];
// create a tooltip for each plot on the chart
chart.config.data.datasets.forEach(function (dataset, i) {
chart.getDatasetMeta(i).data.forEach(function (sector, j) {
// but only create one for pie and doughnut charts if the plot is large enough to even see
if (!_.contains(['doughnut', 'pie'], sector._chart.config.type) || sector._model.circumference > 0.1) {
var tooltip;
// create a new tooltip based upon configuration
if (chart.config.options.showAllTooltips.extendOut) {
// this tooltip reverses the location of the carets from the default
tooltip = new Chart.TooltipReversed({
_chart: chart.chart,
_chartInstance: chart,
_data: chart.data,
_options: chart.options.tooltips,
_active: [sector]
}, chart);
} else {
tooltip = new Chart.Tooltip({
_chart: chart.chart,
_chartInstance: chart,
_data: chart.data,
_options: chart.options.tooltips,
_active: [sector]
}, chart);
}
// might as well initialize this now...it would be a waste to do it once we are looping over our tooltips
tooltip.initialize();
// save the tooltips so they can be rendered later
chart.showAllTooltipsPlugin.tooltipsCollection.push(tooltip);
}
});
});
}
},
afterDraw: function (chart, easing) {
if (chart.config.options.showAllTooltips) {
// we want to wait until everything on the chart has been rendered before showing the
// tooltips for the first time...otherwise it looks weird
if (!chart.showAllTooltipsPlugin.initialRenderComplete) {
// still animating until easing === 1
if (easing !== 1) {
return;
}
// animation is complete, let's remember that fact
chart.showAllTooltipsPlugin.initialRenderComplete = true;
}
// at this point the chart has been fully rendered for the first time so start rendering tooltips
Chart.helpers.each(chart.showAllTooltipsPlugin.tooltipsCollection, function (tooltip) {
// create a namespace to persist plugin state within this tooltip (which unfortunately we have to do)
if (!tooltip.showAllTooltipsPlugin) {
tooltip.showAllTooltipsPlugin = {};
}
// re-enable this tooltip otherise it won't be drawn (remember we disabled all tooltips in beforeRender)
tooltip._options.enabled = true;
// perform standard tooltip setup (which determines it's alignment and x, y coordinates)
tooltip.update(); // determines alignment/position and stores in _view
tooltip.pivot(); // we don't actually need this since we are not animating tooltips, but let's be consistent
tooltip.transition(easing).draw(); // render and animate the tooltip
// disable this tooltip in case something else tries to do something with it later
tooltip._options.enabled = false;
});
}
},
});
// A 'reversed' tooltip places the caret on the opposite side from the current default.
// In order to do this we just need to change the 'alignment' logic
Chart.TooltipReversed = Chart.Tooltip.extend({
// Note: tooltipSize is the size of the box (not including the caret)
determineAlignment: function(tooltipSize) {
var me = this;
var model = me._model;
var chart = me._chart;
var chartArea = me._chartInstance.chartArea;
// set caret position to top or bottom if tooltip y position will extend outsite the chart top/bottom
if (model.y < tooltipSize.height) {
model.yAlign = 'top';
} else if (model.y > (chart.height - tooltipSize.height)) {
model.yAlign = 'bottom';
}
var leftAlign, rightAlign; // functions to determine left, right alignment
var overflowLeft, overflowRight; // functions to determine if left/right alignment causes tooltip to go outside chart
var yAlign; // function to get the y alignment if the tooltip goes outside of the left or right edges
var midX = (chartArea.left + chartArea.right) / 2;
var midY = (chartArea.top + chartArea.bottom) / 2;
if (model.yAlign === 'center') {
leftAlign = function(x) {
return x >= midX;
};
rightAlign = function(x) {
return x < midX;
};
} else {
leftAlign = function(x) {
return x <= (tooltipSize.width / 2);
};
rightAlign = function(x) {
return x >= (chart.width - (tooltipSize.width / 2));
};
}
overflowLeft = function(x) {
return x - tooltipSize.width < 0;
};
overflowRight = function(x) {
return x + tooltipSize.width > chart.width;
};
yAlign = function(y) {
return y <= midY ? 'bottom' : 'top';
};
if (leftAlign(model.x)) {
model.xAlign = 'left';
// Is tooltip too wide and goes over the right side of the chart.?
if (overflowLeft(model.x)) {
model.xAlign = 'center';
model.yAlign = yAlign(model.y);
}
} else if (rightAlign(model.x)) {
model.xAlign = 'right';
// Is tooltip too wide and goes outside left edge of canvas?
if (overflowRight(model.x)) {
model.xAlign = 'center';
model.yAlign = yAlign(model.y);
}
}
}
});

jqplot tooltip display on touch instead of jqplotDataHighlight or higlightMouseOver or highlightMouseDown

I am using the jqplotDataHighlight option to display the tooltip on a chart on MouseOver.
$("#"+sTargetId).bind('jqplotcustomDataHighlight',
function (ev, seriesIndex, pointIndex, data) {
var chart_left = $("#"+sTargetId).offset().left,
chart_right = ($(window).width() - ($("#"+sTargetId).offset().left + $("#"+sTargetId).outerWidth())),
chart_top = $("#"+sTargetId).offset().top,
x = oPlot.axes.xaxis.u2p(data[0]), // convert x axis units to pixels
y = oPlot.axes.yaxis.u2p(data[1]);;
var tooltipData = data[1]*scale;
$('#tooltip').css({left:chart_left+x, top:chart_top+y, marginRight:chart_right});
$('#tooltip').html('<span style="font-family: Arial;font-size:'+sTooltip+';font:bold;color:#000000;">' +sXDisplay+': '+ tooltipData + '</span>');
$('#tooltip').show();
});
$("#"+sTargetId).bind('jqplotcustomDataUnhighlight',
function (ev, seriesIndex, pointIndex, data) {
$('#tooltip').empty();
$('#tooltip').hide();
});
It works fine.On iPad, i want the tooltip to be displayed on some touch event.How can i implement it?
// prop: highlightMouseOver
// True to highlight slice when moused over.
// This must be false to enable highlightMouseDown to highlight when clicking on a slice.
this.highlightMouseOver = true;
// prop: highlightMouseDown
// True to highlight when a mouse button is pressed over a slice.
// This will be disabled if highlightMouseOver is true.
this.highlightMouseDown = false;
I have observed that only the above two options are available. How can I implement it on touchstart or so?
Displaying the tooltip on doubleclick or any other event would also be helpful
Maybe you already figured this out. Here's what works for me. I am using jquerymobile, in jquery.jqplot.js version 0.9.7r635 line No: 2290 change mousemove to vmousemove. If you are using cursor: {followMouse: true} , then things should work out of the box, I have a fixed position for my tooltip, but on mousemove the top and left values did not get applied so i hardcoded the top and left for the tooltip div .jqplot-cursor-tooltip to appear in the same position as it does on click. Although its not a very good solution but I havent seen weird behavior till now. Hope this helps !