Highcharts plotlines above area using DOM - javascript

I want plotlines to be rendered the last(right now area is overlaying them). If i use Zindex width increases and it doesn't look as neath, i also try line-width.
I did this approach for markers to be above plotlines but it doesnt work for plotlines above area. Am i doing something wrong?
componentDidRender() {
if(this.shadowRoot) {
var markers0 = this.shadowRoot.querySelector('.highcharts-markers.highcharts-series-0');
var plotLines0 = this.shadowRoot.querySelector('.highcharts-plot-lines-4');
var area0 = this.shadowRoot.querySelector('.highcharts-area-series');
/// plotlines below markers - works
if(plotLines0 && plotLines0.parentNode && markers0)
plotLines0.parentNode.insertBefore(markers0, plotLines0.nextSibling);
// markers below area - works
// markers0.parentNode.insertBefore(area0, markers0.nextSibling);
//area below plotlines- doesnt work
//if(area0 && area0.parentNode && plotLines0)
//area0.parentNode.insertBefore(plotLines0, area0.nextSibling);
if i run that code for area below plotlines nothing changes.

You can remove the second to last grid line by:
chart: {
events: {
load: function() {
var prevTick;
Highcharts.objectEach(this.yAxis[0].ticks, function(tick) {
if (tick.isLast) {
prevTick.gridLine.destroy();
}
prevTick = tick;
});
}
}
},
Live demo: http://jsfiddle.net/BlackLabel/obam5yxg/

Related

Highcharts synchronize tooltip on multiple charts with multiple series

I am trying to synchronize shared tooltip across multiple charts, each having multiple series.
The problem is in the below example, the tooltip always shows the 3 series, even though at that particular point there are only two series present.
1) How do I make sure that a series is shown in tooltip only when it is actually present?
2) How do I make sure the tooltip is closed when we move out of the chart?
JSFiddle: https://jsfiddle.net/qoL7fx27/1/
Code for synchronization in fiddle:
$('#container').bind('mousemove touchmove touchstart', function (e) {
var chart,
point,
i,
event;
for (i = 0; i < Highcharts.charts.length; i = i + 1) {
chart = Highcharts.charts[i];
var points = [];
// Find coordinates within the chart
event = chart.pointer.normalize(e.originalEvent);
// Get the hovered point
for(var j=0; j<chart.series.length; j++) {
point = chart.series[j].searchPoint(event, true);
points.push(point);
}
chart.tooltip.refresh(points);
}
});
Here is my solution. It's perfectly working for me. I made adjustments based on Synchronisation of multiple charts
Demo here
The following code shows/hides the tooltip and makes sure they are aligned on mousemove and mouseleave.
Note that I found that I only need to find the first point searched and use it to show/hide the tooltip. It's because all my time series share the same x values.
$("#container").bind("mousemove mouseleave", function(e) {
for (let i = 0; i < Highcharts.charts.length; ++i) {
let hart = Highcharts.charts[i];
let event = chart.pointer.normalize(e.originalEvent); // Find coordinates within the chart
let point;
for (let j = 0; j < chart.series.length && !point; ++j) {
point = chart.series[j].searchPoint(event, true);
}
if (!point) return;
if (e.type === "mousemove") {
point.onMouseOver();
chart.xAxis[0].drawCrosshair(event, point); // Show the crosshair
} else {
point.onMouseOut();
chart.tooltip.hide(point);
chart.xAxis[0].hideCrosshair();
}
}
});
Keep reseting the reset function so as to disallow HighCharts resetting the points -- we take over the control.
Highcharts.Pointer.prototype.reset = function() {
return undefined;
};
1) How do I make sure that a series is shown in tooltip only when it is actually present?
The unwanted behavior is caused by searchPoint function - it returns the nearest point even though the x position doesn't mach with other points. So if the series has only one point it'll be always found.
Solution:
Manually select points to display in tooltip.formatter:
formatter: function() {
var outputString = '';
this.points.forEach(function(point) {
if (point.x === this.x) {
outputString += "<span style='color:" + point.color + "'>\u25CF</span> " + point.series.name + ": <b>" + point.y + "</b><br/>";
}
}, this);
return outputString;
}
API reference: https://api.highcharts.com/highcharts/tooltip.formatter
2) How do I make sure the tooltip is closed when we move out of the chart?
Restore the default Highcharts.Pointer.prototype.reset function by removing these lines:
Highcharts.Pointer.prototype.reset = function() {
return undefined;
};
Demo for both questions: https://jsfiddle.net/BlackLabel/2mxxrk5n/
Update:
I posted the wrong answer for the second question. This code hides tooltips:
$('#container').bind('mouseout', function(e) {
Highcharts.charts.forEach(function(chart) {
chart.tooltip.hide();
// undo point highlight
chart.series.forEach(function(series) {
series.points.forEach((point) => point.setState(''));
});
});
});
can you please tell me how to highlight the corresponding points in each chart? As of now, the tooltip shows correctly, however the points are not highlighted in three charts
This piece of highlights points:
points.forEach(function(point_) {
if (point_) {
point_.highlight(e);
}
}, this);
To achieve the desired behavior you must provide a logic for filtering points that should be Highlighted. Here's a very simplified example adjusted to this particular case:
// provide a logic for filtering points
if(points[0] && points[1].x > 0) {
points.pop(); // remove the unwanted point
}

