I have a structure of chart like this:-
data: {
cols: [
{
id: 'Type',
type: 'string'
},
{
id: 'percentage',
type: 'number'
},
{
id: 'tooltip',
role: 'tooltip',
type: 'string',
p: { html: true }
}
],
rows: [
{
c: [
{
v: typeA
},
{
v: 20
},
{
v: 'my Tooltip content'
}
]
},
{
c: [
{
v: 'typeB'
},
{
v: 80
}
]
}
]
},
I want to disable the tooptip only for typeB and but should work with typeA. Is this possible in google charts? (tooptip trigger:none option disable it for whole chart)
when using custom tooltips, if the tooltip column is null or ''
the chart will replace with the default tooltip
to avoid, provide a custom tooltip that is hidden with css
see following working snippet...
google.charts.load('current', {
callback: function () {
var data = google.visualization.arrayToDataTable([
['Type', 'Percent'],
['typeA', 20],
['typeB', 80]
]);
// add tooltip column
data.addColumn({type: 'string', role: 'tooltip', p: {html: true}});
// build tooltip
for (var i = 0; i < data.getNumberOfRows(); i++) {
switch (data.getValue(i, 0)) {
// set visible tooltip
case 'typeA':
data.setValue(i, 2,
'<div class="ggl-tooltip"><div><span>' +
data.getValue(i, 0) + '</span></div><div>' +
data.getValue(i, 1) + '</div></div>'
);
break;
// set hidden tooltip
case 'typeB':
data.setValue(i, 2, '<div class="hdn-tooltip"><div>');
break;
}
}
var container = document.getElementById('chart_div');
var pieChart = new google.visualization.PieChart(container);
pieChart.draw(data, {
tooltip: {
isHtml: true
}
});
},
packages: ['corechart']
});
.hdn-tooltip {
display: none;
visibility: hidden;
}
.ggl-tooltip {
border: 1px solid #E0E0E0;
font-family: Arial, Helvetica;
font-size: 10pt;
padding: 12px 12px 12px 12px;
}
.ggl-tooltip div {
padding-top: 6px;
}
.ggl-tooltip span {
font-weight: bold;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
Related
I would like to simply show/hide the labels of the edges of my vis.js-network - is this possible?
I have tried to update the edges in the vis.js-data structure:
Delete the label property - doesn't work
Set the label to undefined - doesn't work
Set the label to '' - doesn't work
Set the label to ' ' - works
I would prefer a network-wise toggle of some kind, but I haven't found one.
Is there a better way of doing this?
An alternative to updating the label property on each edge is to change the font color to be transparent for all edges. The setOptions() method can be used to update the options and will apply all edges in the network. The options edges.font.color and edges.font.strokeColor should both be updated, then returned to their original values to display the edges.
Example below and also at https://jsfiddle.net/rk9s87ud/.
var nodes = new vis.DataSet([
{ id: 1, label: "Node 1" },
{ id: 2, label: "Node 2" },
{ id: 3, label: "Node 3" },
{ id: 4, label: "Node 4" },
{ id: 5, label: "Node 5" },
]);
var edges = new vis.DataSet([
{ from: 1, to: 2, label: 'Edge 1' },
{ from: 2, to: 3, label: 'Edge 2' },
{ from: 3, to: 4, label: 'Edge 3' },
{ from: 4, to: 5, label: 'Edge 4' },
]);
var container = document.getElementById("mynetwork");
var data = {
nodes: nodes,
edges: edges,
};
var options = {
nodes: {
// Set any other options, for example node color to gold
color: 'gold'
},
edges: {
font: {
// Set to the default colors as per the documentation
color: '#343434',
strokeColor: '#ffffff'
}
}
}
var hiddenEdgeTextOptions = {
edges: {
font: {
// Set the colors to transparent
color: 'transparent',
strokeColor: 'transparent'
}
}
};
var network = new vis.Network(container, data, options);
var displayLabels = true;
document.getElementById('toggleLabels').onclick = function() {
if(displayLabels){
// Apply options for hidden edge text
// This will override the existing options for text color
// This does not clear other options (e.g. node.color)
network.setOptions(hiddenEdgeTextOptions);
displayLabels = false;
} else {
// Apply standard options
network.setOptions(options);
displayLabels = true;
}
}
#mynetwork {
width: 600px;
height: 160px;
border: 1px solid lightgray;
}
<script src="https://visjs.github.io/vis-network/standalone/umd/vis-network.min.js"></script>
<button id="toggleLabels">Toggle labels</button>
<div id="mynetwork"></div>
Can we show a different graph say pie chart in the tooltip hover in the bar chart using nvd3?
Here is one sample which is doing the job. The logic behind this approach is the following:
Disable the default tooltip
Prepare helper chart(donut chart in the example) which is going to be used as a tooltip
In the callback of the main chart (bar chart) register event listeners on the bar elements
mousemove - to show and position the custom donut chart tooltip
mouseleave - to hide the tooltip
var donutContainer = document.getElementById('donut-chart');
var chartDonut;
var chartBar;
nv.addGraph(function() {
chartBar = nv.models.discreteBarChart()
.x(d => d.label)
.y(d => d.value)
.margin({left: 80})
.showValues(true)
.duration(250);
// Disable the default tooltip
chartBar.tooltip.enabled(false);
d3.select('#main-chart svg')
.datum(historicalBarChart)
.call(chartBar);
nv.utils.windowResize(chartBar.update);
return chartBar;
}, () => {
// After the chart is loaded register some listeners
// to determine when to show/hide the custom tooltip chart
var bars = d3.selectAll('.nv-bar');
bars.on('mousemove', function(bar) {
// When the mouse is moved across bar
// show the tooltip chart and update tooltip position
d3.select('#donut-chart svg')
.datum(bar.details)
.call(chartDonut);
nv.utils.windowResize(chartDonut.update);
var e = window.event;
donutContainer.style.display = 'block';
donutContainer.style.left = e.clientX + "px";
donutContainer.style.top = e.clientY - 50 + "px";
});
// When the mouse leaves a bar then hide the tooltip
bars.on('mouseleave', e => donutContainer.style.display = 'none');
});
// Prepare the donut chart for the tooltip
nv.addGraph(function() {
// Note here that duration(0) is used. This is done
// because when you move the cursor between bars with different
// child group count( e.g. OS and Shoes) error is thrown
chartDonut = nv.models.pieChart()
.x(d => d.name)
.y(d => d.value)
.width(150)
.height(150)
.donut(true)
.duration(0)
.showLegend(false);
chartDonut.tooltip.enabled(false);
return chartDonut;
});
// Sample data
const historicalBarChart = [{
key: 'Cumulative Return',
values: [{
label: 'Cars',
value: 1500000,
details: [{
name: 'Audi',
value: 500000
}, {
name: 'Mercedes',
value: 700000
}, {
name: 'Ford',
value: 300000
}]
}, {
label: 'Mobile',
value: 1000000,
details: [{
name: 'iPhone',
value: 500000
}, {
name: 'Samsung',
value: 410000
}, {
name: 'Lenovo',
value: 90000
}]
}, {
label: 'OS',
value: 1500000,
details: [{
name: 'OSX',
value: 500000
}, {
name: 'Windows',
value: 500000
}, {
name: 'Linux',
value: 500000
}]
}, {
label: 'Shoes',
value: 1400000,
details: [{
name: 'Addidas',
value: 500000
}, {
name: 'Nike',
value: 500000
}, {
name: 'Puma',
value: 100000
}, {
name: 'Something',
value: 300000
}]
}]
}];
text {
font: 12px sans-serif;
}
svg {
display: block;
}
html,
body,
#main-chart,
svg {
height: 100%;
width: 400px;
}
#donut-chart {
position: absolute;
height: 150px;
width: 150px;
background-color: white;
z-index: 1;
pointer-events: none;
display: none;
border: 1px solid black;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.6/nv.d3.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js" charset="utf-8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.6/nv.d3.js"></script>
<div id="main-chart"> <svg></svg></div>
<div id="donut-chart"><svg></svg></div>
I use highmaps with "Rich information on click" in a json format. For this I used a previously existing example. However, there are a few parts that I would like to add.
Separate container in which the extra information (countryChart) is
displayed instead of a single container in which both the map and
the extra information are shown Solution given by ppotaczek
Is it possible to display the total per category if no country is selected. In the example below, this means that in (Countrychart)
graph, cat1: 14, cat2: 3 and cat3: 15 (Canada, US and India added
together) are shown. Solution given by ppotaczek
The flags are not displayed, I cannot figure out why this is. Solution given by Emad
In this example I have made a start on the graph hopefully this is a good basis for the extra functionality.
$.ajax({
url: 'https://cdn.rawgit.com/highcharts/highcharts/v6.0.4/samples/data/world-population-history.csv',
success: function() {
var jsondata = {
"data": [{
"value": "8",
"code": "in",
"name": "india",
"testdata": [{
"vcount": "3"
}, {
"vcount": null
}, {
"vcount": "5"
}]
}, {
"value": "15",
"code": "us",
"name": "united states",
"testdata": [{
"vcount": "9"
}, {
"vcount": "2"
}, {
"vcount": "4"
}]
}, {
"value": "9",
"code": "ca",
"name": "canada",
"testdata": [{
"vcount": "2"
}, {
"vcount": "1"
}, {
"vcount": "6"
}]
}]
}
var mapChart;
var countryChart;
var graphdata = [];
var graphdataf = [];
var valuecount;
var countries = {};
$.each(jsondata.data, function(i, item) {
var graphval = [];
var value = item.value;
var code = item.code;
var name = item.name;
graphval.push(code);
graphval.push(value);
graphdata.push(graphval);
$.each(item.testdata, function(j, itemval) {});
countries[item.code] = {
name: item.name,
code3: item.code,
data: item.testdata
};
});
var data = [];
for (var code3 in countries) {
if (countries.hasOwnProperty(code3)) {
$.each(countries[code3].data, function(j, itemval) {
//var graphvaldata = [];
var value = itemval.vcount;
data.push({
name: countries[code3].name,
code3: code3,
value: value,
});
});
}
}
// Wrap point.select to get to the total selected points
Highcharts.wrap(Highcharts.Point.prototype, 'select', function(proceed) {
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
var points = mapChart.getSelectedPoints();
if (points.length) {
if (points.length === 1) {
$('#info #flag').attr('class', 'flag ' + points[0].flag);
$('#info h2').html(points[0].name);
} else {
$('#info #flag').attr('class', 'flag');
$('#info h2').html('Comparing countries');
}
$('#info .subheader').html('<h4>Historical population</h4><small><em>Shift + Click on map to compare countries</em></small>');
if (!countryChart) {
countryChart = Highcharts.chart('country-chart', {
chart: {
height: 250,
spacingLeft: 0
},
credits: {
enabled: false
},
title: {
text: null
},
subtitle: {
text: null
},
xAxis: {
tickPixelInterval: 50,
crosshair: true,
categories: ['cat1', 'cat2', 'cat3']
},
yAxis: {
title: null,
opposite: true
},
tooltip: {
split: true
},
plotOptions: {
series: {
animation: {
duration: 500
},
marker: {
enabled: false
}
}
}
});
}
$.each(points, function(i, point) {
var data,
dataRaw = countries[point['hc-key']].data;
if (dataRaw) {
data = dataRaw.map((p) => parseInt(p.vcount));
}
// Update
if (countryChart.series[i]) {
countryChart.series[i].update({
name: this.name,
data: data,
type: points.length > 1 ? 'column' : 'column'
}, false);
} else {
countryChart.addSeries({
name: this.name,
data: data,
type: points.length > 1 ? 'column' : 'column'
}, false);
}
});
while (countryChart.series.length > points.length) {
countryChart.series[countryChart.series.length - 1].remove(false);
}
countryChart.redraw();
} else {
$('#info #flag').attr('class', '');
$('#info h2').html('');
$('#info .subheader').html('');
if (countryChart) {
countryChart = countryChart.destroy();
}
}
});
// Initiate the map chart
mapChart = Highcharts.mapChart('container', {
title: {
text: 'Population history by country'
},
subtitle: {
text: 'Source: The World Bank'
},
mapNavigation: {
enabled: true,
buttonOptions: {
verticalAlign: 'bottom'
}
},
colorAxis: {
type: 'logarithmic',
endOnTick: false,
startOnTick: false,
minColor: '#fff',
maxColor: '#3D1C5C',
min: 5,
max: 15,
},
tooltip: {
footerFormat: '<span style="font-size: 10px">(Click for details)</span>'
},
credits: {
enabled: false
},
series: [{
data: graphdata,
mapData: Highcharts.maps['custom/world'],
joinBy: 'hc-key',
name: 'Total Play',
allowPointSelect: true,
cursor: 'pointer',
states: {
select: {
color: '#a4edba',
borderColor: 'black',
dashStyle: 'shortdot'
}
}
}]
});
}
});
* {
font-family: sans-serif;
}
#wrapper {
height: 500px;
width: 1000px;
margin: 0 auto;
padding: 0;
overflow: visible;
}
#container {
float: left;
height: 500px;
width: 700px;
margin: 0;
}
#info {
float: left;
width: 270px;
padding-left: 20px;
margin: 100px 0 0 0;
border-left: 1px solid silver;
}
#info h2 {
display: inline;
font-size: 13pt;
}
#info .f32 .flag {
vertical-align: bottom !important;
}
#info h4 {
margin: 1em 0 0 0;
}
#media screen and (max-width: 920px) {
#wrapper,
#container,
#info {
float: none;
width: 100%;
height: auto;
margin: 0.5em 0;
padding: 0;
border: none;
}
}
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/maps/modules/map.js"></script>
<script src="https://code.highcharts.com/mapdata/custom/world.js"></script>
<!-- Flag sprites service provided by Martijn Lafeber, https://github.com/lafeber/world-flags-sprite/blob/master/LICENSE -->
<link rel="stylesheet" type="text/css" href="//github.com/downloads/lafeber/world-flags-sprite/flags32.css" />
<div id="wrapper">
<div id="container"></div>
<div id="info">
<span class="f32"><span id="flag"></span></span>
<h2></h2>
<div class="subheader">Click countries to view history</div>
<div id="country-chart"></div>
</div>
</div>
Thanks in advance for your help!
I can aswer to your third question : The flags are not displayed, I cannot figure out why this is.
The problem is with this line :
$('#info #flag').attr('class', 'flag ' + points[0].flag);
There is no flag property in points object, you can change it to this :
$('#info #flag').attr('class', 'flag ' + points[0]["hc-key"]);
And you will have the flag now.
https://jsfiddle.net/vq26m8nb/7/
As to your questions:
Both charts are already in separate containers. You can remove the div with 'wrapper' id to split them so that they do not appear side by side. Check this example: https://jsfiddle.net/BlackLabel/8jo7vzty/
Yes, for example you can call select on some point with an additional argument and sum the data in the wrapped select method (depending on that additional argument).
if (points.length) {
...
if (arguments[3]) {
totalData = [];
Highcharts.objectEach(countries, function(el){
el.data.forEach(function(val, i){
if (totalData[i]) {
totalData[i] += parseInt(val.vcount)
} else {
totalData[i] = parseInt(val.vcount);
}
});
});
$('#info h2').html('Total data');
countryChart.series[0].setData(totalData);
mapChart.series[0].points[0].select(false, false, true);
}
} else if (!arguments[3]) {
$('#info #flag').attr('class', '');
$('#info h2').html('');
$('#info .subheader').html('');
if (countryChart) {
countryChart = countryChart.destroy();
}
}
...
mapChart = Highcharts.mapChart('container', ...);
mapChart.series[0].points[0].select(true, false, true);
Live demo: https://jsfiddle.net/BlackLabel/mg7x3kje/
The flags are not displayed because your points do not have flag property. You can add them in the way as #Emad Dehnavi suggested.
I was trying this example in `c3js.
Demo
Does anyone know how to increase the font size of the Tooltip contents (both title and value)?
Any help would be appreciated.
You can set a custom font-size to the tspan element:
tspan {
font-size: 20px;
}
Override the font value for the following selectors:
.c3-tooltip th {
/* for the header */
}
.c3-tooltip td.name {
/* for the title cells */
}
.c3-tooltip td.value {
/* for the value cells */
}
EXAMPLE
var chart = c3.generate({
data: {
columns: [
['data1', 30000, 20000, 10000, 40000, 15000, 250000],
['data2', 100, 200, 100, 40, 150, 250]
],
axes: {
data2: 'y2'
}
},
axis : {
y : {
tick: {
format: d3.format("s")
}
},
y2: {
show: true,
tick: {
format: d3.format("$")
}
}
},
tooltip: {
format: {
title: function (d) { return 'Data ' + d; },
value: function (value, ratio, id) {
var format = id === 'data1' ? d3.format(',') : d3.format('$');
return format(value);
}
// value: d3.format(',') // apply this format to both y and y2
}
}
});
.c3-tooltip th {
/* for the header */
color: red !important;
}
.c3-tooltip td.name {
/* for the title cells */
color: green;
}
.c3-tooltip td.value {
/* for the value cells */
color: blue;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.12/c3.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.12/c3.min.js"></script>
<div id='chart'></div>
Whenever a series gets clicked on a legend in a Google Line chart, it seems that a line appears above the data trendline. Is it possible to stop this behavior? I could not find anything in the docs.
An example of this:
when the legend is clicked, the entire series is selected,
which means the row value will be null
chart.getSelection() will return something like...
{row: null, column 1}
vs. when a data point is clicked / selected, the row will have a number reference row: 1, etc...
as such, use the 'select' event listener and cancel the selection when the row is null
chart.setSelection([]);
see following working snippet...
google.charts.load('current', {
callback: function () {
var container = document.getElementById('chart_div');
var chart = new google.visualization.LineChart(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({type: 'string', label: 'Year'});
// series 0
dataTable.addColumn({type: 'number', label: 'Category A'});
dataTable.addColumn({type: 'string', role: 'tooltip', p: {html: true}});
// series 1
dataTable.addColumn({type: 'number', label: 'Category B'});
dataTable.addColumn({type: 'string', role: 'tooltip', p: {html: true}});
// series 2
dataTable.addColumn({type: 'number', label: 'Category C'});
dataTable.addColumn({type: 'string', role: 'tooltip', p: {html: true}});
dataTable.addRows([
['2014', 1000, null, 2000, null, 3000, null],
['2015', 2000, null, 4000, null, 6000, null],
['2016', 3000, null, 6000, null, 9000, null],
]);
for (var i = 0; i < dataTable.getNumberOfRows(); i++) {
dataTable.setValue(i, 2, getTooltip(i, 1));
dataTable.setValue(i, 4, getTooltip(i, 3));
dataTable.setValue(i, 6, getTooltip(i, 5));
}
function getTooltip(rowIndex, columnIndex) {
return '<div class="ggl-tooltip"><span>' +
dataTable.getValue(rowIndex, 0) + ': </span>' +
dataTable.getFormattedValue(rowIndex, columnIndex) + '</div>';
}
// use 'select' listener to disable selection on legend click
google.visualization.events.addListener(chart, 'select', function () {
var selection = chart.getSelection();
if (selection.length > 0) {
if (selection[0].row === null) {
chart.setSelection([]);
}
}
});
chart.draw(dataTable, {
legend: {
position: 'bottom'
},
pointSize: 4,
tooltip: {
isHtml: true
}
});
},
packages: ['corechart']
});
.ggl-tooltip {
border: 1px solid #E0E0E0;
font-family: Arial, Helvetica;
font-size: 10pt;
padding: 12px 12px 12px 12px;
}
.ggl-tooltip span {
font-weight: bold;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>