Google chart legends - Overlapping text - charts

I'm using google chart in my page but the legend text is Overlapped, as the image bellow:
This is my code:
var dataTable = new google.visualization.DataTable();
dataTable.addColumn("date", "Data");
dataTable.addColumn("number", "Ton./Hora");
dataTable.addColumn("number", "Ton./Hora Equiv.");
dataTable.addColumn("number", "Peso (Ton.)");
for (var i = 0; i < dados.length; i++) {
var temp = new Date(dados[i].DT_FIM);
dataTable.addRow([new Date(temp.getFullYear(), temp.getMonth())
,dados[i].TON_HORA
,dados[i].TON_HORA_EQUIV
,dados[i].PES_LIQUI_UNMET]);
}
var date_formatter = new google.visualization.DateFormat({
pattern: "MMM/yyyy"
});
date_formatter.format(dataTable, 0);
var options = {
hAxis: {title: 'Período (mês/ano)'},
series: {0: {type: 'line', targetAxisIndex:0},
1: {type: 'line', targetAxisIndex:0},
2: { type: 'bars', targetAxisIndex: 1 }
},
legend: { position: "top", textStyle: { fontSize: 14 } },
width: 1200,
height: 500
};
var chart = new google.visualization.ComboChart(document.getElementById("div-Equipamento-Produtividade"));
chart.draw(dataTable, options);
My charts is on bootstrap tab nav:
<div id="div-Graficos" class="panel-collapse in">
<div class="panel-body">
<ul id="tab-Graficos" class="nav nav nav-tabs nav-justified" role="tablist">
<li role="presentation" class="active">Equipamento - OEE</li>
<li role="presentation">Equipamento - T2</li>
<li role="presentation">Equipamento - Produtividade</li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane fade in active" id="div-Grafico-OEE">
<div id="div-Equipamento-OEE" style="width: 900px; height: 500px"></div>
</div>
<div role="tabpanel" class="tab-pane fade" id="div-Grafico-T2">
<div id="div-Equipamento-T2" style="width: 900px; height: 500px"></div>
</div>
<div role="tabpanel" class="tab-pane fade" id="div-Grafico-Produtividade">
<div id="div-Equipamento-Produtividade" style="width: 1200px; height: 500px"></div>
</div>
</div>
</div>
</div>
I tried to change the position to "bottom" but the problem continue
What i'm making wrong?