Kendo Chart inside bootstrap carousel

I have a question about kendo chart inside carousel.
In this example:
http://dojo.telerik.com/ExoqI
you can see that Kendo chart doesn't redriwe itself when carousel changes slide.
Does anyone has idea how to solve it?
I also try this logic where I check current carousel index and if it is index before chart element then do the logic:
let currentCarouselIndex = $('#myCarousel div.active').index();
console.log(currentCarouselIndex)
if (currentCarouselIndex == 1){ //next slide will be chartanalysis chart
setTimeout(function(){
let chart = $("#chart").data("kendoChart");
chart.redraw();
},50);
$("#myCarousel").off();
}
}
);
but then the problem is when you go first left with left carousel-control, the chart is not redrawn properly.
Any idea how to fix this problem is appriciated :)Thanks!
The Bootstrap carousel slide.bs event returns a relatedTarget telling you which item is loading next. You could use that to check for a particular chart DIV and then redraw that DIV's chart:
$("#myCarousel").on('slide.bs.carousel', function (e) {
var IsChart = $(e.relatedTarget).find("#chart").length > 0;
var IsChart2 = $(e.relatedTarget).find("#chart1").length > 0;
if (IsChart){
setTimeout(function () {
let chart = $("#chart").data("kendoChart");
chart.redraw();
}, 50);
}
if (IsChart2){
setTimeout(function () {
let chart1 = $("#chart1").data("kendoChart");
chart1.redraw();
}, 50);
}
});
DEMO

Animate transition between values on amcharts svg bar graph

I have a bar chart I built using the 'amcharts' plugin.
The graph updates its values when the a dropdown menu item is selected,
I am trying to get the graph to animate the transition between the values when it changes, currently it either resets the whole animation and animates from '0', or if animateAgain() is commented out (line 142 in js) it jumps to the new value. This code is called after the values have been updated:
// Animate between values instead of resetting animation?
chart.animateAgain(); // Resets animation
chart.validateData(); // redraws the chart with new data
I've searched the docs and google but can't find anything to help with this, anyone have any ideas or pointers in the right direction? Is it possible? Here's the codepen :
http://codepen.io/bananafarma/pen/yewbJQ
Cheers!!
You can use amCharts' own Animate plugin.
It adds a new method to chart objects animateData().
function updateGraph() {
var newData = chart.dataProvider.slice();
if( document.getElementById('data-set').value == 1 ) {
newData[0].gain= 3.8;
newData[1].gain= 8.5;
newData[2].gain= 3;
newData[3].gain= 1.9;
}
else if ( document.getElementById('data-set').value == 2 ) {
console.log("yo");
newData[0].gain= 2.6;
newData[1].gain= 8.6;
newData[2].gain= 13.8;
newData[3].gain= 4;
}
else if ( document.getElementById('data-set').value == 3 ) {
newData[0].gain= 4.8;
newData[1].gain= 10.6;
newData[2].gain= 15.9;
newData[3].gain= 16;
}
// use Animate plugin
chart.animateData( newData, { duration: 1000 } );
}
Here's your updated working demo.

Flot event for range updates in response to panning/zooming

