Skip to content
Snippets Groups Projects
Commit e9d0d571 authored by Kevin Hill's avatar Kevin Hill
Browse files

[ci skip] added event relays and event examples

parent e1fdb039
No related branches found
No related tags found
No related merge requests found
Source diff could not be displayed: it is too large. Options to address this: view the blob.
<!doctype html>
<html>
<head>
<title>Lava.js | Events</title>
<script type="text/javascript" src="../dist/lava.js"></script>
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
<style rel="stylesheet" type="text/css">
html, body {
background-color: #fff;
color: #636b6f;
font-family: 'Nunito', sans-serif;
font-weight: 100;
height: 100vh;
margin: 0;
}
p {
font-size: larger;
}
.flex-center {
align-items: center;
display: flex;
justify-content: center;
}
.position-ref {
position: relative;
}
.align-left {
text-align: left;
}
.float {
float: left;
}
.content {
text-align: center;
}
.title {
font-size: 74px;
}
</style>
</head>
<body>
<div class="flex-center position-ref">
<div class="content">
<div class="title">
Lava.js v4.0
</div>
<p>Event integration (click a slice!)</p>
<div>
<div class="align-left float">
<pre><code>
var chartJson = {
label: "Test",
type: "PieChart",
elementId: "my-pie-chart",
datatable: function (data) {
data.addColumn('string', 'Topping');
data.addColumn('number', 'Slices');
data.addRows([
['Mushrooms', 3],
['Onions', 1],
['Olives', 1],
['Zucchini', 1],
['Pepperoni', 2]
]);
return data;
},
options: {
title: 'My Daily Activities'
},
};
var chart = lava.store(chartJson);
chart.on('ready', function() {
console.log(this.uuid + ' is ready!');
});
chart.on('select', function (chart, data) {
var selectedItem = chart.getSelection()[0];
if (selectedItem) {
var topping = data.getValue(selectedItem.row, 0);
alert('The user selected ' + topping);
}
});
lava.run();
</code></pre>
</div>
<div class="float" style="width: 400px;">
<pre><code>
&#x3C;div id=&#x22;my-pie-chart&#x22;&#x3E;&#x3C;/div&#x3E;
</code></pre>
<div id="my-pie-chart"></div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
var chartJson = {
label: "Test",
type: "PieChart",
elementId: "my-pie-chart",
datatable: function (data) {
data.addColumn('string', 'Topping');
data.addColumn('number', 'Slices');
data.addRows([
['Mushrooms', 3],
['Onions', 1],
['Olives', 1],
['Zucchini', 1],
['Pepperoni', 2]
]);
return data;
},
options: {
title: 'My Daily Activities'
},
};
var chart = lava.store(chartJson);
chart.on('ready', function() {
alert(this.uuid + ' is ready!');
});
chart.on('select', function (chart, data) {
var selectedItem = chart.getSelection()[0];
if (selectedItem) {
var topping = data.getValue(selectedItem.row, 0);
alert('The user selected ' + topping);
}
});
lava.run();
</script>
</body>
</html>
<!doctype html>
<html>
<head>
<title>Lava.js Standalone</title>
<title>Lava.js | Basic Syntax</title>
<script type="text/javascript" src="../dist/lava.js"></script>
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
<style rel="stylesheet" type="text/css">
Loading
Loading
@@ -14,8 +14,8 @@
margin: 0;
}
 