check that the chart is not being drawn while hidden
see the following snippet, the chart is hidden by default,
then shown once the chart's 'ready' event fires
notice, it produces the same result as posted in the question...
google.charts.load('current', {
callback: function () {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn("date", "Data");
dataTable.addColumn("number", "Ton./Hora");
dataTable.addColumn("number", "Ton./Hora Equiv.");
dataTable.addColumn("number", "Peso (Ton.)");
for (var i = 0; i < 12; i++) {
var temp = new Date();
dataTable.addRow([new Date(temp.getFullYear(), i)
,(i + 2) * 6
,(i + 1) * 12
,(i + 0) * 18]);
}
var date_formatter = new google.visualization.DateFormat({
pattern: "MMM/yyyy"
});
date_formatter.format(dataTable, 0);
var options = {
hAxis: {title: 'Período (mês/ano)'},
series: {0: {type: 'line', targetAxisIndex:0},
1: {type: 'line', targetAxisIndex:0},
2: { type: 'bars', targetAxisIndex: 1 }
},
legend: { position: "top", textStyle: { fontSize: 14 } },
width: 1200,
height: 500
};
var container = document.getElementById("div-Equipamento-Produtividade");
var chart = new google.visualization.ComboChart(container);
google.visualization.events.addListener(chart, 'ready', function () {
container.style.display = null;
});
chart.draw(dataTable, options);
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="div-Equipamento-Produtividade" style="display: none;"></div>
however, if the container is shown before drawing the chart,
the legend turns out nicely...
google.charts.load('current', {
callback: function () {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn("date", "Data");
dataTable.addColumn("number", "Ton./Hora");
dataTable.addColumn("number", "Ton./Hora Equiv.");
dataTable.addColumn("number", "Peso (Ton.)");
for (var i = 0; i < 12; i++) {
var temp = new Date();
dataTable.addRow([new Date(temp.getFullYear(), i)
,(i + 2) * 6
,(i + 1) * 12
,(i + 0) * 18]);
}
var date_formatter = new google.visualization.DateFormat({
pattern: "MMM/yyyy"
});
date_formatter.format(dataTable, 0);
var options = {
hAxis: {title: 'Período (mês/ano)'},
series: {0: {type: 'line', targetAxisIndex:0},
1: {type: 'line', targetAxisIndex:0},
2: { type: 'bars', targetAxisIndex: 1 }
},
legend: { position: "top", textStyle: { fontSize: 14 } },
width: 1200,
height: 500
};
var container = document.getElementById("div-Equipamento-Produtividade");
container.style.display = null;
var chart = new google.visualization.ComboChart(container);
chart.draw(dataTable, options);
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="div-Equipamento-Produtividade" style="display: none;"></div>

Every framework or code that hides the chart DIV using "display: none" will make legends to overlap when the chart is draw inside an inactive DIV.
Hidding the chart DIV with "visibility: hidden" works fine, with no overlapping.
I had this issue and only solved it coding the NAV features by myself, without using Bootstrap/JQuery/etc...

Related

Open popup after flyTo in Leaflet?

I have a Leaflet-map with a layer containing markers with popups using bindPopup. I written this function that flies to the next marker onclick:
const makeFlyTo = () => {
const button = document.getElementById("next");
L.DomEvent.on(button, "click", function(e) {
if (currentView === data.length) {
currentView = 0;
}
map.flyTo(
[data[currentView].lat, data[currentView].lng],
{ zoom },
{
animate: true,
duration: 3
}
);
currentView++;
});
};
I would be nice if the popup opened up on "arrival". Any idea how this can be done?
We have to open marker first and they use FlyTo.
marker.openPopup();
map.flyTo([value['lat'], value['lng']], 15);
As mentioned in the comments, If we use flyTo and then open Popup then most of the times the view adjustment made by popup in map is incorrect.
map.panTo([value['lat'], value['lng']], 15).on('zoomend', () => { setTimeout(()=>marker.openPopup(), 3000) })
OR
map.panTo([value['lat'], value['lng']], 15).on('zoomend', () => marker.openPopup())
Example -
var map = L.map("map").setView([46.76336, -71.32453], 16);
var OpenStreetMap_Mapnik = L.tileLayer(
"http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
{
maxZoom: 19,
attribution:
'© OpenStreetMap'
}
).addTo(map);
function addRowTable(marker, code, coords) {
var tr = document.createElement("tr");
var td = document.createElement("td");
td.textContent = code;
tr.appendChild(td);
tr.onclick = () => {
marker.openPopup();
map.flyTo([value['lat'], value['lng']], 15);
};
document.getElementById("t_points").appendChild(tr);
}
function addMarker(code, lat, lng) {
var marker = L.marker([lat, lng]);
marker.title = code;
marker.bindPopup(code);
marker.addTo(map);
addRowTable(marker, code, [lat, lng]);
}
$(document).ready(function () {
var points = [
["M02KM262", 46.76336, -71.32453],
["M10KM052", 46.76186, -71.32247],
["83KM081", 46.76489, -71.32664],
["83KM082", 46.76672, -71.32919]
];
for (var i = 0; i < points.length; i++) {
addMarker(points[i][0], points[i][1], points[i][2]);
}
});
html, body, .full, #map{
margin: 0;
padding:0;
height: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script>
<script src="https://unpkg.com/leaflet#1.0.3/dist/leaflet.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://unpkg.com/leaflet#1.0.3/dist/leaflet.css" rel="stylesheet"/>
<div class="row full">
<div class="col col-sm-3 full" style="overflow: auto;">
<h3 >List</h3>
<table class="table table-bordered">
<thead>
<tr>
<th>Codes</th>
</tr>
</thead>
<tbody id="t_points"></tbody>
</table>
</div>
<div id="map" class="col col-sm-9 full"></div>
</div>

Can't display leaflet.js map in Vue component

I am getting error:
Here is my code:
var guestContent = Vue.extend({
template: `
<div>
test
</div>
`,
data: function ()
{
return {
map: false
}
},
ready: function()
{
this.map = L.map('map').setView([51.505, -0.09], 13);
},
methods:
{
}
}
);
var userContent = Vue.extend({
template: `
<p>SOME USER CONTENT TEST</p>
`
});
var adminContent = Vue.extend({
template: `
<p>ADMIN CONTENT TEST</p>
<div id="map" style="width: 600px; height: 400px"></div>
`
});
I am getting next error: Map container not found.
The DOM is not ready when you try to create the map. Wrap it with this.$nextTick().
ready: function() {
this.$nextTick(function () {
this.map = L.map('map').setView([51.505, -0.09], 13);
}
},
You created 3 different components: guestContent, userContent, adminContent.
But you load map only in guestContent which don't has tag with id="map". You need to add map container to template.
var guestContent = Vue.extend({
template: `
<div id="map" style="width: 600px; height: 400px"></div>
`,
data: function ()
{
return {
map: false
}
},
ready: function()
{
this.map = L.map('map').setView([51.505, -0.09], 13);
},
methods:
{
}
}
);
Vue.component('guest-content', guestContent)
new Vue({
el: '#app'
})
Check this example http://jsfiddle.net/3dqeuoqL/

How can I correctly hide columns in my Google chart?

I have a google spreadsheet with with 5 columns in it. column 0 is the title column and the other four have the values.
I want to do a different column chart (using google charts API) for each of the four value columns, but I can't hide the other columns. When I use
chartview1.setColumns([ 0, 1 ]);
it works fine! But when I do
chartview2.setColumns([0, 2 ]);
I get the error:
Invalid column index 2. Should be an integer in the range [0-1]
Similarly, when I do tableview2.setColumns([ 0, 2]); and then implement the dataView as a table (rather than a columnChart)
it works fine and hides the other columns.
Can anyone tell me what I am doing wrong? I can provide the full code if necessary.
I tried using the method outlined here :
how to hide column in google charts table
but this doesn't work for me.
Thanks
UPDATE: Here is the full code:
<html>
<head>
<meta charset="UTF-8">
<title>Service Desk Performance (Weekly)</title>
<style>
h2 {
font-family:"helvetica",arial, sans-serif;
}
.tableHeader {
background:transparent;
}
.tableHeader th {
background-image:none !important;
background:#ccc !important;
color:#fff !important;
border-bottom:2px solid #222 !important;
}
.tableRow {
background:#e9e9e9;
}
</style>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart", "table"]});
function initialize() {
var opts = {sendMethod: 'auto'};
// Replace the data source URL on next line with your data source URL.
var query = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1c6r2xi4eY4iGcgWCRQcPce8A79OhDN4v5khkkC2WFVM/edit?usp=sharing', opts);
-
// Optional request to return only column C and the sum of column B, grouped by C members.
//query.setQuery('select C, sum(B) group by C');
// Send the query with a callback function.
query.send(handleQueryResponse);
}
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var data = response.getDataTable();
var chartview1 = new google.visualization.DataView(data);
var tableview1 = new google.visualization.DataView(data);
var chartview2 = new google.visualization.DataView(data);
var tableview2 = new google.visualization.DataView(data);
var chartview3 = new google.visualization.DataView(data);
var tableview3 = new google.visualization.DataView(data);
var chartview4 = new google.visualization.DataView(data);
var tableview4 = new google.visualization.DataView(data);
chartview1.setColumns([ 0, 1 ]);
tableview1.setColumns([ 0, 1 ]);
chartview2.setColumns([ 0, 2 ]);
tableview2.setColumns([ 0, 2 ]);
chartview3.setColumns([ 0, 3 ]);
tableview3.setColumns([ 0, 3 ]);
chartview4.setColumns([ 0, 4 ]);
tableview4.setColumns([ 0, 4 ]);
var test= chartview2.getNumberOfColumns();
console.log(test);
var chartOptions = {
vAxis: {
title: 'Requests',
gridlines: {color: 'transparent'},
baseline:0
},
chartArea: {
left:100,
top:40,
width:"100%"
},
hAxis: { title: 'Assignee Group' },
colors: [ '#00ccff', '#afafaf' ],
animation: {
startup: true,
duration: 500,
easing: 'in'
},
legend: {position:'none'}
};
var tableOptions = {
showRowNumber: false,
right:100,
top:40,
width: '100%',
alternatingRowStyle: false,
cssClassNames: {
headerRow: 'tableHeader',
tableRow: 'tableRow',
tableCell: 'tableCell'
}
};
var chart1 = new google.visualization.ColumnChart(document.getElementById('chart1'));
var table1 = new google.visualization.Table(document.getElementById('table1'));
chart1.draw(chartview1, chartOptions);
table1.draw(tableview1, tableOptions);
var chart2 = new google.visualization.ColumnChart(document.getElementById('chart2'));
var table2 = new google.visualization.Table(document.getElementById('table2'));
chart2.draw(chartview2, chartOptions);
table2.draw(tableview2, tableOptions);
var chart3 = new google.visualization.ColumnChart(document.getElementById('chart3'));
var table3 = new google.visualization.Table(document.getElementById('table3'));
chart3.draw(chartview3, chartOptions);
table3.draw(tableview3, tableOptions);
var chart4 = new google.visualization.ColumnChart(document.getElementById('chart4'));
var table4 = new google.visualization.Table(document.getElementById('table4'));
chart4.draw(chartview4, chartOptions);
table4.draw(tableview4, tableOptions);
}
google.setOnLoadCallback(initialize);
</script>
</head>
<body>
<h2>Week 1</h2>
<div class="row">
<div style="float:left;width:70%;">
<div id="chart1" style="width:100%; height:600px;position:relative;"></div>
</div>
<div style="float:right;width:30%;">
<div id="table1" style="width:100%;margin:10px 40px 0 0;"></div>
</div>
<div style="clear:both"></div>
</div>
<hr>
<h2>Week 2</h2>
<div class="row">
<div style="float:left;width:70%;">
<div id="chart2" style="width:100%; height:600px;position:relative;"></div>
</div>
<div style="float:right;width:30%;">
<div id="table2" style="width:100%;margin:10px 40px 0 0;"></div>
</div>
<div style="clear:both"></div>
</div>
<h2>Week 3</h2>
<div class="row">
<div style="float:left;width:70%;">
<div id="chart3" style="width:100%; height:600px;position:relative;"></div>
</div>
<div style="float:right;width:30%;">
<div id="table3" style="width:100%;margin:10px 40px 0 0;"></div>
</div>
<div style="clear:both"></div>
</div>
<hr>
<h2>Week 4</h2>
<div class="row">
<div style="float:left;width:70%;">
<div id="chart4" style="width:100%; height:600px;position:relative;"></div>
</div>
<div style="float:right;width:30%;">
<div id="table4" style="width:100%;margin:10px 40px 0 0;"></div>
</div>
<div style="clear:both"></div>
</div>
</body>
</html>
I have had very similar issues to this - I create a 5 column DataTable from an array of analytic data and then dynamically construct a DataView in order to hide different sets of columns as and when the user chooses options on the page and finally display as an AreaChart. I found that hiding the last 2 columns using either view.hideColumns([3,4]) or view.setColumns([0,1,2]) works ok, but any attempt to hide a column that results in a non-contiguous set of column indices results in a failure of the AreaChart to display the result - it sounds like your ColumnChart has exactly the same issue.
The only solution I've discovered thus far is to make a copy of the view after the columns have been hidden. This creates a new view which has contiguous column indices and which will correctly populate the chart. It shouldn't be necessary, but I can't find any other way around the issue so far.
So in your case:
// create view and hide unwanted columns as before
var chartview2 = new google.visualization.DataView(data);
chartview2.setColumns([ 0, 2 ]);
// make a copy of the view to create contiguous index set
var chartview2_copy = new google.visualization.DataView(chartview2);
// use the view copy with the ColumnChart
var chart2 = new google.visualization.ColumnChart(document.getElementById('chart2'));
chart2.draw(chartview2_copy, chartOptions);
This isn't pretty, but it worked for me, so perhaps the same will solve your issues also.

How to change Google Charts number format for controllers?

When implementing a dashboard using Google Charts we are able to change the format of displayed quantities in tables with google.visualization.NumberFormat().
However, we haven't been able to find a way to change number formats in controllers. We would like to accomplish what the image shows:
We looked in the documentation for Google Charts controllers, but we couldn't find anything helpful for this. Any help is appreciated. :)
The google API has a built in function for this.
options:{
ui:{
format:{
prefix:'$',
}
}
Did a small fiddle for it, link.
More info about configuration here and here.
You could specify ui.cssClass option to to assign the custom CSS class to the control:
programmaticSlider = new google.visualization.ControlWrapper({
'controlType': 'NumberRangeFilter',
'containerId': 'programmatic_control_div',
'options': {
'filterColumnLabel': 'Salary',
'ui': { 'cssClass': 'currencyfilter' }
}
});
and then specify rule for a thumb label:
.currencyfilter .google-visualization-controls-rangefilter-thumblabel:before {
color: brown;
content: '$';
}
Complete example
google.load('visualization', '1', { 'packages': ['corechart', 'controls'] });
google.setOnLoadCallback(drawChart);
function drawChart() {
var dashboard = new google.visualization.Dashboard(
document.getElementById('programmatic_dashboard_div'));
// We omit "var" so that programmaticSlider is visible to changeRange.
var programmaticSlider = new google.visualization.ControlWrapper({
'controlType': 'NumberRangeFilter',
'containerId': 'programmatic_control_div',
'options': {
'filterColumnLabel': 'Salary',
'ui': { 'labelStacking': 'vertical', 'cssClass': 'currencyfilter' }
}
});
var programmaticChart = new google.visualization.ChartWrapper({
'chartType': 'PieChart',
'containerId': 'programmatic_chart_div',
'options': {
'width': 300,
'height': 300,
'legend': 'none',
'chartArea': { 'left': 15, 'top': 15, 'right': 0, 'bottom': 0 },
'pieSliceText': 'value'
}
});
var data = google.visualization.arrayToDataTable([
['Name', 'Salary'],
['Mike', 10000],
['Jim', 8000],
['Alice', 12500],
['Bob', 7000]
]);
var formatter = new google.visualization.NumberFormat({ prefix: '$' });
formatter.format(data, 1);
dashboard.bind(programmaticSlider, programmaticChart);
dashboard.draw(data);
}
.currencyfilter .google-visualization-controls-rangefilter-thumblabel:before {
color: brown;
content: '$';
}
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<div id="programmatic_dashboard_div" style="border: 1px solid #ccc">
<table class="columns">
<tr>
<td>
<div id="programmatic_control_div" style="padding-left: 2em; min-width: 250px"></div>
</td>
<td>
<div id="programmatic_chart_div"></div>
</td>
</tr>
</table>
</div>

Lbal and legend with spiderweb in dojox chart

Here is my code :
I need to make a spiderweb graph with a legend in blue here.
3 axys
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6.0/dojo/dojo.xd.js"></script>
<script>
dojo.require("dojox.charting.Chart2D");
dojo.require("dojox.charting.axis2d.Default");
dojo.require("dojox.charting.plot2d.Default");
dojo.require("dojox.charting.plot2d.Spider");
dojo.require("dojox.charting.axis2d.Base");
dojo.require("dojox.charting.widget.Legend");
dojo.ready(
function(Chart, Default, Default, Spider, Base,Legend){
var chart1 = new dojox.charting.Chart("chart1");
chart1.addPlot("default", {
type: "Spider",
labelOffset: -10,
seriesFillAlpha: 0.2,
markerSize: 3,
precision: 0,
divisions: 11,
spiderType: "polygon"
});
var data= [ {"J":0,"S":0,"I":0},
{"J":10,"S":10,"I":10},
{"J":7,"S":4,"I":8} ];
chart1.addSeries("min", {data: data[0] }, { fill: "blue" });
chart1.addSeries("max", {data: data[1] }, { fill: "blue" });
chart1.addSeries("Test", {data: data[2] }, { fill: "blue",text: "Test" });
chart1.render();
chart1.removeSeries("min");
chart1.removeSeries("max");
var legendTwo = new Legend({chart: chart1}, "legendTwo");
});
</script>
</head>
<body>
<div id="chart1" style="width: 600px; height: 600px;"> </div>
<div id="legendTwo"></div>
</body>
</html>
And i don't understand why the label and the legend doesn't print.
The remove is due to a bug of dojox.
Regards
Bussiere
I may be misunderstanding your issue, but since you are using the old module loading style (dojo.require), you need the full name of the Legend class:
var legendTwo = new dojox.charting.widget.Legend({chart: chart1}, "legendTwo");