For Flot, is there an event that fires after the user has completed panning or zooming using the mouse scroll wheel (after the range.xaxis.to/from and range.yaxis.to/from have settled)? I am trying to use the line below to update the selection on an overview plot after the user has panned or zoomed in the main plot, but am finding that either the update to the overview plot happens after panning or zooming(not both).
$("#plot").bind("mouseup scroll",updateOverviewSelection);
Edit: http://jsfiddle.net/apandit/nu2rr58h/9/
In the jsfiddle, I am unable to pan in the main plot and the cursor does not seem to change back to normal. The user can click and drag in the overview plot to make a selection, which leads to zooming in the main plot. I would also like to be able to allow the user to pan and zoom in the main plot and have the selection box in the overview plot updated; I am attempting to do this by binding the updateOverviewSelection method to the plot div for the scroll and mouseup events. Is there an event in Flot that fires every time the x- and y-axis limits are updated?
The solution to this issue is below. The issue was that setting the overview plot's selection(overview.setSelection(ranges);) was triggering the zoom method because it was bound to the plotselected event in the overview plot. At the end of the zoom method, the main plot was plotted, which was again calling the overview.setSelection(ranges); line in the updateOverviewSelection method. To prevent this ping-pong between the two methods/events, I added an updatingOverviewSelection flag.
http://jsfiddle.net/apandit/nu2rr58h/12/
var datasets = [[
[0,0],[1,1],[2,2],[3,3],[4,4],[5,5],[6,6],[7,7],[8,8],[9,9]
],
[
[0,0],[-1,-1],[-2,-2],[-3,-3],[-4,-4],[-5,-5],[-6,-6],[-7,-7],[-8,-8],[-9,-9]
]];
var plot = $.plot("#plot",datasets,{
pan: {
interactive: true
},
zoom: {
interactive: true,
mode: "x"
}
});
var overview = $.plot("#overview",datasets,{
selection: {
mode: "xy"
}
});
var updatingOverviewSelection = false;
$("#plot").bind("plotpan plotzoom",updateOverviewSelection);
$("#overview").bind("plotselected", zoom);
function zoom(event,ranges) {
if(updatingOverviewSelection) {
updatingOverviewSelection = false;
}
else {
var options = plot.getOptions();
options.xaxes[0].min = ranges.xaxis.from;
options.xaxes[0].max = ranges.xaxis.to;
options.yaxes[0].min = ranges.yaxis.from;
options.yaxes[0].max = ranges.yaxis.to;
plot = $.plot("#plot",datasets,options);
}
};
// get the window x-axis and y-axis ranges for the main plot
// and set the selection in the overview plot to those ranges
function updateOverviewSelection(event) {
var options = plot.getOptions();
var ranges = {
xaxis: {
from: options.xaxes[0].min,
to: options.xaxes[0].max
},
yaxis: {
from: options.yaxes[0].min,
to: options.yaxes[0].max
}
};
updatingOverviewSelection = true;
overview.setSelection(ranges);
};

How to color Google Column Chart's every bar differently and keep them as it is

Though I have successfully colored the bars of google chart individually but not able to keep them when we hover mouse over it. It is getting reset back to blue(which is default).
Here is the jsfiddle of what I have done jsfiddle.
I tried to control the hover behaviour with multiple ways like below.
This I am keeping outside (document.ready) but inside script tag.
1)
$('#chart_div').hover(
function() {
$('#chart_client').hide(); // chart_client is another google chart div.
}, function() { // just for testing I was doing hide/show of that.
$('#chart_client').show();
}
);
2)
$("#chart_div").on({
mouseenter: function () {
$('#chart_client').hide();
},
mouseleave:function () {
$('#chart_client').show();
}
},'rect');
3)
google.visualization.events.addListener('#chart_div', 'ready', function () {
$('#chart_div rect').mouseover(function (e) {
alert('hello');
});
});
I must be doing something wrong, could you please tell me what and where.
I solved it using below code. Earlier I was trying to create charts using dynamically adding rows into chart(please visit my jsfiddle) but with this below approach I am first preparing data(converting dynamic to static) and adding that static data in to chart's 'arrayToDataTable' method.
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawUserKeywordChart);
function drawUserKeywordChart() {
var val = 'Tax:47;Finance:95;Awards:126;Bank:137;Debt:145;';
var length = val.length;
var array = [];
//preparing data
while(length>0){
var sepAt = val.indexOf(";");
var value = parseInt(val.substring(val.indexOf(":")+1, sepAt));
array.push(val.substring(0, val.indexOf(":")));
array.push(value);
val = val.substring(val.indexOf(";")+1, length);
length = val.length;
}
var data = google.visualization.arrayToDataTable([
['Keyword', 'Occurences', { role: 'style' }],
[array[0], array[1], '#8AA3B3'],
[array[2], array[3], '#A9B089'],
[array[4], array[5], '#848C49'],
[array[6], array[7], '#44464A'],
[array[8], array[9], '#704610'],
]);
var options = {
title: 'Keyword Matches',
width: 660,
height: 450,
titleTextStyle:{bold:true,fontSize:20},
legend:{position:'none'}
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_keyword1'));
chart.draw(data, options);
}
Please advice if you find anything wrong here or you have better approach than this.

Categories