How is it possible to format the number values on a google bar chart with dual x-Axes?
The top axes with the label support should have at least four decimal places, like the value shown in the tooltip.
What I have tried is this approach, but it doesn't seem to work.
My code:
data.addColumn('string', 'RuleName');
data.addColumn('number', 'Lift');
data.addColumn('number', 'Support');
for (var i = 0; i < chartsdata.length; i++) {
data.addRow([rule, Lift,Support)]);
}
// format numbers in second column to 5 decimals
var formatter = new google.visualization.NumberFormat({
pattern: '#,##0.00000'
}); // This does work, but only for the value in the tooltip.
formatter.format(data, 2);
// Passing in some options
var chart = new google.charts.Bar(document.getElementById('barChart'));
var options = {
title: "Association Rules by lift and support",
bars: 'horizontal',
series: {
0: { axis: 'Lift', targetAxisIndex: 0, },
1: { axis: 'Support', targetAxisIndex: 1}
},
axes: {
x: {
Lift: { label: 'Lift', format: '0,000' //Doesn't work, }, // Bottom x-axis.
Support: { side: 'top', label: 'Support' } // Top x-axis.
}
}, ..........
What I also tried is this approach from the google doc:
series:{hAxes:{1:{title:'abc', format: '0,0000'}}
Any help would be greatly appreciated!
there are several options that are not supported by Material charts
see --> Tracking Issue for Material Chart Feature Parity
although format is not listed, there are several options not supported for --> {hAxis,vAxis,hAxes.*,vAxes.*}
so that could be the problem
note: the above options should stand alone and not be included in the series option,
as seen in the question (What I also tried...)
you can change both x-axis formats by using hAxis.format
but don't think you'll be able to change just one
see following working snippet...
google.charts.load('current', {
packages: ['bar']
}).then(function () {
var data = new google.visualization.DataTable();
data.addColumn('string', 'RuleName');
data.addColumn('number', 'Lift');
data.addColumn('number', 'Support');
for (var i = 0; i < 10; i++) {
data.addRow([i.toString(), i+2, i+3]);
}
var formatter = new google.visualization.NumberFormat({
pattern: '#,##0.00000'
});
formatter.format(data, 2);
var chart = new google.charts.Bar(document.getElementById('barChart'));
var options = {
chart: {
title: 'Association Rules by lift and support'
},
bars: 'horizontal',
series: {
0: {axis: 'Lift'},
1: {axis: 'Support'}
},
axes: {
x: {
Lift: {label: 'Lift'},
Support: {side: 'top', label: 'Support'}
}
},
hAxis: {
format: '#,##0.00000'
},
height: 320
};
chart.draw(data, google.charts.Bar.convertOptions(options));
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="barChart"></div>
Related
I have a Google Chart (column-chart) showing a single dated (Jan-2010 = 2010-01-01) column - but the resulting column seems to run from 1-Jul-09 through to 1-Jul-10 (note this seems to change depending on the width of the screen); how can I fix this so that the column sits only on the 01-Jan-2010 date? (**Note, the dates/values are variable and can include one or hundreds of column values so we CANNOT simply hard code this or change the column type from 'date' to 'string').
var arr = eval("[[new Date(2010, 0, 1), 0,1]]");
var data = new google.visualization.DataTable();
data.addColumn('date', 'Dt');
data.addColumn('number', 'Open');
data.addColumn('number', 'Closed');
data.addRows(arr);
var options_stacked = {
isStacked: true,
height: 300,
colors: ['#111', '#a00'],
hAxis: {
slantedText: false,
format: 'd/MMM/yy',
},
legend: {
position: 'top',
},
vAxis: {
minValue: 0
}
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options_stacked);
A demonstrator for this can be found on https://jsfiddle.net/Abeeee/d5fojtp2/34/
you can add custom ticks to ensure each column "sits" on the correct date.
the ticks option expects an array of values.
we can use DataTable method --> getDistinctValue(colIndex)
to return the date values from the data table.
var xTicks = data.getDistinctValues(0);
hAxis: {
slantedText: false,
format: 'd.MMM.yy', <---- changed from 'd/MMM/yy' to avoid line breaks
ticks: xTicks
},
see following working snippet...
function doTest() {
var arr = eval("[[new Date(2010, 0, 1), 0,1]]");
var data = new google.visualization.DataTable();
data.addColumn('date', 'Dt');
data.addColumn('number', 'Open');
data.addColumn('number', 'Closed');
data.addRows(arr);
var xTicks = data.getDistinctValues(0);
var options_stacked = {
isStacked: true,
height: 300,
colors: ['#111', '#a00'],
hAxis: {
slantedText: false,
format: 'd/MMM/yy',
ticks: xTicks
},
legend: {
position: 'top',
},
vAxis: {
minValue: 0
}
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options_stacked);
}
window.addEventListener('resize', doTest);
google.charts.load('current', {
packages: ['corechart', 'bar']
});
google.charts.setOnLoadCallback(doTest);
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<h1>Google Charts</h1>
<div id="chart_div"></div>
I have to add zoom in and zoom out in the google scatter chart,so I tried
explorer: {
actions: ['dragToZoom', 'rightClickToReset']
}
in options, but it did not work.. Below is my code
var data = new google.visualization.DataTable();
data.addColumn('number', 'speed(rpm)');
data.addColumn('number', 'Toq(Nm)');
data.addRows([
<c:forEach items="${resultList }" var="result" varStatus="status">
[${result.mcuMotspd}, ${result.mcuMottoq}],
</c:forEach>
]);
var options = {
chart: {
},
axes: {
x: {
0: { side: 'bottom', label: 'speed(rpm)'} // Top x-axis.
},
y: {
0: { side: 'left', label:'toq(Nm)'} // Top x-axis.
}
},
explorer: {
actions: ['dragToZoom', 'rightClickToReset']
}
};
var chart = new google.charts.Scatter(document.getElementById('chart_area'));
chart.draw(data, google.charts.Scatter.convertOptions(options));
}
Please anyone help me for adding zoom in and out for the google scatter chart.. I cannot find information from google chart api reference..
I'm working on a small HTML application for my website that does some simulations and plots it to a graph (using Google Charts). All of the data will originate in the JavaScript code on the page (i.e. I'm not trying to pull in data from a database or anything like that). For this reason, I would like to have access to the data table from other functions so the data can be updated when a new simulation is run.
What I'm running into is that if I build a data table (and data view) inside of the drawChart() function, everything works fine. See this jsfiddle or the following code:
//Google charts stuff
google.charts.load('current', { 'packages': ['line', 'corechart'] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var forceChartDiv = document.getElementById('force_chart_div');
var sim_data = new google.visualization.DataTable();
sim_data.addColumn('number', 'Elapsed Time (sec)');
sim_data.addColumn('number', "Total Force");
sim_data.addColumn('number', "M1 Force(Each)");
sim_data.addRows([
[0.0, -.5, 5.7],
[0.1, .4, 8.7],
[0.2, .5, 12]
]);
var forceDataView = new google.visualization.DataView(sim_data);
forceDataView.setColumns([0, 1, 2]);
var forceChartOptions = {
chart: {title: 'Simulation Results: Force'},
width: 900,
height: 500,
series: {
// Gives each series an axis name that matches the Y-axis below.
0: { axis: 'Total' },
1: { axis: 'Individual' }
},
axes: {
// Adds labels to each axis; they don't have to match the axis names.
y: {
Total: { label: 'Total Force (Newtons)'},
Individual: { label: 'Per-Motor Force (Newtons)'}
}
}
};
var forceChart = new google.charts.Line(forceChartDiv);
forceChart.draw(forceDataView, google.charts.Line.convertOptions(forceChartOptions));
}
But if I move the code for the creation of the data table and data view outside of the function scope, it doesn't work. See this jsfiddle or the following code:
var sim_data;
var forceDataView;
//Google charts stuff
google.charts.load('current', { 'packages': ['line', 'corechart'] });
sim_data = new google.visualization.DataTable();
sim_data.addColumn('number', 'Elapsed Time (sec)');
sim_data.addColumn('number', "Total Force");
sim_data.addColumn('number', "M1 Force(Each)");
sim_data.addRows([
[0.0, -0.5, 5.7],
[0.1, 0.4, 8.7],
[0.2, 0.5, 12]
]);
forceDataView = new google.visualization.DataView(sim_data);
forceDataView.setColumns([0, 1, 2]);
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var forceChartDiv = document.getElementById('force_chart_div');
var forceChartOptions = {
chart: {title: 'Simulation Results: Force'},
width: 900,
height: 500,
series: {
// Gives each series an axis name that matches the Y-axis below.
0: { axis: 'Total' },
1: { axis: 'Individual' }
},
axes: {
// Adds labels to each axis; they don't have to match the axis names.
y: {
Total: { label: 'Total Force (Newtons)'},
Individual: { label: 'Per-Motor Force (Newtons)'}
}
}
};
var forceChart = new google.charts.Line(forceChartDiv);
forceChart.draw(forceDataView, google.charts.Line.convertOptions(forceChartOptions));
}
Both of these examples use the following HTML:
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="force_chart_div"></div>
I thought it might have something to do with the execution order of the callback function. But putting it in different spots in the code doesn't seem to change anything. In my full project, I went so far as to add a button that called the drawChart() function just to check, but that didn't help either.
Depending on where I put the callback function call, I'll get a red "Data Table is not Defined" alert showing up where the chart is supposed to be on the webpage. That pretty much tells me what I already suspected, but I don't know how to fix it. Any help would be appreciated. I'm a huge JS noob, by the way, so go easy on me.
your instinct was correct, you must wait on the callback to finish,
before using the google.visualization or google.charts namespaces.
it has to do more with timing, than placement of the code.
instead of using the callback statement, we can use the promise that the load statement returns.
as in the following snippet...
var sim_data;
var forceDataView;
//Google charts stuff
google.charts.load('current', {
packages: ['line', 'corechart']
}).then(function () {
sim_data = new google.visualization.DataTable();
sim_data.addColumn('number', 'Elapsed Time (sec)');
sim_data.addColumn('number', "Total Force");
sim_data.addColumn('number', "M1 Force(Each)");
sim_data.addRows([
[0.0, -0.5, 5.7],
[0.1, 0.4, 8.7],
[0.2, 0.5, 12]
]);
forceDataView = new google.visualization.DataView(sim_data);
forceDataView.setColumns([0, 1, 2]);
});
function drawChart() {
var forceChartDiv = document.getElementById('force_chart_div');
var forceChartOptions = {
chart: {title: 'Simulation Results: Force'},
width: 900,
height: 500,
series: {
// Gives each series an axis name that matches the Y-axis below.
0: { axis: 'Total' },
1: { axis: 'Individual' }
},
axes: {
// Adds labels to each axis; they don't have to match the axis names.
y: {
Total: { label: 'Total Force (Newtons)'},
Individual: { label: 'Per-Motor Force (Newtons)'}
}
}
};
var forceChart = new google.charts.Line(forceChartDiv);
forceChart.draw(forceDataView, google.charts.Line.convertOptions(forceChartOptions));
}
I'm new to coding but over the last several months I've managed to fumble my way through creating a web site that utilises a Google Line Chart and embedded linear trendline to display historical Mean Sea Level and the rate of Mean Sea Level rise for various locations around New Zealand and the Pacific. Each location has it's own Google Line Chart with a linear trendline to show the rate of Mean Sea Level Change for a user selected period. I now want to extend the functionality of each Google Line Chart such that both a linear and polynomial trendline extend to the year 2120 (they currently only show up to the year 2018) even though the available data from which they are calculated uses observed data up to the year 2018. This will allow the user to predict the sea level height up to the year 2020. I realise this explanation may be confusing, so please see my web site www.sealevel.nz to see the existing charts which I hope will aid in understanding my problem.
Below is the code for the extended version of the chart that shows both a linear and second degree polynomial trendline with the x axis of the Google Line Chart now showing up the year 2120. My problem is that I need the y axis to adjust dynamically to show the entirety of both trendlines no matter which time period the user selects. For example if you select the years 1971 and 2018 from the date range slider, then both trendlines are cut off at the years 2017 (linear) and 2031 (polynomial) respectively. I need to be able to see both trendlines and their values up to the year 2120.
Please excuse my novice coding skills. My Code:
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script src="https://unpkg.com/mathjs/dist/math.min.js"></script>
<script type="text/javascript">
google.load('visualization', 'current', {'packages':['controls','corechart']});
google.setOnLoadCallback(initialize);
function initialize() {
var query = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1vn1iuhsG33XzFrC4QwkTdUnxOGdcPQOj-cuaEZeX-eA/edit#gid=0');
query.send(drawDashboard);
}
function drawDashboard(response) {
var data = response.getDataTable();
//Asign units of 'mm' to data.
var formatMS = new google.visualization.NumberFormat({
pattern: '# mm'
});
// format into data mm..
for (var colIndex = 1; colIndex < data.getNumberOfColumns(); colIndex++) {
formatMS.format(data, colIndex);
}
var YearPicker = new google.visualization.ControlWrapper({
'controlType': 'NumberRangeFilter',
'containerId': 'filter_div',
'options': {
'filterColumnLabel': 'Year',
'ui': {
cssClass: 'filter-date',
'format': { pattern: '0000' },
'labelStacking': 'vertical',
'allowTyping': false,
'allowMultiple': false
}
},
});
var MSLChart = new google.visualization.ChartWrapper({
'chartType': 'LineChart',
'containerId': 'chart_div',
'options': {
'fontSize': '14',
'title': 'Timbucktoo Annual Mean Sea Level Summary',
hAxis: {title: 'Year', format:'0000', maxValue: 2120},
vAxis: {title: 'Height above Chart Datum (mm)', format:'0000'},
'height': 600,
chartArea: {height: '81%', width: '85%', left: 100},
'legend': {'position': 'in', 'alignment':'end', textStyle: {fontSize: 13} },
colors: ['blue'],
trendlines: {
0: {
type: 'polynomial',
degree: 2,
color: 'green',
visibleInLegend: true,
},
1: {
type: 'linear',
color: 'black',
visibleInLegend: true,
},
},
series: {
0: { visibleInLegend: true },
1: { visibleInLegend: false },
},
},
'view': {'columns': [0,1,2]}
});
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard_div')).
bind(YearPicker, MSLChart).
draw(data)
</script>
first, I'm not sure why the chart would draw a trend line that isn't visible
which makes this a bit tricky, because we first have to draw the chart,
in order to find the min & max y-axis values.
but there are chart methods we can use to find the max value.
first, we get the chart's layout interface.
var chartLayout = MSLChart.getChart().getChartLayoutInterface();
since we're using a ChartWrapper, we have to get the chart from the wrapper (MSLChart.getChart()).
next, we use method getBoundingBox to find the min & max values of each line.
var yAxisCoords = {min: null, max: null};
var lineIndex = 0;
var boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
do {
yAxisCoords.max = yAxisCoords.max || boundsLine.top;
yAxisCoords.max = Math.min(yAxisCoords.max, boundsLine.top);
yAxisCoords.min = yAxisCoords.min || (boundsLine.top + boundsLine.height);
yAxisCoords.min = Math.max(yAxisCoords.min, (boundsLine.top + boundsLine.height));
lineIndex++;
boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
} while (boundsLine !== null);
then we use method getVAxisValue to determine what each y-axis value should be,
set the viewWindow on the y-axis, and re-draw the chart.
MSLChart.setOption('vAxis.viewWindow.max', chartLayout.getVAxisValue(yAxisCoords.max));
MSLChart.setOption('vAxis.viewWindow.min', chartLayout.getVAxisValue(yAxisCoords.min));
MSLChart.draw();
we do all this in a function.
we use a one time 'ready' event on the chart wrapper for the first calculation.
then again, on the chart.
google.visualization.events.addOneTimeListener(MSLChart, 'ready', filterChange);
function filterChange() {
// get chart layout
var chartLayout = MSLChart.getChart().getChartLayoutInterface();
// get y-axis bounds
var yAxisCoords = {min: null, max: null};
var lineIndex = 0;
var boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
do {
yAxisCoords.max = yAxisCoords.max || boundsLine.top;
yAxisCoords.max = Math.min(yAxisCoords.max, boundsLine.top);
yAxisCoords.min = yAxisCoords.min || (boundsLine.top + boundsLine.height);
yAxisCoords.min = Math.max(yAxisCoords.min, (boundsLine.top + boundsLine.height));
lineIndex++;
boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
} while (boundsLine !== null);
// re-draw chart
MSLChart.setOption('vAxis.viewWindow.max', chartLayout.getVAxisValue(yAxisCoords.max));
MSLChart.setOption('vAxis.viewWindow.min', chartLayout.getVAxisValue(yAxisCoords.min));
MSLChart.draw();
google.visualization.events.addOneTimeListener(MSLChart.getChart(), 'ready', filterChange);
}
see following working snippet...
(when you run the snippet, click "full page" at the top right)
google.charts.load('current', {
packages: ['controls']
}).then(initialize);
function initialize() {
var query = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1vn1iuhsG33XzFrC4QwkTdUnxOGdcPQOj-cuaEZeX-eA/edit#gid=0');
query.send(drawDashboard);
}
function drawDashboard(response) {
var data = response.getDataTable();
//Asign units of 'mm' to data.
var formatMS = new google.visualization.NumberFormat({
pattern: '# mm'
});
// format into data mm..
for (var colIndex = 1; colIndex < data.getNumberOfColumns(); colIndex++) {
formatMS.format(data, colIndex);
}
var YearPicker = new google.visualization.ControlWrapper({
controlType: 'NumberRangeFilter',
containerId: 'filter_div',
options: {
filterColumnLabel: 'Year',
ui: {
cssClass: 'filter-date',
format: {pattern: '0000'},
labelStacking: 'vertical',
allowTyping: false,
allowMultiple: false
}
},
});
var MSLChart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'chart_div',
dataTable: data,
options: {
fontSize: '14',
title: 'Timbucktoo Annual Mean Sea Level Summary',
hAxis: {title: 'Year', format: '0000', maxValue: 2120},
vAxis: {title: 'Height above Chart Datum (mm)', format:'###0'},
height: 600,
chartArea: {height: '81%', width: '85%', left: 100},
legend: {position: 'in', alignment: 'end', textStyle: {fontSize: 13}},
colors: ['blue'],
trendlines: {
0: {
type: 'polynomial',
degree: 2,
color: 'green',
visibleInLegend: true,
},
1: {
type: 'linear',
color: 'black',
visibleInLegend: true,
},
},
series: {
0: { visibleInLegend: true },
1: { visibleInLegend: false },
},
},
view: {columns: [0,1,2]}
});
google.visualization.events.addOneTimeListener(MSLChart, 'ready', filterChange);
function filterChange() {
// get chart layout
var chartLayout = MSLChart.getChart().getChartLayoutInterface();
// get y-axis bounds
var yAxisCoords = {min: null, max: null};
var lineIndex = 0;
var boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
do {
yAxisCoords.max = yAxisCoords.max || boundsLine.top;
yAxisCoords.max = Math.min(yAxisCoords.max, boundsLine.top);
yAxisCoords.min = yAxisCoords.min || (boundsLine.top + boundsLine.height);
yAxisCoords.min = Math.max(yAxisCoords.min, (boundsLine.top + boundsLine.height));
lineIndex++;
boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
} while (boundsLine !== null);
// re-draw chart
MSLChart.setOption('vAxis.viewWindow.max', chartLayout.getVAxisValue(yAxisCoords.max));
MSLChart.setOption('vAxis.viewWindow.min', chartLayout.getVAxisValue(yAxisCoords.min));
MSLChart.draw();
google.visualization.events.addOneTimeListener(MSLChart.getChart(), 'ready', filterChange);
}
var dashboard = new google.visualization.Dashboard(
document.getElementById('dashboard_div')
).bind(YearPicker, MSLChart).draw(data);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard_div">
<div id="chart_div"></div>
<div id="filter_div"></div>
</div>
note: it appears you're using an old load statement, to load google chart.
see above snippet for update...
I want to change my Google Chart's y-axis title to horizontal orientation. Currently, it is drawn with vertical writing, as shown in this image:
My chart drawing code
function drawVisualization() {
// Some raw data (not necessarily accurate)
var data = google.visualization.arrayToDataTable(temp);
var options = {
title: 'Report',
// vAxis: {title: 'Cups'},
hAxis: {
title: 'Date'
},
seriesType: 'bars',
series: {
0: {
targetAxisIndex: 0
},
1: {
targetAxisIndex: 1,
type: 'line'
}
},
vAxes: {
0: {
title: '報酬額',
titleTextStyle: {
italic: false,
}
},
1: {
title: '再生',
titleTextStyle: {
italic: false,
}
},
},
'chartArea' : {'width': '70%', left: '15%'}
};
var chart = new google.visualization.ComboChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
You can see in the Axis Overview:
Direction - You can customize the direction using the
hAxis/vAxis.direction option.
hAxis.direction The direction in which the values along the
horizontal axis grow. Specify -1 to reverse the order of the values.
Type: 1 or -1 Default: 1
If this didn't answer the question, try the workarounds from this SO post.
I did like this. And works well. I don't think this is pretty way.
If anyone find better way Please say to me thanks.
var textTags = document.getElementsByTagName("text");
var searchPlay = "Play";
var searchProfit = "Profit"
$.each(textTags, function(index,value){
if (value.textContent == searchPlay) {
$(this).css('transform','rotate(1turn)');
console.log(value);
}
if (value.textContent == searchProfit) {
console.log(value);
$(this).css('transform', 'rotate(1turn)');
}
});