The axis is showing disordered values and the columns are summing I don't know why.
The data is in percentage although it could be more then 100% if the achievement is superior to target.
This is my code (before it there is one Foreach):
$vttCloud = number_format((($CountryCloudAchieved)*pow(($CountryTarget*0.25 ), -1))*100, 2, ",", ".");
$vtt = number_format((($CountryAchieved)*pow(($CountryTarget), -1))*100, 2, ",", ".");
if ($vttCloud == 0 && $vtt == 0) {} else {
?>
['<?php echo $Country; ?>', '<?php echo $vtt; ?>', '<?php echo $vttCloud; ?>'],
<?php } } ?>
use numbers instead of strings for columns 1 & 2 (lose the single quotes)...
['<?php echo $Country; ?>', <?php echo $vtt; ?>, <?php echo $vttCloud; ?>],
strange it will let you draw a chart with strings as values,
see following two examples, one with numbers, the other with strings...
google.charts.load('current', {
callback: function () {
drawChartGood();
drawChartBad();
},
packages:['bar']
});
function drawChartGood() {
var dataTable = google.visualization.arrayToDataTable([
['Country', 'vtt', 'vttCloud'],
['Czech Republic', 50, 60],
['Italy', 75, 80],
['Croatia', 28, 40]
]);
var options = {
bars: 'horizontal'
};
var chart = new google.charts.Bar(document.getElementById('chart_good'));
chart.draw(dataTable, google.charts.Bar.convertOptions(options));
}
function drawChartBad() {
var dataTable = google.visualization.arrayToDataTable([
['Country', 'vtt', 'vttCloud'],
['Czech Republic', '50', '60'],
['Italy', '75', '80'],
['Croatia', '28', '40']
]);
var options = {
bars: 'horizontal'
};
var chart = new google.charts.Bar(document.getElementById('chart_bad'));
chart.draw(dataTable, google.charts.Bar.convertOptions(options));
}
div {
padding-bottom: 24px;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div>Numbers</div>
<div id="chart_good"></div>
<div>Strings</div>
<div id="chart_bad"></div>
Related
I want to change my widget but I only want to change
series: [<?php echo $data['campaign']['0']->report_summary->open_rate * 100?>],
To the new data I am getting something like series: [100], But this is not working
$(document).ready(function () {
var element = document.getElementById("kt_mixed_widget_18_chart");
var height = parseInt(KTUtil.css(element, 'height'));
if (!element) {
return;
}
var options = {
series: [<?php echo $data['campaign']['0']->report_summary->open_rate * 100?>],
chart.updateOptions([{
series: [newData]
}]);
This worked!
ApexCharts.exec('chart_id', 'updateSeries', [5]);
Google-chart trend-line not showing. Tried to put the code in vAxis, hAxis and only in options but no luck. I know that the first column must be a number or date and so on and my first column is a date.
<script type="text/javascript">
data.sort([{column: 0}]);
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Date', 'Sum'],
<?php while($row = mysqli_fetch_assoc($result)) { ?>
[<?php echo $row['date'] ?>, <?php echo $row['col2'] ?> ],
<?php } ?>
]);
var options = {
legend: { position: 'bottom' },
title: 'Sum per day',
hAxis : { textStyle : { fontSize: 10 } },
vAxis: { viewWindowMode: 'explicit', viewWindow: { min: 0 } },
trendlines: { 0: {} }
};
var chart = new google.visualization.LineChart(document.getElementById('line_chart'));
chart.draw(data, options);
}
</script>
when loading the data, the first column needs to be converted from a string to a date.
place the value from php in quotes and inside a date constructor.
e.g.
[new Date('<?php echo $row['date'] ?>'), <?php echo $row['col2'] ?> ],
if you still have problems with the squiggly line,
sort the data before drawing...
data.sort([{column: 0}]);
var chart = new google.visualization.LineChart(document.getElementById('line_chart'));
chart.draw(data, options);
I'm now working on chart.js(V2.4) and I have some problems.
I've looked up a lot of similar issues/questions but none of it solves my problem.
Error in console log shows: "Chart.controllers[meta.type] is not a constructor"
Here's my code:
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
</head>
<body>
<label style="margin-left:3%;">X : </label>
<select id="selectxfield" style="width:20%;margin-top:2%;margin-left:1%;display:inline;">
<option>player</option>
</select>
<label style="margin-left:3%;">Y : </label>
<select name="selectyfield" style="width:20%;margin-left:1%;display:inline;">
<option>ppg</option>
</select>
<button id="btnchart" style="margin-left:3%;">Submit</button>
<canvas id="areaChart" style="height:250px"></canvas>
<canvas id="lineChart" style="height:250px"></canvas>
<canvas id="barChart" style="height:250px"></canvas>
</body>
<script type="text/javascript">
$(function () {
// This will get the first returned node in the jQuery collection.
function isEmpty(obj){
for(var key in obj){
if(obj.hasOwnProperty(key))
return false;
}
return true;
}
function randomColor() {
var colorVal = "rgb(";
for(i = 0; i < 3; i++) {
colorVal += Math.round(250*Math.random());
if (i < 2) {
colorVal += ",";
}
}
colorVal += ")";
return colorVal;
}
$('#btnchart').click(function(){
var jsdata = '{"name": "2011NBA.csv", "resource_id": "pao3ckw7b3lj8eh4ad0899oiy", "success": "true", "records": [{"id": 1, "player": "LeBron James", "division": "East", "ppg": "27.1", "rpg": "7.9", "apg": "6.2", "blk": "0.81", "stl": "1.85"}, {"id": 2, "player": "Kevin Durant", "division": "West", "ppg": "28", "rpg": "8", "apg": "3.5", "blk": "1.17", "stl": "1.33"}, {"id": 3, "player": "Dwight Howard", "division": "East", "ppg": "20.6", "rpg": "14.5", "apg": "1.9", "blk": "2.15", "stl": "1.5"}, {"id": 4, "player": "Christ Paul", "division": "West", "ppg": "19.8", "rpg": "3.6", "apg": "9.1", "blk": "0.07", "stl": "2.53"}, {"id": 5, "player": "Derrick Rose", "division": "East", "ppg": "21.8", "rpg": "3.4", "apg": "7.9", "blk": "0.72", "stl": "0.9"}]}'
var data = JSON.parse(jsdata);
var x = []; // use array to save the field's name
var y = []; // use array to save data
var xf = $( "#selectxfield option:selected" ).text();// get selected value
$.each(data.records, function(i, v) {
x.push(v[xf]);
});
var areaChartData = {
labels: x,
datasets: []
};
var selectyfield = document.getElementsByName('selectyfield') // selectyfield can be added dynamically in my code, but I set it to one just for debug convenience
var dt = data.records;
for (j=0;j<selectyfield.length;j++){
var color = randomColor();
var index = selectyfield[j].selectedIndex;
var k = selectyfield[j].options[index].text;
$.each(data.records, function(ky, vl) {
y.push(parseFloat(vl[k]));
});
if (isEmpty(data.records)){
$.each(dt, function(ky, vl) {
y.push(parseFloat(vl[k]));
});
}
var data ={
label: k,
fillColor: color,
strokeColor: color,
pointColor: color,
pointStrokeColor: "#c1c7d1",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: y
}
areaChartData["datasets"].push(data);
y = [];
}
var areaChartOptions = {
// a lot of options
};
var barChartOptions = {
// a lot of options
};
var area = document.getElementById("areaChart")
var areaChartCanvas = area.getContext("2d");
var areaChart = new Chart(areaChartCanvas,{
type: "area",
data: areaChartData,
options: areaChartOptions
});
var line = document.getElementById("lineChart")
var lineChartCanvas = line.getContext("2d");
var lineChartOptions = areaChartOptions;
var lineChartData = areaChartData;
lineChartOptions.datasetFill = false;
var lineChart = new Chart(lineChartCanvas,{
type: "line",
data: lineChartData,
options: lineChartOptions
});
var bar = document.getElementById("barChart")
var barChartCanvas = bar.getContext("2d");
var barChartData = areaChartData;
barChartOptions.datasetFill = false;
var lineChart = new Chart(barChartCanvas,{
type: "bar",
data: barChartData,
options: barChartOptions
});
});
});
</script>
</html>
The select field is fixed just for convenience.
I am sure the code works fine in older chart.js (v1.X), I just have to change some code usage above.
Hope someone can help me finding the error, thanks
Few days later, I finally reached the contributors and members of chart.js.
They helped me and pointed out that there's no chart type named "area".
After deleting that part, the code works fine.
It's still strange that the debug message didn't show relative information but something not correlated to.
I just hit a similar problem. Looking into the source, it seems Chart.controllers is an object with all the different types of chart as properties. meta.type is whatever you pass as type in the options hash to the new Chart() constructor. So in your case it was complaining that Chart.controllers["area"] is not a constructor.
I appreciate that you've already found the answer to your specific problem, but I thought it would be worth expanding on this because (a) as you pointed out, the debug message is a bit unhelpful by itself, and (b) this might help anyone who has similar difficulties (for example, in my case I put in "Line" instead of "line" and if I'd understood what the error message actually meant it would have saved me a bit of digging).
I created a bar chart, with an html tooltip that displayed an image. This worked perfectly. I then added event handlers for the Ready and Select events and a bootstrap modal that pops up when the user clicks on one of the bars. Now the html tooltips don't appear any more when you hover over a bar. But, if I change the code to say "tooltip: {}", then I do get the tooltip showing the html content (as text). I'm not sure if this is as a result of adding the event handlers, or adding bootstrap, but I can't get the tooltips to show an image any more.
How can I get the tooltips to show again? and how can I get them to show when I hover over the annotation on the bar? I thought that was what annotationText was for, but my (text) tooltip only shows when I hover over the bar, not the text.
Here is a cut down version of the code with irrelevant bits omitted for clarity:
var DashboardWindow = new function()
{
this.DetailChart = null;
this.onLoad = function()
{
google.charts.load( 'current', { 'packages': ['corechart', 'bar'] } );
google.charts.setOnLoadCallback( this.drawCharts );
j$( '#detailsPopup' ).on( 'show.bs.modal', DashboardWindow.getDetailsData );
}
this.detailsReadyHandler = function()
{
google.visualization.events.addListener( DashboardWindow.DetailChart, 'select', DashboardWindow.detailsSelectHandler );
}
this.detailsSelectHandler = function( e )
{
var selection = DashboardWindow.DetailChart.getSelection();
if( selection.length > 0 )
{
var item = DashboardWindow.DetailChartData.getValue( selection[0].row, 0 );
j$( '#detailsPopupTitle' ).text( item );
j$( '#detailsPopup' ).modal( { show: true, keyboard: true } );
}
}
this.drawCharts = function()
{
.....
j$.ajax( {
type: "POST",
url: .....
} ).done( function( result )
{
if( result.d.Detail != null )
{
var data = new google.visualization.DataTable();
var groupHeader = j$( '#' + Dashboard_DetailsType ).val();
data.addColumn( 'string', groupHeader );
data.addColumn( 'number', 'NPS Score' );
data.addColumn( { type: 'string', role: 'annotation' } );
data.addColumn( { type: 'string', role: 'style' } );
data.addColumn( { type: 'string', role: 'tooltip', p: { 'html': true } } );
data.addColumn( { type: 'string', role: 'annotationText', p: { 'html': true } } );
result.d.Detail.forEach( function( row )
{
var red = ....
var green = ....
var tooltip = '';
if( row.NPS != null )
{
tooltip = '<div class="tooltip"><b>' + row.GroupName + '</b><br/><hr/>NPS Score: <b>' + row.NPS.toFixed( 1 ) + '</b><br/>Responses: ' + row.NPSMessageCount.toString() + '<br>'
+ 'Last Score: ' + ( row.LastNPS == null ? 'none' : row.LastNPS.toFixed( 1 ) ) + '<br/>'
+ '<img id="overall_nps_score_trend" alt="trend" src="images/icons/trend-' + ( ( row.Trend == 1 ) ? 'up' : ( ( row.Trend == 255 ) ? 'down' : 'same' ) ) + '-64.png" /></div>';
}
data.addRow( [
row.GroupName,
row.NPS,
row.NPS == null ? '' : row.NPS.toFixed( 1 ) + ' (' + row.NPSMessageCount.toString() + ' Responses)',
row.NPS == null ? '' : 'color: #' + red + green + '50',
tooltip,
tooltip
] );
} );
var chartWidth = j$( '#nps_details_chart' ).width() - 300;
var options =
{
bar: { groupWidth: "90%" },
legend: { position: "none" },
hAxis: { minValue: 0, maxValue: 100 },
chartArea: { left: 260, top: 20, width: chartWidth, height: result.d.Detail.length * 34 - 80 },
height: result.d.Detail.length * 34,
tooltip: { isHtml: true, ignoreBounds: true, trigger: focus }
};
DashboardWindow.DetailChartData = data;
DashboardWindow.DetailChart = new google.visualization.BarChart( document.getElementById( "nps_details_chart" ) );
google.visualization.events.addListener( DashboardWindow.DetailChart, 'ready', DashboardWindow.detailsReadyHandler );
DashboardWindow.DetailChart.draw( data, options );
}
} )
.fail( function( response, status, error )
{
....
} );
}
}
function pageLoad()
{
DashboardWindow.onLoad();
}
For anyone else with a similar issue, there were 2 problems here.
The first was my use of 'div class="tooltip"' in my tooltip content, as bootstrap.css defines a tooltip class which seems to prevent the tootip being displayed. Changing the class name fixed the issue.
The second problem was tooltips not appearing over the annotation text. This is most noticable when the bar length is zero as there is no way to see the tootip. This code demonstrates the issue:
<html>
<body>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load("current", {packages:["corechart"]});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
["District", "Score", { role: "annotation" }, { role: "tooltip", p: { html: true } } , { role: "annotationText", p: { html: true } }],
["District 1", 25, "12 (6 Responses)", "<b>Score 12</b><br/>(6 Responses)", "<b>Score 12</b><br/>(6 Responses)"],
["District 2", 5, "5 (8 Responses)", "<b>Score 5</b><br/>(8 Responses)", "<b>Score 5</b><br/>(8 Responses)"],
["District 3", 3, "3 (14 Responses)", "<b>Score 3</b><br/>(14 Responses)", "<b>Score 3</b><br/>(14 Responses)"],
["District 4", 0, "0 (3 Responses)", "<b>Score 0</b><br/>(3 Responses)", "<b>Score 0</b><br/>(3 Responses)"],
["District 5", 18, "18 (9 Responses)", "<b>Score 18</b><br/>(9 Responses)", "<b>Score 18</b><br/>(9 Responses)"],
]);
var options = {
title: "District Scores",
width: 600,
height: 400,
bar: {groupWidth: "95%"},
tooltip: { isHtml: true },
legend: { position: "none" },
};
var chart = new google.visualization.BarChart(document.getElementById("barchart_values"));
chart.draw(data, options);
}
</script>
<div id="barchart_values" style="width: 900px; height: 300px;"></div>
</body>
</html>
swapping the order of the tooltip and annotationText within the data fixes the issue. (i.e. make the annotationText the 4th column following the annotation).
I still can't get a tooltip over the annotation when the annotation is within the bar, but if the bar is short so that the annotation is outside of the bar then the tooltip is displaying ok.
I made half a donut chart with Google charts and I have a problem that the sum of visible percentage is equal to 50%. Is there any possible solution ?
Image of my chart
you can override the text displayed on the slice by using the following config option...
pieSliceText: 'value'
then in the data, set the formatted value of the cells to the correct percentage...
var data = [
['Task', 'Hours'],
// use formatted values
['A', {v: 19.2, f: '38.4%'}],
['B', {v: 30.8, f: '61.6%'}],
[null, 50]
];
the following working snippet uses the same approach,
but calculates the correct percentages,
rather than hard-coding...
google.charts.load('current', {
callback: function () {
var data = [
['Task', 'Hours'],
['A', 19.2],
['B', 30.8],
[null, 50.0]
];
var total = 0;
for (var i = 1; i < data.length; i++) {
if (data[i][0] !== null) {
total += data[i][1];
}
}
var numberFormat = new google.visualization.NumberFormat({
pattern: '#,##0.0',
suffix: '%'
});
var dataTable = google.visualization.arrayToDataTable(data);
for (var i = 0; i < dataTable.getNumberOfRows(); i++) {
if (dataTable.getValue(i, 0) !== null) {
dataTable.setFormattedValue(i, 1, numberFormat.formatValue(((dataTable.getValue(i, 1) / total) * 100)));
}
}
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
var options = {
height: 400,
chartArea: {
top: 24
},
colors: ['#8BC34A', '#64B5F6'],
legend: 'none',
pieHole: 0.4,
pieStartAngle: 270,
pieSliceText: 'value',
slices: {
2: {
color: 'transparent'
}
},
theme: 'maximized',
width: 400
};
chart.draw(dataTable, options);
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>