.full-height {
height: 100vh;
p {
font-size: larger;
}
 
.flex-center {
Loading
Loading
@@ -28,29 +28,62 @@
position: relative;
}
 
.align-left {
text-align: left;
}
.float {
float: left;
}
.content {
text-align: center;
}
 
.title {
font-size: 84px;
}
.m-b-md {
margin-bottom: 10px;
font-size: 74px;
}
</style>
</head>
 
<body>
<div class="flex-center position-ref full-height">
<div class="flex-center position-ref">
<div class="content">
<div class="title m-b-md">
Lava.js <small>v4.0</small>
<div class="title">
Lava.js v4.0
</div>
<p>The Google Chart API wrapper.</p>
<div>
<div class="align-left float">
<pre><code>
var chartJson = {
label: "Test",
type: "PieChart",
elementId: "my-pie-chart",
datatable: [
['Task', 'Hours per Day'],
['Work', 11],
['Eat', 2],
['Commute', 2],
['Watch TV', 2],
['Sleep', 7]
],
options: {
title: 'My Daily Activities'
},
};
 
<div class="links">
<div id="my-pie-chart"></div>
lava.store(chartJson);
lava.run();
</code></pre>
</div>
<div class="float" style="width: 400px;">
<pre><code>
&#x3C;div id=&#x22;my-pie-chart&#x22;&#x3E;&#x3C;/div&#x3E;
</code></pre>
<div id="my-pie-chart"></div>
</div>
</div>
</div>
</div>
Loading
Loading
Loading
Loading
@@ -2,7 +2,7 @@
/* globals __OPTIONS__:true */
 
import LavaJs from './lava/Lava';
import { domLoaded } from './lava/Utils';
import {domLoaded} from './lava/Utils';
 
/**
* Assign the Lava.js module to the window and
Loading
Loading
Loading
Loading
@@ -43,7 +43,7 @@ export default class Chart extends Renderable
 
this.formats = json.formats;
 
this.events = typeof json.events === 'object' ? json.events : null;
//this.events = typeof json.events === 'object' ? json.events : null;
this.pngOutput = typeof json.pngOutput === 'undefined' ? false : Boolean(json.pngOutput);
 
/**
Loading
Loading
@@ -54,13 +54,15 @@ export default class Chart extends Renderable
 
this.gchart = new google.visualization[this.class](this.element);
 
this._attachEventRelays();
if (this.formats) {
this.applyFormats();
}
 
if (this.events) {
this._attachEvents();
}
// if (this.events) {
// this._attachEvents();
// }
 
this.draw();
 
Loading
Loading
@@ -111,9 +113,7 @@ export default class Chart extends Renderable
* @private
*/
_attachEvents() {
let $chart = this;
forIn(this.events, function (callback, event) {
forIn(this.events, (callback, event) => {
let context = window;
let func = callback;
 
Loading
Loading
@@ -122,17 +122,17 @@ export default class Chart extends Renderable
func = callback[1];
}
 
console.log(`[lava.js] The "${$chart.uuid}::${event}" event will be handled by "${func}" in the context`, context);
console.log(`[lava.js] The "${this.uuid}::${event}" event will be handled by "${func}" in the context`, context);
 
/**
* Set the context of "this" within the user provided callback to the
* chart that fired the event while providing the datatable of the chart
* to the callback as an argument.
*/
google.visualization.events.addListener($chart.gchart, event, function() {
const callback = context[func].bind($chart.gchart);
google.visualization.events.addListener(this.gchart, event, () => {
let callback = context[func].bind(this.gchart);
 
callback($chart.data);
callback(this.data);
});
});
}
Loading
Loading
Loading
Loading
@@ -13,10 +13,10 @@ import uniq from 'lodash/uniq';
import EventEmitter from 'events';
import Chart from './Chart';
import Dashboard from './Dashboard';
import Renderable from './Renderable';
import defaultOptions from './Options';
import {addEvent, getType, noop} from './Utils';
import {InvalidCallback, RenderableNotFound} from './Errors'
import Renderable from './Renderable';
 
/**
* @property {string} VERSION
Loading
Loading
@@ -93,7 +93,7 @@ export default class LavaJs extends EventEmitter {
* @protected
* @callback _readyCallback
*/
this._readyCallback = noop;
this._readyCallback = undefined;
}
 
/**
Loading
Loading
@@ -132,6 +132,8 @@ export default class LavaJs extends EventEmitter {
this._addPackages(renderable.packages);
 
this._volcano[renderable.label] = renderable;
return renderable;
}
 
/**
Loading
Loading
@@ -148,24 +150,17 @@ export default class LavaJs extends EventEmitter {
* for some examples relative to LineCharts.
*
* @public
* @param {string} label
* @param {Function} callback
* @throws InvalidLabel
* @throws InvalidCallback
* @param {string} label
* @throws RenderableNotFound
*/
get(label, callback) {
if (typeof callback !== 'function') {
throw new InvalidCallback(callback);
}
get(label) {
let renderable = this._volcano[label];
 
if (!renderable) {
if (! renderable) {
throw new RenderableNotFound(label);
}
 
callback(renderable);
return renderable;
}
 
/**
Loading
Loading
@@ -193,8 +188,10 @@ export default class LavaJs extends EventEmitter {
console.log('[lava.js] Firing "ready" event.');
this.emit('ready');
 
console.log('[lava.js] Executing lava.ready(callback)');
this._readyCallback();
if (this._readyCallback) {
console.log('[lava.js] Executing lava.ready(callback)');
this._readyCallback();
}
});
}
 
Loading
Loading
@@ -212,7 +209,7 @@ export default class LavaJs extends EventEmitter {
throw new InvalidCallback(callback);
}
 
this._readyCallback = callback;
this._readyCallback = callback.bind(this);
}
 
/**
Loading
Loading
Loading
Loading
@@ -5,7 +5,7 @@
* @property {string} label - Label for the chart.
* @property {string} type - Type of chart.
* @property {Object} element - Html element in which to render the chart.
* @property {Object} chart - Google chart object.
* @property {Object} gchart - Google chart object.
* @property {string} package - Type of Google chart package to load.
* @property {boolean} pngOutput - Should the chart be displayed as a PNG.
* @property {Object} data - Datatable for the chart.
Loading
Loading
@@ -18,9 +18,10 @@
* @property {Function} uuid - Creates identification string for the chart.
* @property {Object} _errors - Collection of errors to be thrown.
*/
import {getType} from "./Utils"
import {ElementIdNotFound} from "./Errors";
import EventEmitter from 'events';
import getProperties from './VisualizationMap';
import {getType} from './Utils'
import {ElementIdNotFound} from './Errors';
 
/**
* Chart module
Loading
Loading
@@ -31,8 +32,7 @@ import getProperties from './VisualizationMap';
* @copyright (c) 2017, KHill Designs
* @license MIT
*/
export default class Renderable
{
export default class Renderable extends EventEmitter {
/**
* Chart Class
*
Loading
Loading
@@ -43,6 +43,8 @@ export default class Renderable
* @constructor
*/
constructor(json) {
super();
this.gchart = null;
this.type = json.type;
this.label = json.label;
Loading
Loading
@@ -52,7 +54,7 @@ export default class Renderable
 
this.element = document.getElementById(this.elementId);
 
if (! this.element) {
if (!this.element) {
throw new ElementIdNotFound(this.elementId);
}
}
Loading
Loading
@@ -62,8 +64,7 @@ export default class Renderable
*
* @return {string}
*/
get class()
{
get class() {
return getProperties(this.type).class;
}
 
Loading
Loading
@@ -72,8 +73,7 @@ export default class Renderable
*
* @return {string}
*/
get packages()
{
get packages() {
return getProperties(this.type).package;
}
 
Loading
Loading
@@ -83,7 +83,7 @@ export default class Renderable
* @return {string}
*/
get uuid() {
return this.type+'::'+this.label;
return this.type + '::' + this.label;
}
 
/**
Loading
Loading
@@ -104,25 +104,10 @@ export default class Renderable
* @param {object} payload Json representation of a DataTable
*/
setData(payload) {
// If the payload is from the php class JoinedDataTable->toJson(), then create
// two new DataTables and join them with the defined options.
if (getType(payload.data) === 'Array') {
this.data = google.visualization.data.join(
new google.visualization.DataTable(payload.data[0]),
new google.visualization.DataTable(payload.data[1]),
payload.keys,
payload.joinMethod,
payload.dt2Columns,
payload.dt2Columns
);
return;
}
// Since Google compiles their classes, we can't use instanceof to check since
// it is no longer called a "DataTable" (it's "gvjs_P" but that could change...)
if (getType(payload.getTableProperties) === 'Function') {
this.data = payload;
// If a function is received, then create an new DataTable and pass it to the
// function for user modifications.
if (getType(payload) === 'Function') {
this.data = payload(new google.visualization.DataTable());
 
return;
}
Loading
Loading
@@ -140,6 +125,30 @@ export default class Renderable
payload = payload.data;
 
// TODO: handle formats better...
return;
}
// Since Google compiles their classes, we can't use instanceof to check since
// it is no longer called a "DataTable" (it's "gvjs_P" but that could change...)
if (getType(payload.getTableProperties) === 'Function') {
this.data = payload;
return;
}
// If the payload is from the php class JoinedDataTable->toJson(), then create
// two new DataTables and join them with the defined options.
if (getType(payload.data) === 'Array') {
this.data = google.visualization.data.join(
new google.visualization.DataTable(payload.data[0]),
new google.visualization.DataTable(payload.data[1]),
payload.keys,
payload.joinMethod,
payload.dt2Columns,
payload.dt2Columns
);
return;
}
 
// If we reach here, then it must be standard JSON for creating a DataTable.
Loading
Loading
@@ -155,4 +164,26 @@ export default class Renderable
setOptions(options) {
this.options = options;
}
/**
* Attach event emitters onto the google chart as relays for listening
* to the events from the lavachart.
*
* @private
*/
_attachEventRelays() {
let defaultEvents = [
'ready',
'select',
'error',
'onmouseover',
'onmouseout'
];
defaultEvents.forEach(event => {
google.visualization.events.addListener(
this.gchart, event, () => this.emit(event, this.gchart, this.data)
);
});
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment