다음은 Google 시각화 API를 사용하는 방법을 보여주는 몇 가지 코드 샘플입니다.
표 예
function drawTable() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Name');
data.addColumn('number', 'Salary');
data.addColumn('boolean', 'Full Time');
data.addRows(5);
data.setCell(0, 0, 'John');
data.setCell(0, 1, 10000, '$10,000');
data.setCell(0, 2, true);
data.setCell(1, 0, 'Mary');
data.setCell(1, 1, 25000, '$25,000');
data.setCell(1, 2, true);
data.setCell(2, 0, 'Steve');
data.setCell(2, 1, 8000, '$8,000');
data.setCell(2, 2, false);
data.setCell(3, 0, 'Ellen');
data.setCell(3, 1, 20000, '$20,000');
data.setCell(3, 2, true);
data.setCell(4, 0, 'Mike');
data.setCell(4, 1, 12000, '$12,000');
data.setCell(4, 2, false);
var table = new google.visualization.Table(document.getElementById('table_div'));
table.draw(data, {showRowNumber: true, width: '100%', height: '100%'});
google.visualization.events.addListener(table, 'select', function() {
var row = table.getSelection()[0].row;
alert('You selected ' + data.getValue(row, 0));
});
}
맞춤설정된 표의 예
<style>
.bold-green-font {
font-weight: bold;
color: green;
}
.bold-font {
font-weight: bold;
}
.right-text {
text-align: right;
}
.large-font {
font-size: 15px;
}
.italic-darkblue-font {
font-style: italic;
color: darkblue;
}
.italic-purple-font {
font-style: italic;
color: purple;
}
.underline-blue-font {
text-decoration: underline;
color: blue;
}
.gold-border {
border: 3px solid gold;
}
.deeppink-border {
border: 3px solid deeppink;
}
.orange-background {
background-color: orange;
}
.orchid-background {
background-color: orchid;
}
.beige-background {
background-color: beige;
}
</style>
...
function drawTable() {
var cssClassNames = {
'headerRow': 'italic-darkblue-font large-font bold-font',
'tableRow': '',
'oddTableRow': 'beige-background',
'selectedTableRow': 'orange-background large-font',
'hoverTableRow': '',
'headerCell': 'gold-border',
'tableCell': '',
'rowNumberCell': 'underline-blue-font'};
var options = {'showRowNumber': true, 'allowHtml': true, 'cssClassNames': cssClassNames};
var data = new google.visualization.DataTable();
data.addColumn('string', 'Name');
data.addColumn('number', 'Salary');
data.addColumn('boolean', 'Full Time');
data.addRows(5);
data.setCell(0, 0, 'John');
data.setCell(0, 1, 10000, '$10,000', {'className': 'bold-green-font large-font right-text'});
data.setCell(0, 2, true, {'style': 'background-color: red;'});
data.setCell(1, 0, 'Mary', null, {'className': 'bold-font'});
data.setCell(1, 1, 25000, '$25,000', {'className': 'bold-font right-text'});
data.setCell(1, 2, true, {'className': 'bold-font'});
data.setCell(2, 0, 'Steve', null, {'className': 'deeppink-border'});
data.setCell(2, 1, 8000, '$8,000', {'className': 'deeppink-border right-text'});
data.setCell(2, 2, false, null);
data.setCell(3, 0, 'Ellen', null, {'className': 'italic-purple-font large-font'});
data.setCell(3, 1, 20000, '$20,000');
data.setCell(3, 2, true);
data.setCell(4, 0, 'Mike');
data.setCell(4, 1, 12000, '$12,000');
data.setCell(4, 2, false);
var container = document.getElementById('table');
var table = new google.visualization.Table(container);
table.draw(data, options);
table.setSelection([{'row': 4}]);
}
게이지 예
강도:
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['gauge']});
google.charts.setOnLoadCallback(drawGauge);
var gaugeOptions = {min: 0, max: 280, yellowFrom: 200, yellowTo: 250,
redFrom: 250, redTo: 280, minorTicks: 5};
var gauge;
function drawGauge() {
gaugeData = new google.visualization.DataTable();
gaugeData.addColumn('number', 'Engine');
gaugeData.addColumn('number', 'Torpedo');
gaugeData.addRows(2);
gaugeData.setCell(0, 0, 120);
gaugeData.setCell(0, 1, 80);
gauge = new google.visualization.Gauge(document.getElementById('gauge_div'));
gauge.draw(gaugeData, gaugeOptions);
}
function changeTemp(dir) {
gaugeData.setValue(0, 0, gaugeData.getValue(0, 0) + dir * 25);
gaugeData.setValue(0, 1, gaugeData.getValue(0, 1) + dir * 20);
gauge.draw(gaugeData, gaugeOptions);
}
</script>
</head>
<body>
<div id="gauge_div" style="width:280px; height: 140px;"></div>
<input type="button" value="Go Faster" onclick="changeTemp(1)" />
<input type="button" value="Slow down" onclick="changeTemp(-1)" />
</body>
</html>
상호작용 예
이 예에서는 더 복잡한 상호작용을 위해 시각화를 결합하는 방법을 보여줍니다.
다음 특징을 보여줍니다.
- DataView 객체를 사용하여 DataTable의 데이터를 제한하고 형식을 지정하는 방법
- 두 개의 시각화를 동일한 데이터에 연결하는 방법
- 테이블 시각화의 'sort' 이벤트를 사용하는 방법
- 형식 지정 도구를 사용하여 표시된 데이터의 형식을 다시 지정하는 방법
표의 헤더를 클릭하여 세로 막대형 차트도 정렬되는 것을 확인할 수 있습니다.
컨트롤 및 대시보드를 사용하면 여러 차트를 컨트롤과 결합하여 표시할 데이터를 조작할 수 있습니다.
function drawSort() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Name');
data.addColumn('number', 'Salary');
data.addColumn('boolean', 'Full Time');
data.addRows(5);
data.setCell(0, 0, 'John');
data.setCell(0, 1, 10000);
data.setCell(0, 2, true);
data.setCell(1, 0, 'Mary');
data.setCell(1, 1, 25000);
data.setCell(1, 2, true);
data.setCell(2, 0, 'Steve');
data.setCell(2, 1, 8000);
data.setCell(2, 2, false);
data.setCell(3, 0, 'Ellen');
data.setCell(3, 1, 20000);
data.setCell(3, 2, true);
data.setCell(4, 0, 'Mike');
data.setCell(4, 1, 12000);
data.setCell(4, 2, false);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1]);
var formatter = new google.visualization.NumberFormat({prefix: '$'});
formatter.format(data, 1); // Apply formatter to second column
var table = new google.visualization.Table(document.getElementById('table_sort_div'));
table.draw(data, {width: '100%', height: '100%'});
var chart = new google.visualization.BarChart(document.getElementById('chart_sort_div'));
chart.draw(view);
google.visualization.events.addListener(table, 'sort',
function(event) {
data.sort([{column: event.column, desc: !event.ascending}]);
chart.draw(view);
});
}
전체 HTML 페이지 예
시각화 차트가 삽입된 웹페이지를 만드는 엔드 투 엔드 예시입니다. 또한 Google 스프레드시트에 연결된 차트와 시각화 이벤트를 사용하여 상호작용하는 두 개의 차트를 보여줍니다.
이 예시에서는 가상의 영화 체인 회사의 인기 영화 및 영화관 위치에 관한 간단한 통계 페이지를 표시합니다.
이 페이지에는 서로 상호작용하여 영화관 위치를 표시하는 지도와 테이블 시각화가 포함됩니다. 이 페이지에는 위치별로 판매된 각 영화의 티켓 수를 표시하는 열 차트가 있습니다. Google Sheets에서 데이터를 가져옵니다. 이 스프레드시트의 게시된 버전을 완벽하게 볼 수 있습니다.
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {
'packages': ['table', 'map', 'corechart'],
// Note: you will need to get a mapsApiKey for your project.
// See: https://developers.google.com/chart/interactive/docs/basic_load_libs#load-settings
'mapsApiKey': 'AIzaSyD-9tSrke72PouQMnMX-a7eZSW0jkFMBWY'
});
google.charts.setOnLoadCallback(initialize);
function initialize() {
// The URL of the spreadsheet to source data from.
var query = new google.visualization.Query(
'https://spreadsheets.google.com/pub?key=pCQbetd-CptF0r8qmCOlZGg');
query.send(draw);
}
function draw(response) {
if (response.isError()) {
alert('Error in query');
}
var ticketsData = response.getDataTable();
var chart = new google.visualization.ColumnChart(
document.getElementById('chart_div'));
chart.draw(ticketsData, {'isStacked': true, 'legend': 'bottom',
'vAxis': {'title': 'Number of tickets'}});
var geoData = google.visualization.arrayToDataTable([
['Lat', 'Lon', 'Name', 'Food?'],
[51.5072, -0.1275, 'Cinematics London', true],
[48.8567, 2.3508, 'Cinematics Paris', true],
[55.7500, 37.6167, 'Cinematics Moscow', false]]);
var geoView = new google.visualization.DataView(geoData);
geoView.setColumns([0, 1]);
var table =
new google.visualization.Table(document.getElementById('table_div'));
table.draw(geoData, {showRowNumber: false, width: '100%', height: '100%'});
var map =
new google.visualization.Map(document.getElementById('map_div'));
map.draw(geoView, {showTip: true});
// Set a 'select' event listener for the table.
// When the table is selected, we set the selection on the map.
google.visualization.events.addListener(table, 'select',
function() {
map.setSelection(table.getSelection());
});
// Set a 'select' event listener for the map.
// When the map is selected, we set the selection on the table.
google.visualization.events.addListener(map, 'select',
function() {
table.setSelection(map.getSelection());
});
}
</script>
</head>
<body>
<table align="center">
<tr valign="top">
<td style="width: 50%;">
<div id="map_div" style="width: 400px; height: 300;"></div>
</td>
<td style="width: 50%;">
<div id="table_div"></div>
</td>
</tr>
<tr>
<td colSpan=2>
<div id="chart_div" style="align: center; width: 700px; height: 300px;"></div>
</td>
</tr>
</table>
</body>
</html>
쿼리 래퍼 예
이 예에서는 쿼리 전송의 여러 측면을 래핑하는 자바스크립트 객체를 만드는 방법을 보여줍니다. QueryWrapper라는 이 객체는 쿼리 문자열, 시각화 핸들, 시각화 옵션 집합을 사용하여 인스턴스화됩니다. 한 가지 메서드인 sendAndDraw()
를 외부 호출자에 노출합니다. 이 메서드는 쿼리 문자열을 보내고 응답을 처리하고 시각화에서 draw()
를 호출하거나 쿼리가 오류를 반환한 경우 오류 메시지를 표시합니다. 여기에서 호스트 페이지에는 조직 차트 시각화로 결과가 표시됩니다.
다음은 호스트 페이지의 코드입니다.
<!DOCTYPE html>
<html>
<head>
<title>Query Wrapper Example</title>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript" src="querywrapper.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages' : ['orgchart']});
google.charts.setOnLoadCallback(function() { sendAndDraw('') });
var dataSourceUrl = 'https://spreadsheets.google.com/tq?key=rCaVQNfFDMhOM6ENNYeYZ9Q&pub=1';
var query;
function sendAndDraw(queryString) {
var container = document.getElementById('orgchart');
var orgChart = new google.visualization.OrgChart(container);
query && query.abort();
query = new google.visualization.Query(dataSourceUrl + queryString);
var queryWrapper = new QueryWrapper(query, orgChart, {'size': 'large'}, container);
queryWrapper.sendAndDraw();
}
</script>
</head>
<body>
<h1>Query Wrapper Example</h1>
<form action="">
<span> This example uses the following spreadsheet: <br />
<a href="https://spreadsheets.google.com/pub?key=rCaVQNfFDMhOM6ENNYeYZ9Q">
https://spreadsheets.google.com/pub?key=rCaVQNfFDMhOM6ENNYeYZ9Q
</a></span>
<br /><br />
<select onChange="sendAndDraw(this.value)">
<option value="">No query string</option>
<option value="&tq=limit 3">query=limit 3</option>
<option value="&tq=select G,H">(Error) query=select G,H</option>
</select>
</form>
<br />
<div id="orgchart"></div>
</body>
</html>
QueryWrapper 객체의 JavaScript는 다음과 같습니다.
/**
* A google.visualization.Query Wrapper. Sends a
* query and draws the visualization with the returned data or outputs an
* error message.
*
* DISCLAIMER: This is an example code which you can copy and change as
* required. It is used with the google visualization API which is assumed to
* be loaded to the page. For more info see:
* https://developers.google.com/chart/interactive/docs/reference#Query
*/
/**
* Constructs a new query wrapper with the given query, visualization,
* visualization options, and error message container. The visualization
* should support the draw(dataTable, options) method.
* @constructor
*/
var QueryWrapper = function(query, visualization, visOptions, errorContainer) {
this.query = query;
this.visualization = visualization;
this.options = visOptions || {};
this.errorContainer = errorContainer;
this.currentDataTable = null;
if (!visualization || !('draw' in visualization) ||
(typeof(visualization['draw']) != 'function')) {
throw Error('Visualization must have a draw method.');
}
};
/** Draws the last returned data table, if no data table exists, does nothing.*/
QueryWrapper.prototype.draw = function() {
if (!this.currentDataTable) {
return;
}
this.visualization.draw(this.currentDataTable, this.options);
};
/**
* Sends the query and upon its return draws the visualization.
* If the query is set to refresh then the visualization will be drawn upon
* each refresh.
*/
QueryWrapper.prototype.sendAndDraw = function() {
var query = this.query;
var self = this;
query.send(function(response) {self.handleResponse(response)});
};
/** Handles the query response returned by the data source. */
QueryWrapper.prototype.handleResponse = function(response) {
this.currentDataTable = null;
if (response.isError()) {
this.handleErrorResponse(response);
} else {
this.currentDataTable = response.getDataTable();
this.draw();
}
};
/** Handles a query response error returned by the data source. */
QueryWrapper.prototype.handleErrorResponse = function(response) {
var message = response.getMessage();
var detailedMessage = response.getDetailedMessage();
if (this.errorContainer) {
google.visualization.errors.addError(this.errorContainer,
message, detailedMessage, {'showInTooltip': false});
} else {
throw Error(message + ' ' + detailedMessage);
}
};
/** Aborts the sending and drawing. */
QueryWrapper.prototype.abort = function() {
this.query.abort();
};
테이블 쿼리 래퍼 예
다음은 단일 요청으로 모든 데이터를 가져오지 않고도 대규모 데이터 세트를 페이징된 표 시각화로 표시하는 방법을 보여주는 예입니다. 이는 대량의 데이터가 있고 페이지에서 한 번에 모든 데이터를 요청하거나 저장하는 오버헤드를 피하려는 경우에 유용합니다.
JavaScript는 TableQueryWrapper 객체를 정의합니다. 이 객체는 정렬 및 페이지로 나누기를 처리하기 위해 요청을 수행하는 google.visualization.Query
객체와 테이블 시각화를 관리합니다. 객체는 google.visualization.Query
인스턴스, 시각화와 이로 인해 발생한 오류를 보유하는 데 사용되는 페이지 요소의 핸들, draw()
메서드에 전달할 옵션 (가져올 행 수를 pageSize
옵션으로 포함)을 사용하여 인스턴스화됩니다. 이 객체는 페이징 및 정렬 이벤트를 포착하고 처리하여 테이블 시각화를 관리합니다.
사용자가 앞 또는 뒤로 페이지를 넘기면 TableQueryWrapper는 적절한 LIMIT 및 OFFSET 값으로 새 쿼리를 만들고 전송하여 테이블 페이지를 다시 채우는 방식으로 이벤트를 처리합니다. 마찬가지로 사용자가 열을 클릭하여 정렬 순서를 변경하면 TableQueryWrapper는 적절한 ORDER BY 절로 새 쿼리를 만들고 전송하여 이벤트를 처리하고 다시 오프셋 0으로 재설정합니다.
다음 예시에서는 드롭다운 상자를 사용하여 표시할 테이블 행 수를 선택할 수 있습니다. 변경된 경우 호스트 페이지가 새 TableQueryWrapper 인스턴스를 만든 다음 선택된 행 수를 반영하는 LIMIT 절과 OFFSET 절이 없는 새 쿼리를 전송합니다 (즉, 첫 번째 행으로 다시 이동).
다음은 호스트 페이지의 코드입니다.
<!DOCTYPE html>
<html>
<head>
<title>Table Query Wrapper Example</title>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript" src="tablequerywrapper.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages' : ['table']});
google.charts.setOnLoadCallback(init);
var dataSourceUrl = 'https://spreadsheets.google.com/tq?key=rh_6pF1K_XsruwVr_doofvw&pub=1';
var query, options, container;
function init() {
query = new google.visualization.Query(dataSourceUrl);
container = document.getElementById("table");
options = {'pageSize': 5};
sendAndDraw();
}
function sendAndDraw() {
query.abort();
var tableQueryWrapper = new TableQueryWrapper(query, container, options);
tableQueryWrapper.sendAndDraw();
}
function setOption(prop, value) {
options[prop] = value;
sendAndDraw();
}
</script>
</head>
<body>
<p>This example uses the following spreadsheet: <br />
<a href="https://spreadsheets.google.com/pub?key=rh_6pF1K_XsruwVr_doofvw">
https://spreadsheets.google.com/pub?key=rh_6pF1K_XsruwVr_doofvw
</a>
</p>
<form action="">
Number of rows to show:
<select onChange="setOption('pageSize', parseInt(this.value, 10))">
<option value="0">0</option>
<option value="3">3</option>
<option selected=selected value="5">5</option>
<option value="8">8</option>
<option value="-1">-1</option>
</select>
</form>
<br />
<div id="table"></div>
</body>
</html>
다음은 TableQueryWrapper 객체의 JavaScript 코드입니다.
/**
* A wrapper for a query and a table visualization.
* The object only requests 1 page + 1 row at a time, by default, in order
* to minimize the amount of data held locally.
* Table sorting and pagination is executed by issuing
* additional requests with appropriate query parameters.
* E.g., for getting the data sorted by column 'A' the following query is
* attached to the request: 'tq=order by A'.
*
* Note: Discards query strings set by the user on the query object using
* google.visualization.Query#setQuery.
*
* DISCLAIMER: This is an example code which you can copy and change as
* required. It is used with the google visualization API table visualization
* which is assumed to be loaded to the page. For more info see:
* https://developers.google.com/chart/interactive/docs/gallery/table
* https://developers.google.com/chart/interactive/docs/reference#Query
*/
/**
* Constructs a new table query wrapper for the specified query, container
* and tableOptions.
*
* Note: The wrapper clones the options object to adjust some of its properties.
* In particular:
* sort {string} set to 'event'.
* page {string} set to 'event'.
* pageSize {Number} If number <= 0 set to 10.
* showRowNumber {boolean} set to true.
* firstRowNumber {number} set according to the current page.
* sortAscending {boolean} set according to the current sort.
* sortColumn {number} set according to the given sort.
* @constructor
*/
var TableQueryWrapper = function(query, container, options) {
this.table = new google.visualization.Table(container);
this.query = query;
this.sortQueryClause = '';
this.pageQueryClause = '';
this.container = container;
this.currentDataTable = null;
var self = this;
var addListener = google.visualization.events.addListener;
addListener(this.table, 'page', function(e) {self.handlePage(e)});
addListener(this.table, 'sort', function(e) {self.handleSort(e)});
options = options || {};
options = TableQueryWrapper.clone(options);
options['sort'] = 'event';
options['page'] = 'event';
options['showRowNumber'] = true;
var buttonConfig = 'pagingButtonsConfiguration';
options[buttonConfig] = options[buttonConfig] || 'both';
options['pageSize'] = (options['pageSize'] > 0) ? options['pageSize'] : 10;
this.pageSize = options['pageSize'];
this.tableOptions = options;
this.currentPageIndex = 0;
this.setPageQueryClause(0);
};
/**
* Sends the query and upon its return draws the Table visualization in the
* container. If the query refresh interval is set then the visualization will
* be redrawn upon each refresh.
*/
TableQueryWrapper.prototype.sendAndDraw = function() {
this.query.abort();
var queryClause = this.sortQueryClause + ' ' + this.pageQueryClause;
this.query.setQuery(queryClause);
this.table.setSelection([]);
var self = this;
this.query.send(function(response) {self.handleResponse(response)});
};
/** Handles the query response after a send returned by the data source. */
TableQueryWrapper.prototype.handleResponse = function(response) {
this.currentDataTable = null;
if (response.isError()) {
google.visualization.errors.addError(this.container, response.getMessage(),
response.getDetailedMessage(), {'showInTooltip': false});
} else {
this.currentDataTable = response.getDataTable();
this.table.draw(this.currentDataTable, this.tableOptions);
}
};
/** Handles a sort event with the given properties. Will page to page=0. */
TableQueryWrapper.prototype.handleSort = function(properties) {
var columnIndex = properties['column'];
var isAscending = properties['ascending'];
this.tableOptions['sortColumn'] = columnIndex;
this.tableOptions['sortAscending'] = isAscending;
// dataTable exists since the user clicked the table.
var colID = this.currentDataTable.getColumnId(columnIndex);
this.sortQueryClause = 'order by `' + colID + (!isAscending ? '` desc' : '`');
// Calls sendAndDraw internally.
this.handlePage({'page': 0});
};
/** Handles a page event with the given properties. */
TableQueryWrapper.prototype.handlePage = function(properties) {
var localTableNewPage = properties['page']; // 1, -1 or 0
var newPage = 0;
if (localTableNewPage != 0) {
newPage = this.currentPageIndex + localTableNewPage;
}
if (this.setPageQueryClause(newPage)) {
this.sendAndDraw();
}
};
/**
* Sets the pageQueryClause and table options for a new page request.
* In case the next page is requested - checks that another page exists
* based on the previous request.
* Returns true if a new page query clause was set, false otherwise.
*/
TableQueryWrapper.prototype.setPageQueryClause = function(pageIndex) {
var pageSize = this.pageSize;
if (pageIndex < 0) {
return false;
}
var dataTable = this.currentDataTable;
if ((pageIndex == this.currentPageIndex + 1) && dataTable) {
if (dataTable.getNumberOfRows() <= pageSize) {
return false;
}
}
this.currentPageIndex = pageIndex;
var newStartRow = this.currentPageIndex * pageSize;
// Get the pageSize + 1 so that we can know when the last page is reached.
this.pageQueryClause = 'limit ' + (pageSize + 1) + ' offset ' + newStartRow;
// Note: row numbers are 1-based yet dataTable rows are 0-based.
this.tableOptions['firstRowNumber'] = newStartRow + 1;
return true;
};
/** Performs a shallow clone of the given object. */
TableQueryWrapper.clone = function(obj) {
var newObj = {};
for (var key in obj) {
newObj[key] = obj[key];
}
return newObj;
};
마우스 오버 도움말 예
이 예시에서는 마우스 오버 이벤트를 수신 대기하여 차트에 도움말을 표시하는 방법을 보여줍니다.
<script>
// barsVisualization must be global in our script tag to be able
// to get and set selection.
var barsVisualization;
function drawMouseoverVisualization() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Year');
data.addColumn('number', 'Score');
data.addRows([
['2005',3.6],
['2006',4.1],
['2007',3.8],
['2008',3.9],
['2009',4.6]
]);
barsVisualization = new google.visualization.ColumnChart(document.getElementById('mouseoverdiv'));
barsVisualization.draw(data, null);
// Add our over/out handlers.
google.visualization.events.addListener(barsVisualization, 'onmouseover', barMouseOver);
google.visualization.events.addListener(barsVisualization, 'onmouseout', barMouseOut);
}
function barMouseOver(e) {
barsVisualization.setSelection([e]);
}
function barMouseOut(e) {
barsVisualization.setSelection([{'row': null, 'column': null}]);
}
</script>