How to draw a combo graph in Google Chart vertically with dual axes at top and bottom? - google-visualization

I've got a Google Chart ComboGraph in vertical orientation and I'd like to display the dependent axis (horizontal one in this configuration) both at the bottom and at the top of the graph.
For horizontal orientation, a hack I can use to achieve this is to create a dummy second axis - then the two axes display on left and right of the graph. But this doesn't translate to top and bottom for a vertical orientation.
I don't mind using some JS fiddling to achieve the result but it's not clear to me if this is possible - any ideas?
Here's an example graph - there's also the issue that the viewWindow doesn't seem to be respected for either axis, as can be seen by looking at the 'horizontal' view (the 'tracking' and 'candle' should fit together):
<html>
<head>
<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(drawVisualization);
function drawVisualization() {
// Some raw data (not necessarily accurate)
var data = google.visualization.arrayToDataTable([
['Value', 'Candle', '', '', '', 'Points', 'Tracking'],
['1', 165, 938, 938, 998, 450, 938],
['2', -150, 599, 599, 1268, 288, 599],
['3', 157, 587, 587, 807, 397, 587],
['4', 139, 615, 615, 968, 215, 615],
['5', 136, 629, 629, 1026, 1200, 629]
]);
var options = {
orientation:'vertical',
title : '',
vAxis: {title: ''},
hAxis: {
0: {
title: '0',
viewWindow: { min: -200, max: 1200 },
minorGridlines: { count: 4, color:'#E9E9E9' }
},
1: {
title: '1',
viewWindow: { min: -200, max: 1200 }
}
},
seriesType: 'candlesticks',
series: {
1: {type: 'line', pointsVisible:true,lineWidth:0,color:'#FF9955'},
2: {type:'bars',color:'#AAAAFF'},
0: {color: 'blue', targetAxisIndex: 1}
}
};
var chart = new google.visualization.ComboChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
<body>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
</body>
</html>

Top-X Charts are only available via standard config options on a Material chart
However, Material charts do not support "combo" charts...
But if all you want are the same axis labels displayed at the top,
you can clone them and change the 'y' attribute manually,
when the 'ready' event fires
see following working snippet,
use chart method --> getChartLayoutInterface().getBoundingBox('chartarea')
to find the top coordinate of the chart area...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['Value', 'Candle', '', '', '', 'Points', 'Tracking'],
['1', 165, 938, 938, 998, 450, 938],
['2', -150, 599, 599, 1268, 288, 599],
['3', 157, 587, 587, 807, 397, 587],
['4', 139, 615, 615, 968, 215, 615],
['5', 136, 629, 629, 1026, 1200, 629]
]);
var options = {
orientation:'vertical',
title : '',
vAxis: {title: ''},
hAxis: {
0: {
title: '0',
viewWindow: { min: -200, max: 1200 },
minorGridlines: { count: 4, color:'#E9E9E9' }
},
1: {
title: '1',
viewWindow: { min: -200, max: 1200 }
}
},
seriesType: 'candlesticks',
series: {
1: {type: 'line', pointsVisible:true,lineWidth:0,color:'#FF9955'},
2: {type:'bars',color:'#AAAAFF'},
0: {color: 'blue', targetAxisIndex: 1}
}
};
var container = document.getElementById('chart_div');
var chart = new google.visualization.ComboChart(container);
google.visualization.events.addListener(chart, 'ready', function () {
var chartLayout = chart.getChartLayoutInterface();
var svg = container.getElementsByTagName('svg')[0];
var axisLabels = svg.getElementsByTagName('text');
var coords = chartLayout.getBoundingBox('chartarea');
Array.prototype.forEach.call(axisLabels, function(label) {
if (label.getAttribute('text-anchor') === 'middle') {
var topAxisLabel = label.cloneNode(true);
var yCoord = coords.top - parseInt(topAxisLabel.getAttribute('font-size'));
topAxisLabel.setAttribute('y', yCoord);
svg.appendChild(topAxisLabel);
}
});
});
chart.draw(data, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
note: changes made manually in this way will not show when using chart method --> getImageURI()
if you need to get an image, you can use html2canvas instead...

Related

Polar Area Chart with equal sized section

I would like to create an Polar Area Chart with equal size sections (not based on the actual value) like this with ng2-charts: Example
I thought that using the scales.r.max setting at 1 will create the effect I need, but any data that exceeds the max value overflow outside the bound of the chart instead of clipping it.
Does anybody have an idea how to achieve this?
Thanks in advance for your help,
I think you don't need a polar area but a pie chart should fit better the picture you posted.
You could define a data array with all the same value "1 / labels.length" where labels are the months of the posted picture.
Then you should use Datalabels plugin in order to set the real number to show in the chart.
const labels = ['January', 'Fabruary', 'March', 'April', 'May', 'June', 'July'];
const data = [65, 8, 90, 81, 56, 55, 40];
const value = 1 / labels.length;
const colors = [
'rgb(53, 152, 219)',
'rgb(46, 204, 113)',
'rgb(155, 89, 182)',
'rgb(241, 196, 15)',
'rgb(189, 195, 199)',
'rgb(203, 184, 214)',
'rgb(216, 252, 207)'
];
const ctx = document.getElementById("myChart");
const polarChart = new Chart(ctx, {
type: 'pie',
plugins: [ChartDataLabels],
data: {
labels: labels,
datasets: [{
data: labels.concat().fill(value),
backgroundColor: colors,
}]
},
options: {
plugins: {
legend: {
position: 'right'
},
datalabels: {
color: 'black',
font: {
size: 24,
weight: 'bold'
},
formatter: (value, context) => data[context.dataIndex]
}
},
}
});
.myChartDiv {
max-width: 600px;
max-height: 400px;
}
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.9.1/dist/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels#2.1.0/dist/chartjs-plugin-datalabels.min.js"></script>
<div class="myChartDiv">
<canvas id="myChart" width="600" height="400"></canvas>
</div>

I am not able to remove legend in this google chart, also not able to change height , I putted it inside a col-md-4 div , also there help me

js code :
its to add chart to col-4 bar must have 3 columns each having space between it all different color, remove legend in this google chart
function drawBarChart() {
var data = google.visualization.arrayToDataTable([
["Retention", "Level", {
role: "style"
}],
["HIGH", 12, "#E54B4B"],
["ELEVATED", 29, "#FFB100"],
["LOW", 52, "#2BC18D"],
]);
var options = {
title: "Density of Precious Metals, in g/cm^3",
height: 600,
width: 370,
legend: 'none',
bar: {
groupWidth: "55%"
},
ticks: [0, 20, 40, 60, 80, 100],
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_divTwo'));
// Convert the Classic options to Material options.
chart.draw(data, google.charts.Bar.convertOptions(data, options));
};

Chart.js - How to set a line chart dataset as disabled on load

Using chart.js v2, is it possible to mark a dataset in a line chart as being disabled on initial load?
Didn't find an option for it in the documentation.
Yes, there is a "hidden" flag in ChartJS.
eg.
data:
{
datasets: [
{
data: [1,2,3],
label: 'My First Dataset',
hidden: true,
},
],
}
See this issue on GitHub: https://github.com/chartjs/Chart.js/issues/689
The accepted solution has the downside, that hiding/unhiding signals might sometimes fail after initializing the chart like that.
It might be a better idea to change it in the current metadata of the dataSet, which holds the actual data that is used by the chart:
chart.data.datasets.forEach((dataSet, i) => {
var meta = chart.getDatasetMeta(i);
meta.hidden = (<your-condition-here>);
});
this.chart.update();
If you are using angular-chartjs, then you can add the properties of the dataset in the chart-dataset-override property:
For example:
HTML:
<div class="container" ng-app="app" ng-controller="ChartCtrl">
<canvas id="bar" class="chart chart-bar" chart-data="data" chart-labels="labels" chart-series="series" chart-dataset-override="datasetOverride">
</canvas>
</div>
Javascript:
Chart.defaults.global.legend.display = true;
angular.module("app", ["chart.js"])
.controller("ChartCtrl", function($scope) {
$scope.labels = ['2006', '2007', '2008', '2009', '2010', '2011', '2012'];
$scope.series = ['Series A', 'Series B'];
$scope.data = [
[65, 59, 80, 81, 56, 55, 40],
[28, 48, 40, 19, 86, 27, 90]
];
$scope.datasetOverride = [{}, {
hidden: true,
}];
});

How to show bar chart in the range control window for google charts

Fiddle here
https://jsfiddle.net/811x5f6d/
Right now it shows line plots in the range control. I want to create bar (column) chart in the range control window to mimic my actual chart window. None of the options I tried work. Is there a way?
<script type="text/javascript">
google.load('visualization', '1', {
packages: ['controls']
});
google.setOnLoadCallback(createTable);
function createTable() {
// Create the dataset (DataTable)
var myData = google.visualization.arrayToDataTable([
['Month', 'Bolivia', 'Ecuador', 'Madagascar', 'Papua NewGuinea', 'Rwanda', 'Average'],
[1, 165, 938, 522, 998, 450, 614.6],
[2, 135, 1120, 599, 1268, 288, 682],
[3, 157, 1167, 587, 807, 397, 623],
[4, 139, 1110, 615, 968, 215, 609.4],
[5, 136, 691, 629, 1026, 366, 569.6]
]);
// Create a dashboard.
var dash_container = document.getElementById('dashboard_div'),
myDashboard = new google.visualization.Dashboard(dash_container);
// Create a date range slider
var myDateSlider = new google.visualization.ControlWrapper({
'controlType': 'ChartRangeFilter',
'containerId': 'control_div',
'options': {
'filterColumnLabel': 'Month',
'chartType' : 'ComboChart'
}
});
// Bar chart visualization
var myChart = new google.visualization.ChartWrapper({
'chartType': 'ColumnChart',
'containerId': 'line_div',
title: 'Monthly Coffee Production by Country',
vAxis: {
title: 'Cups'
},
hAxis: {
title: 'Month'
},
seriesType: 'bars'
});
// Bind myLine to the dashboard, and to the controls
// this will make sure our line chart is update when our date changes
myDashboard.bind(myDateSlider, myChart);
myDashboard.draw(myData);
}
</script>
<div id="dashboard_div">
<div id="control_div">
<!-- Controls renders here -->
</div>
<div id="line_div">
<!-- Line chart renders here -->
</div>
<div id="table_div">
<!-- Table renders here -->
</div>
</div>
Nevermind I figured it out.
Here is the fiddle that shows the required chages to make it work
https://jsfiddle.net/odupLn52/
Modified Code:
<script type="text/javascript">
google.load('visualization', '1', {
packages: ['controls']
});
google.setOnLoadCallback(createTable);
function createTable() {
// Create the dataset (DataTable)
var myData = google.visualization.arrayToDataTable([
['Month', 'Bolivia', 'Ecuador', 'Madagascar', 'Papua New Guinea', 'Rwanda', 'Average'],
[1, 165, 938, 522, 998, 450, 614.6],
[2, 135, 1120, 599, 1268, 288, 682],
[3, 157, 1167, 587, 807, 397, 623],
[4, 139, 1110, 615, 968, 215, 609.4],
[5, 136, 691, 629, 1026, 366, 569.6]
]);
// Create a dashboard.
var dash_container = document.getElementById('dashboard_div'),
myDashboard = new google.visualization.Dashboard(dash_container);
// Create a date range slider
var myDateSlider = new google.visualization.ControlWrapper({
'controlType': 'ChartRangeFilter',
'containerId': 'control_div',
'options': {
'filterColumnLabel': 'Month',
ui: {
'chartType' : 'ComboChart',
chartOptions: {seriesType: "bars"}
}
}
});
// Bar chart visualization
var myChart = new google.visualization.ChartWrapper({
'chartType': 'ColumnChart',
'containerId': 'line_div',
title: 'Monthly Coffee Production by Country',
vAxis: {
title: 'Cups'
},
hAxis: {
title: 'Month'
},
seriesType: 'bars'
});
// Bind myLine to the dashboard, and to the controls
// this will make sure our line chart is update when our date changes
myDashboard.bind(myDateSlider, myChart);
myDashboard.draw(myData);
}
</script>
<div id="dashboard_div">
<div id="control_div">
<!-- Controls renders here -->
</div>
<div id="line_div">
<!-- Line chart renders here -->
</div>
<div id="table_div">
<!-- Table renders here -->
</div>
</div>

How to add target line in google column chart?

How to add the target line in google column chart like this.
If you'd like to combine the columnchart and linechart, use ComboChart. Documentation and examples are here :
https://developers.google.com/chart/interactive/docs/gallery/combochart
basically, have the data point for the line chart as one of the columns in the DataTable and specify this column to be the "series" = "line", whereas the other columns are visualized in a ColumnChart.
You can use a Stepped Area series to achieve this. It's a little awkward but works well.
var data = google.visualization.arrayToDataTable([
['Month', 'Bolivia', 'Ecuador', 'Madagascar', 'Papua New Guinea', 'Rwanda', ''],
['2004/05', 165, 938, 522, 998, 450, 250],
['2005/06', 135, 1120, 599, 1268, 288, 250],
['2006/07', 157, 1167, 587, 807, 397, 250],
['2007/08', 139, 1110, 615, 968, 215, 250],
['2008/09', 136, 691, 629, 1026, 366, 250]
]);
var options = {
seriesType: "line",
series: {5: {
type: "steppedArea",
color: '#FF0000',
visibleInLegend: false,
areaOpacity: 0}
}
};
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
Example
Stepped Area Google Chart Example
To avoid the ugly outline, just use: enableInteractivity: false
To make the steppedArea #Ryan suggested above a litte bit less awkward, you can setup a second (right) axis and set the base line to the value you want for the target line. The second axis will be setup for the seppedArea data. This avoids the uggly outline effect when you hover the pointer over the chart and under the line. Do something like this in the options:
var options = {
seriesType: "line",
series: {5: {
type: "steppedArea",
color: '#FF0000',
visibleInLegend: false,
areaOpacity: 0,
targetAxisIndex: 1 } //tell the series values to be shown in axe 1 bellow
},
vAxes: [ //each object in this array refers to one axe setup
{}, //axe 0 without any special configurations
{
ticks: [250], //use this if you want to show the target value
baseline: 250 //this shifts the base line to 250
}
]
};