Is it possible to link all/some of the points of a scatter plotly plot so whenever you click on them a new tab is opened and the hyperlink linked on that point is fired?
I am using plotly within a Django webserver implementation, this means that plotly is rendered with javascript.
You can use the click handler to implement this. But it may be hard to open in new tab, given most browsers try to prevent popups at all times.
var trace1 = {
x: [1, 2, 3],
y: [1, 6, 3],
mode: 'markers',
type: 'scatter',
text: ['Plotly', 'StackOverflow', 'Google'],
hoverinfo: 'text',
marker: { size: 12 }
};
var links = ['https://plot.ly/', 'http://stackoverflow.com/', 'https://google.com/'];
var data = [ trace1 ];
var layout = {
title:'Hyperlinked points'
};
var myPlot = document.getElementById('myDiv');
Plotly.newPlot(myPlot, data, layout);
myPlot.on('plotly_click', function(data){
if (data.points.length === 1) {
var link = links[data.points[0].pointNumber];
// Note: window navigation here.
window.location = link;
}
});
<!-- Plotly.js -->
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="myDiv" style="width: 480px; height: 300px;"></div>
Related
I'm trying to plot 10+ scatter plots on one page using Plotly. However, I've noticed that if more than 8 plots are created, some of the plots show a square with a frowny face. I've read that this means Chrome failed to render the chart.
It does not matter how complex the chart is. Even 9 basic charts will cause one not to render. See below for example with code to replicate the issue:
https://codepen.io/ceds/pen/wvrGoLa
HTML
<div id="graphDiv1"></div>
<div id="graphDiv2"></div>
<div id="graphDiv3"></div>
<div id="graphDiv4"></div>
<div id="graphDiv5"></div>
<div id="graphDiv6"></div>
<div id="graphDiv7"></div>
<div id="graphDiv8"></div>
<div id="graphDiv9"></div>
<div id="graphDiv10"></div>
<div id="graphDiv11"></div>
<div id="graphDiv12"></div>
<div id="graphDiv13"></div>
JS
for (let i = 1;i < 13;i++) {
var trace1 = {
x: [1, 2, 3, 4],
y: [4, 1, 5, 3],
mode: 'markers',
type: 'scattergl',
marker:{
size: [30, 80, 50, 80],
color: 'blue'
},
name: 'Third Trace'
};
var data = [trace1];
var layout = {
title: `Chart ${i}`
};
var graphDiv = document.getElementById('graphDiv' + i.toString());
Plotly.newPlot(graphDiv, data, layout);
}
Any idea how to get past this ?
Seems like there is a Github issue open on this. The issue is not resolved as it's a limitation of Chrome:
https://github.com/plotly/plotly.js/issues/2333
I want to plot the scattered data with a colorscale and the errorbars should have the same colorscale.
I found answers for plotly R (How do you make plotly error bars follow a colorscale?), but I can't translate it to js. Also using the name attribute for this seems strange to me.
Here is a minimal example (https://jsfiddle.net/ztqoemkd/1)
var trace1 = {
type: 'scatter',
mode: 'markers',
y: [2, 1, 3],
marker: {
size: 20,
color: [1, 2, 3],
showscale: true
},
error_y: {
type:'data',
array: [0.5, 0.7, 0.5],
color: [1, 2, 3]
}
}
Plotly.newPlot('myDiv', [trace1])
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="myDiv"></div>
I still don't know, if can be done self consistently with plotly itself.
At least, I could now develop this work around with d3:
// get colors from data points
rgbs = Plotly.d3.selectAll('.points .point').data().map(d => d.mcc)
// apply colors to errorbars
Plotly.d3.selectAll('.yerror').style('stroke', (d,i) => rgbs[i])
Here is the full demo:
https://jsfiddle.net/vor6e9wj
and the output is
Note 1: After zooming, the errorbars are again black.
Note 2: It does not work for scattergl.
Edit 1: To keep the colors while zooming, the work around can be attached to plotly_relayout (see https://jsfiddle.net/9s64y5cv).
In a chart I render using Plotly.js, I define titles for each axis. When mouse hovering the items within the chart, a popup is shown, but the "labels" shown do not use the titles I had defined.
For example, the default value for the x axis is x. I defined hellox as title and that value is show in the chart, but not when mouse hovering a value (x is still shown).
See a live example here of what I mean: https://codepen.io/anon/pen/qoGQvx
I've been looking a the documentation and I didn't find anything so far that did exactly what I wanted: simply change the labels in the popup.
Also the question is quite old, I would like to write a solution I came up when facing the same problem. I did define a var text array for hover info which I filled with the labels for x, y and z values. Please have a look at the following fiddle where I use a heatmap plot for demonstration (this is what I am using in my project, but it can be easily adapted for your chart option): http://jsfiddle.net/zLc5y63g/
This is the html code:
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<body>
<br><br>
<!-- Source and on-click event for plotly.js -->
<div id="plotly_chart" style="width: 90%; height: 270px"></div>
And this the JavaScript:
var zValues = [[1, 20, 30], [20, 1, 60], [30, 60, 1]];
var yValues = ['data1', 'data2', 'data3'];
var xValues = ['condition1', 'condition2', 'condition3'];
var config = {
displaylogo: false
};
// fill in 'text' array for hover
var text = zValues.map (function(zValues, i) { return zValues.map (function (value, j) {
return ` ID: ${yValues[i]}<br> Condition: ${xValues[j]}<br> Value: ${value.toFixed(2)} `
});
});
Plotly.newPlot('plotly_chart', [{x: xValues, y: yValues, z: zValues, text: text, hoverinfo: 'text', hoverlabel: {bgcolor: '#41454c'}, type: 'heatmap', colorscale: 'Viridis'}], config );
Maybe this is still useful.
// ignore this comment - required to post the following jsfiddle.net link!
Please see https://jsfiddle.net/68bf25vh/
If you click a doughnut segment, the corresponding tooltip displays, which is the correct functionality.
The problem is triggering this desired functionality when a user clicks one of the buttons below the doughnut. E.g. when a user clicks the 'Trigger Segment 1 Click' button. The tooltip should display above segment 1 (just as if the user had clicked segment 1).
A bonus would be having the tooltip displaying above segment 1 initially too, but not essential.
Any help much appreciated :)
Please note
Using Chart.js v 2.5.0. I've read a few articles suggesting to use a showTooltip() method, e.g. chart.showTooltip([chart.segments[0]], true); Unfortunately this method does not exist in this version.
Found this https://stackoverflow.com/a/37989832, but this displays all tooltips. Just want the tooltip of the active (current) segment to display.
You can use the following function to display corresponding tooltip, when clicked on an external button :
function showTooltip(chart, index) {
var segment = chart.getDatasetMeta(0).data[index];
chart.tooltip._active = [segment];
chart.tooltip.update();
chart.draw();
}
When calling the function, pass chart-instance and button-index as the first and second argument respectively.
BONUS :
To initially show the tooltip of segment-1, add the following config in your chart options :
animation: {
onComplete: function() {
if (!isChartRendered) {
showTooltip(myChart, 0);
isChartRendered = true;
}
}
}
* declare a variable named isChartRendered in global-scope and set it to false
ᴡᴏʀᴋɪɴɢ ᴇxᴀᴍᴘʟᴇ ⧩
var isChartRendered = false;
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['Segment 1', 'Segment 2', 'Segment 3'],
datasets: [{
data: [10, 10, 10]
}]
},
options: {
events: ['click'],
cutoutPercentage: 70,
legend: {
display: false
},
tooltips: {
displayColors: false
},
onClick: function(evt, elements) {},
// BONUS: show segment 1 tooltip initially
animation: {
onComplete: function() {
if (!isChartRendered) {
showTooltip(myChart, 0);
isChartRendered = true;
}
}
}
}
});
$(document).on('click', 'button', function() {
var $this = $(this),
index = $this.index();
showTooltip(myChart, index);
});
function showTooltip(chart, index) {
var segment = chart.getDatasetMeta(0).data[index];
chart.tooltip._active = [segment];
chart.tooltip.update();
chart.draw();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="width:400px;height:400px;">
<canvas id="myChart"></canvas>
</div>
<div style="margin-top:50px;">
<button>Trigger Segment 1 Click</button>
<button>Trigger Segment 2 Click</button>
<button>Trigger Segment 3 Click</button>
</div>
For Chart.js 3 the GRUNT`s solution needs some modifications:
chart.tooltip.setActiveElements([{datasetIndex: 0, index: index}]);
chart.tooltip.update();
chart.render();
If you want to change also the segment style:
const activeSegment = chart.getDatasetMeta(0).data[index];
chart.updateHoverStyle([{element: activeSegment, datasetIndex: 0}], null, true);
I am attempting to create an onclick event on my plotly chart. Following the documentation i have created the following chart:
var graphDiv = document.getElementById('uniqueId');
Plotly.newPlot('uniqueId', charData, layout);
graphDiv.on('plotly_click', function (data) {
var i = 0;
})
However when i run this i get the following error:
graphDiv.on is not a function
So can anyone tell me what im doing wrong?
Note i have also attempted with jquery:
$('#uniqueId').on('plotly_click', function(){})
This didnt throw an error but the function was not called when clicking the chart.
fiddle:
https://jsfiddle.net/c1kt3r82/127/
In your fiddle you are using plotly-basic.js, you would need to use plotly-latest.min.js to get the on functionality.
TESTER = document.getElementById('tester');
Plotly.plot( TESTER, [{
x: [1, 2, 3, 4, 5],
y: [1, 2, 4, 8, 16] }], {
margin: { t: 0 } } );
TESTER.on('plotly_click', function(data){
alert('did you just click on me?!')
})
/* Current Plotly.js version */
console.log( Plotly.BUILD );
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="tester" style="width:600px;height:250px;"></div>