Center Highstock chart scrollbar handle - charts

I have a bunch of stock charts rendered with Highstock charting API.
In an attempt to center the scrollbar handle for each chart, I use the following piece of code:
/* ============ Position chart scroll BEGIN ============ */
$(".highcharts-container").each(function () {
var scrollBar = $(this).find('.highcharts-scrollbar');
var scrollBarElms = scrollBar.find('rect');
var scrollBarTrackWidth = $(scrollBarElms[0]).attr("width");
var scrollBarHandleWidth = $(scrollBarElms[1]).attr("width");
var xPos = (scrollBarTrackWidth / 2) - (scrollBarHandleWidth / 2);
$(scrollBarElms[1]).attr("x", xPos);
});
/* ============ Position chart scroll END ============ */
The problem is that the handle and the 3 vertical lines that should 'decorate' it are separated. (You can see the entire thing HERE.)
Any suggestions on how to keep them together?

function getData() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -999; i <= 0; i = i + 1) {
data.push([
time + i * 1000,
Math.round(Math.random() * 100)]);
}
return data;
}
function getRange(data) {
var l = data.length,
range = l * 0.1, // number of points -> 10%
min = data[Math.round(l / 2 - range / 2)][0],
max = data[Math.round(l / 2 + range / 2)][0];
return {
min: min,
max: max
};
}
/* ============ CHARTS OPTIONS BEGIN ============ */
var options = {
chart: {
zoomType: 'x',
events: {
load: function () {
// set up the updating of the chart each second
var series = this.series[0];
setInterval(function () {
var x = (new Date()).getTime();
var y = Math.round(Math.random() * 100);
series.addPoint([x, y]);
}, 1000);
}
}
},
xAxis: {
},
rangeSelector: {
buttons: [{
count: 1,
type: 'minute',
text: '1M'
}, {
count: 5,
type: 'minute',
text: '5M'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 0
},
title: {
text: null
},
exporting: {
enabled: false
},
// Disable navigator
navigator: {
enabled: false
},
series: [{
name: ''
}]
}
/* ============ CHARTS OPTIONS END ============ */
/* ============ DRAW CHARTS BEGIN ============ */
function renderCharts() {
$('div.chart-container').each(function () {
var chartId = $(this).attr('id');
var chartIdParts = chartId.split('-');
var chartIdentifier = chartIdParts[1];
//Set chart options dinamically
var chartId = "chart" + chartIdentifier;
var chart = $('#' + chartId);
var renderTo = "chartcontainer-" + chartIdentifier;
//Render Charts for each aech container
options.chart.renderTo = renderTo;
options.chart.type = 'line';
options.series[0].data = getData();
var range = getRange(options.series[0].data);
options.xAxis.min = range.min;
options.xAxis.max = range.max;
var chart = new Highcharts.StockChart($.extend(true, {}, options));
});
}
function setChatType() {
// Show types list (piker)
$('.current-type').on('click', function () {
$(this).parents('div.chart-options').find('ul.type ul').addClass('clicked');
});
$('.chart-options ul ul li a').on('click', function () {
//Get piked chart type
var type = $(this).parent('li').attr('data-chart-type');
// For text and Title Capitalization
var textAndTitle = type.replace(/^[a-z]/, function (m) {
return m.toUpperCase()
});
// Show piked type in picker
var currSetClass = 'current-type ' + type;
$(this).parents('.chart-options').find('.current-type')
.text(textAndTitle)
.attr({
class: currSetClass,
title: textAndTitle
});
// Then Hide the types list
$('.chart-options ul ul').removeClass('clicked');
//Identify current chart container by ID
var chartCtnId = $(this).parents('div.chart').find('.chart-container').attr('id');
// Render chart again with new type
options.chart.renderTo = chartCtnId;
options.chart.type = type;
var chart = new Highcharts.StockChart($.extend(true, {}, options));
});
}
/* ============ DRAW CHARTS END ============ */
$(document).ready(function () {
$("article.grid:even").addClass('left')
$("article.grid:odd").addClass('right');
// Draw charts
renderCharts();
// Set/change chart type
setChatType();
});
The entire solution can be found HERE.
Thanks to Paweł Fus for help!

Related

change tooltip color in amchart

I want to change the background colour of the tooltip value in Amchart 5.
I mean the black background colour.
You can create an instance of Tooltip and store it in a variable. Use it in your valueAxis configuration, then modify the background color of your tooltip through its background element.
let tooltip = am5.Tooltip.new(root, {});
let valueAxis = mainPanel.yAxes.push(
am5xy.ValueAxis.new(root, {
// ...
tooltip,
// ...
})
);
tooltip.get("background").set("fill", am5.color(0x0000ff));
Full example (using this demo from the official website):
am5.ready(function() {
// Create root element
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/getting-started/#Root_element
let root = am5.Root.new("chartdiv");
// Set themes
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/concepts/themes/
root.setThemes([am5themes_Animated.new(root)]);
// Create a stock chart
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/charts/stock-chart/#Instantiating_the_chart
let stockChart = root.container.children.push(
am5stock.StockChart.new(root, {})
);
// Set global number format
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/concepts/formatters/formatting-numbers/
root.numberFormatter.set("numberFormat", "#,###.00");
// Create a main stock panel (chart)
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/charts/stock-chart/#Adding_panels
let mainPanel = stockChart.panels.push(
am5stock.StockPanel.new(root, {
wheelY: "zoomX",
panX: true,
panY: true
})
);
// Create value axis
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
let tooltip = am5.Tooltip.new(root, {});
let valueAxis = mainPanel.yAxes.push(
am5xy.ValueAxis.new(root, {
renderer: am5xy.AxisRendererY.new(root, {
pan: "zoom"
}),
extraMin: 0.1, // adds some space for for main series
tooltip,
numberFormat: "#,###.00",
extraTooltipPrecision: 2
})
);
tooltip.get("background").set("fill", am5.color(0x0000ff));
let dateAxis = mainPanel.xAxes.push(
am5xy.GaplessDateAxis.new(root, {
baseInterval: {
timeUnit: "minute",
count: 1
},
renderer: am5xy.AxisRendererX.new(root, {}),
tooltip: am5.Tooltip.new(root, {})
})
);
// add range which will show current value
let currentValueDataItem = valueAxis.createAxisRange(valueAxis.makeDataItem({ value: 0 }));
let currentLabel = currentValueDataItem.get("label");
if (currentLabel) {
currentLabel.setAll({
fill: am5.color(0xffffff),
background: am5.Rectangle.new(root, { fill: am5.color(0x000000) })
})
}
let currentGrid = currentValueDataItem.get("grid");
if (currentGrid) {
currentGrid.setAll({ strokeOpacity: 0.5, strokeDasharray: [2, 5] });
}
// Add series
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/charts/xy-chart/series/
let valueSeries = mainPanel.series.push(
am5xy.CandlestickSeries.new(root, {
name: "AMCH",
clustered: false,
valueXField: "Date",
valueYField: "Close",
highValueYField: "High",
lowValueYField: "Low",
openValueYField: "Open",
calculateAggregates: true,
xAxis: dateAxis,
yAxis: valueAxis,
legendValueText:
"open: [bold]{openValueY}[/] high: [bold]{highValueY}[/] low: [bold]{lowValueY}[/] close: [bold]{valueY}[/]",
legendRangeValueText: ""
})
);
// Set main value series
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/charts/stock-chart/#Setting_main_series
stockChart.set("stockSeries", valueSeries);
// Add a stock legend
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/charts/stock-chart/stock-legend/
let valueLegend = mainPanel.plotContainer.children.push(
am5stock.StockLegend.new(root, {
stockChart: stockChart
})
);
// Set main series
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/charts/stock-chart/#Setting_main_series
valueLegend.data.setAll([valueSeries]);
// Add cursor(s)
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/charts/xy-chart/cursor/
mainPanel.set(
"cursor",
am5xy.XYCursor.new(root, {
yAxis: valueAxis,
xAxis: dateAxis,
snapToSeries: [valueSeries],
snapToSeriesBy: "y!"
})
);
// Add scrollbar
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/charts/xy-chart/scrollbars/
let scrollbar = mainPanel.set(
"scrollbarX",
am5xy.XYChartScrollbar.new(root, {
orientation: "horizontal",
height: 50
})
);
stockChart.toolsContainer.children.push(scrollbar);
let sbDateAxis = scrollbar.chart.xAxes.push(
am5xy.GaplessDateAxis.new(root, {
baseInterval: {
timeUnit: "minute",
count: 1
},
renderer: am5xy.AxisRendererX.new(root, {})
})
);
let sbValueAxis = scrollbar.chart.yAxes.push(
am5xy.ValueAxis.new(root, {
renderer: am5xy.AxisRendererY.new(root, {})
})
);
let sbSeries = scrollbar.chart.series.push(
am5xy.LineSeries.new(root, {
valueYField: "Close",
valueXField: "Date",
xAxis: sbDateAxis,
yAxis: sbValueAxis
})
);
sbSeries.fills.template.setAll({
visible: true,
fillOpacity: 0.3
});
// Data generator
let firstDate = new Date();
let lastDate;
let value = 1200;
// data
function generateChartData() {
let chartData = [];
for (var i = 0; i < 50; i++) {
let newDate = new Date(firstDate);
newDate.setMinutes(newDate.getMinutes() - i);
value += Math.round((Math.random() < 0.49 ? 1 : -1) * Math.random() * 10);
let open = value + Math.round(Math.random() * 16 - 8);
let low = Math.min(value, open) - Math.round(Math.random() * 5);
let high = Math.max(value, open) + Math.round(Math.random() * 5);
chartData.unshift({
Date: newDate.getTime(),
Close: value,
Open: open,
Low: low,
High: high
});
lastDate = newDate;
}
return chartData;
}
let data = generateChartData();
// set data to all series
valueSeries.data.setAll(data);
sbSeries.data.setAll(data);
// update data
let previousDate;
setInterval(function() {
let valueSeries = stockChart.get("stockSeries");
let date = Date.now();
let lastDataObject = valueSeries.data.getIndex(valueSeries.data.length - 1);
if (lastDataObject) {
let previousDate = lastDataObject.Date;
let previousValue = lastDataObject.Close;
value = am5.math.round(previousValue + (Math.random() < 0.5 ? 1 : -1) * Math.random() * 2, 2);
let high = lastDataObject.High;
let low = lastDataObject.Low;
let open = lastDataObject.Open;
if (am5.time.checkChange(date, previousDate, "minute")) {
open = value;
high = value;
low = value;
let dObj1 = {
Date: date,
Close: value,
Open: value,
Low: value,
High: value
};
valueSeries.data.push(dObj1);
sbSeries.data.push(dObj1);
previousDate = date;
} else {
if (value > high) {
high = value;
}
if (value < low) {
low = value;
}
let dObj2 = {
Date: date,
Close: value,
Open: open,
Low: low,
High: high
};
valueSeries.data.setIndex(valueSeries.data.length - 1, dObj2);
sbSeries.data.setIndex(sbSeries.data.length - 1, dObj2);
}
// update current value
if (currentLabel) {
currentValueDataItem.animate({ key: "value", to: value, duration: 500, easing: am5.ease.out(am5.ease.cubic) });
currentLabel.set("text", stockChart.getNumberFormatter().format(value));
let bg = currentLabel.get("background");
if (bg) {
if(value < open){
bg.set("fill", root.interfaceColors.get("negative"));
}
else{
bg.set("fill", root.interfaceColors.get("positive"));
}
}
}
}
}, 1000);
}); // end am5.ready()
#chartdiv {
width: 100%;
height: 350px;
}
<script src="https://cdn.amcharts.com/lib/5/index.js"></script>
<script src="https://cdn.amcharts.com/lib/5/xy.js"></script>
<script src="https://cdn.amcharts.com/lib/5/stock.js"></script>
<script src="https://cdn.amcharts.com/lib/5/themes/Animated.js"></script>
<div id="chartdiv"></div>

How to display totals to google chart

I want to display the total for each stacked column on the end of the column.
I cant quite work out how to total the columns within the setColumns view code i have below. Can anyone help finalise this?
I am looking to achieve the total on the end of the stacked column like this:
[![enter image description here][1]][1]
Here is my code so far that works for charting but not quite for displaying total labels
myDrawFunc(){
var data = new google.visualization.DataTable();
data.addColumn('string', 'Scenario');
for (var i = 0; i < rows.length; i++) {
ptype = rows[i].cells[2].querySelector('.part').value;
if (ptype.length > 0) {
console.log(ptype);
// Declare columns
data.addColumn('number', ptype);
}
}
for (var i = 0; i < tcd.length; i++) {
var dn = 1 + i;
designLabel = "Design " + dn;
tcd[i].unshift(designLabel);
}
data.addRows(tcd);
//var view = new google.visualization.DataView(data);
var view = getDataView(data);
console.log(data);
chart = new google.visualization.BarChart(document.getElementById('chart_div'));
chart.draw(view, globalOptions);
}
//get Data view
function getDataView(dataTable) {
var dataView;
var viewColumns = [];
var columnsTotal = dataTable.getNumberOfColumns();
for (var i = 0; i < columnsTotal; i++) {
addViewColumn(viewColumns, i);
//add extra columns
if (i == columnsTotal) {
pushExtraCols(viewColumns);
}
}
// set series for displaying total columns
createSeries(columnsTotal) ;
dataView = new google.visualization.DataView(dataTable);
dataView.setColumns(viewColumns);
return dataView;
}
function addViewColumn(viewColumns, index) {
viewColumns.push(index);
if (index > 0) {
viewColumns.push({
calc: function (dt, row) {
console.log(row, index);
return dt.getValue(row, index);
},
role: 'annotation',
type: 'number'
});
}
}
function createSeries(columnsTotal) {
var seriesT = columnsTotal - 1;
console.log(seriesT);
seriesObj = {
[seriesT]: {
annotations: {
stem: {
color: "transparent",
length: 128
},
textStyle: {
color: "red",
}
},
enableInteractivity: false,
tooltip: "none",
visibleInLegend: false
}
}
globalOptions.series = seriesObj;
}
function pushExtraCols(viewColumns) {
viewColumns.push(
{
calc: function (dt, row) {
return 0;
},
label: "Total",
type: "number",
});
viewColumns.push({
calc: function (dt, row) {
return getTotal(dt, row);
},
type: "number",
role: "annotation"
});
}
//add up row total per column
function getTotal(dt, row) {
total = 0;
for (var i = 0; i < dt.getNumberOfColumns()-1; i++) {
total += dt.getValue(row, i);
}
console.log("total=" + total);
return total;
}
Try with parseInt
total = parseInt(total) + dt.getValue(row, i)

How do you properly configure an event listener/handler for a CategoryFilter control?

I am trying to plot the following sample data using a LineChart with a CategoryFilter to filter on year.
Data table is defined as:
aggData: [Date: date][Team: string][Score: number]
From the aggData table I dynamically calculate the default hAxis ticks as
var hAxisTicks = [];
var dateRange = aggData.getColumnRange(0);
for (var date = dateRange.min; date <= dateRange.max; date = new Date(date.getFullYear(), date.getMonth() + 1)) {
hAxisTicks.push(date);
}
The year picker and the line chart are configured as:
var yearPicker = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'categoryFilter_div',
options: {
filterColumnIndex: 0,
ui: {
allowTyping: false,
allowMultiple: false,
label: 'Year:',
labelStacking: 'vertical'
},
useFormattedValue: true
}
});
var lineChart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'chart_div',
options: {
width: 900,
height: 500,
hAxis: {
format: 'MMM', ticks: hAxisTicks
}
}
});
I added the following event listener
google.visualization.events.addListener(yearPicker, 'statechange', function () {
google.visualization.events.addOneTimeListener(lineChart, 'ready', getTicks);
});
I need to create/recreate the hAxis ticks everytime the yearPicker changes by calling getTicks
function getTicks() {
var ticks = [];
if (yearPicker.getState().selectedValues.length > 0) {
for (var i = 0; i <= hAxisTicks.length; i = i + 1) {
var date = new Date(hAxisTicks[i]);
if (date.getFullYear() == yearPicker.getState().selectedValues[0]) {
ticks.push(date)
}
}
}
else {
for (var i = 0; i <= hAxisTicks.length; i = i + 1) {
var date = new Date(hAxisTicks[i]);
ticks.push(date);
}
lineChart.setOption('hAxis.ticks', ticks);
lineChart.draw();
}
lineChart.setOption('hAxis.ticks', ticks);
lineChart.draw();
}
Here's what happens at different stages
1- When page first loads the graph looks like (the getTicks function is NOT called) which is correct:
2- When the year is changed to 2019, for example, the hAxis ticks get recalculated (the getTicks function is does get called) and the graph appears to be correct
3- Attempting to go back to the default chart to display all years, an a.getTime is not a function error message appears under the CategoryFilter
4- Any subsequent attempts to change the CategoryFilter to any value throws a ```One or more participants failed to draw()
How can I rectify this behavior?
I realized my iteration over the hAxisTics array was incorrect. I should stop at < hAxisTics.length instead of <= hAxisTics.length and I should recalculate inside the event handler
google.visualization.events.addListener(yearPicker, 'statechange', function () {
var ticks = [];
if (yearPicker.getState().selectedValues.length > 0) {
for (var i = 0; i < hAxisTicks.length; i = i + 1) {
var date = new Date(hAxisTicks[i]);
if (date.getFullYear() == yearPicker.getState().selectedValues[0]) {
ticks.push(date)
}
}
}
else {
for (var i = 0; i < hAxisTicks.length; i = i + 1) {
var date = new Date(hAxisTicks[i]);
ticks.push(date);
}
lineChart.setOption('hAxis.ticks', ticks);
lineChart.draw();
}
lineChart.setOption('hAxis.ticks', ticks);
lineChart.draw();
});

Famo.us not loading Constructor of Strip View in Timbre Example

I am working no Timbre View Example of Famo.us, and what I am trying to achieve is simply open the page by clicking on strip view options in the app and closing the Menu Drawer as soon as I click on the Strip View option
for achieving this functionality I've read the Broad Cast and Listing from the Famo.us documentation. and wrote the following code in my example.
1) created a function to Broadcasting from an event handler with emit method and called it in Constructor of the Strip View.
Strip View:
define(function(require, exports, module) {
var View = require('famous/core/View');
var Surface = require('famous/core/Surface');
var Transform = require('famous/core/Transform');
var StateModifier = require('famous/modifiers/StateModifier');
var ImageSurface = require('famous/surfaces/ImageSurface');
var HeaderFooter = require('famous/views/HeaderFooterLayout');
var FastClick = require('famous/inputs/FastClick');
var check = true;
Boolean(check);
function StripView() {
View.apply(this, arguments);
_createBackground.call(this);
_createIcon.call(this);
_createTitle.call(this);
_setListenersForStripView.call(this);
}
StripView.prototype = Object.create(View.prototype);
StripView.prototype.constructor = StripView;
StripView.DEFAULT_OPTIONS = {
width: 320,
height: 55,
angle: -0.2,
iconSize: 32,
iconUrl: 'img/strip-icons/famous.png',
title: 'Famo.us',
fontSize: 26,
onload: 'StripView()'
};
function allFunctions()
{
_createBackground();
_createIcon();
_createTitle();
}
function _createBackground() {
this.backgroundSurface = new Surface({
size: [this.options.width, this.options.height],
properties: {
backgroundColor: 'black',
boxShadow: '0 0 1px black'
}
});
var rotateModifier = new StateModifier({
transform: Transform.rotateZ(this.options.angle)
});
var skewModifier = new StateModifier({
transform: Transform.skew(0, 0, this.options.angle)
});
this.add(rotateModifier).add(skewModifier).add(this.backgroundSurface);
// this.backgroundSurface.on("touchend", function(){alert("Click caught")})
}
function _createIcon() {
var iconSurface = new ImageSurface({
size: [this.options.iconSize, this.options.iconSize],
content: this.options.iconUrl,
pointerEvents: 'none'
});
var iconModifier = new StateModifier({
transform: Transform.translate(24, 2, 0)
});
this.add(iconModifier).add(iconSurface);
// iconSurface.on("click", function(){alert("Click caught")})
}
function _createTitle() {
this.titleSurface = new Surface({
size: [true, true],
pointerEvents: 'none',
content: this.options.title,
properties: {
color: 'white',
fontFamily: 'AvenirNextCondensed-DemiBold',
fontSize: this.options.fontSize + 'px',
textTransform: 'uppercase',
// pointerEvents : 'none'
}
});
var titleModifier = new StateModifier({
transform: Transform.thenMove(Transform.rotateZ(this.options.angle), [75, -5, 0])
});
this.add(titleModifier).add(this.titleSurface);
}
function _setListenersForStripView() {
this.backgroundSurface.on('touchend', function() {
this._eventOutput.emit('menuToggleforStripView');
alert('clicked on title');
}.bind(this));
}
module.exports = StripView;
});
2) Then created a Trigger Method in App View
App View:
define(function(require, exports, module) {
var View = require('famous/core/View');
var Surface = require('famous/core/Surface');
var Modifier = require('famous/core/Modifier');
var Transform = require('famous/core/Transform');
var StateModifier = require('famous/modifiers/StateModifier');
var Easing = require('famous/transitions/Easing');
var Transitionable = require('famous/transitions/Transitionable');
var GenericSync = require('famous/inputs/GenericSync');
var MouseSync = require('famous/inputs/MouseSync');
var TouchSync = require('famous/inputs/TouchSync');
GenericSync.register({'mouse': MouseSync, 'touch': TouchSync});
var PageView = require('views/PageView');
var StripView = require('views/StripView');
var MenuView = require('views/MenuView');
var StripData = require('data/StripData');
function AppView() {
View.apply(this, arguments);
this.menuToggle = false;
this.pageViewPos = new Transitionable(0);
this.stripViewPos = new Transitionable(0);
_createPageView.call(this);
_StripView.call(this);
_createMenuView.call(this);
_setListeners.call(this);
_handleSwipe.call(this);
_setListenersForStripView.call(this);
}
AppView.prototype = Object.create(View.prototype);
AppView.prototype.constructor = AppView;
AppView.DEFAULT_OPTIONS = {
openPosition: 276,
transition: {
duration: 300,
curve: 'easeOut'
},
posThreshold: 138,
velThreshold: 0.75
};
function _createPageView() {
this.pageView = new PageView();
this.pageModifier = new Modifier({
transform: function() {
return Transform.translate(this.pageViewPos.get(), 0, 0);
}.bind(this)
});
this._add(this.pageModifier).add(this.pageView);
}
function _StripView() {
this.stripView = new StripView();
this.stripModifier = new Modifier({
transform: function() {
return Transform.translate(this.stripViewPos.get(), 0, 0);
}.bind(this)
});
this._add(this.stripModifier).add(this.stripView);
}
function _createMenuView() {
this.menuView = new MenuView({stripData: StripData});
var menuModifier = new StateModifier({
transform: Transform.behind
});
this.add(menuModifier).add(this.menuView);
}
function _setListeners() {
this.pageView.on('menuToggle', this.toggleMenu.bind(this));
}
function _setListenersForStripView() {
this.stripView.on('menuToggleforStripView', this.toggleMenu.bind(this));
}
function _handleSwipe() {
var sync = new GenericSync(
['mouse', 'touch'],
{direction: GenericSync.DIRECTION_X}
);
this.pageView.pipe(sync);
sync.on('update', function(data) {
var currentPosition = this.pageViewPos.get();
if (currentPosition === 0 && data.velocity > 0) {
this.menuView.animateStrips();
}
this.pageViewPos.set(Math.max(0, currentPosition + data.delta));
}.bind(this));
sync.on('end', (function(data) {
var velocity = data.velocity;
var position = this.pageViewPos.get();
if (this.pageViewPos.get() > this.options.posThreshold) {
if (velocity < -this.options.velThreshold) {
this.slideLeft();
} else {
this.slideRight();
}
} else {
if (velocity > this.options.velThreshold) {
this.slideRight();
} else {
this.slideLeft();
}
}
}).bind(this));
}
AppView.prototype.toggleMenu = function() {
if (this.menuToggle) {
this.slideLeft();
} else {
this.slideRight();
this.menuView.animateStrips();
}
};
AppView.prototype.slideLeft = function() {
this.pageViewPos.set(0, this.options.transition, function() {
this.menuToggle = false;
}.bind(this));
};
AppView.prototype.slideRight = function() {
this.pageViewPos.set(this.options.openPosition, this.options.transition, function() {
this.menuToggle = true;
}.bind(this));
};
module.exports = AppView;
});
now what this code does, is create another strip overlapping the previous strips and it only works on the newly created strip view but not on the other strips which means when it comes back to srip view it loads only the DEFAULT_OPTIONS of strip view because the strip which is being generated newly and overlaping is titled famo.us
Please let me know where I am going wrong and how can I open a new view in my application by closing menu drawer.
Do you have a folder named 'data' with the 'StripData.js' file on your famo.us project?
I'm asking because I downloaded the the Starter Kit and I didn't find that file inside.

Integrating / adding Google Earth View to my map

I am creating an interactive map for a non profit association "Friends of Knox Mountain Park" but I am getting trouble with the Google Earth view.
I've been searching on the web for weeks and none of the solutions I found works for me. Can someone take a look of the code and let me know what I should do to include Google Earth View in the map? Thanks in advance.
The online project: http://www.virtualbc.ca/knoxmountain/
And this is the javascript file (mapa2.js) containing the google map's code:
google.load('earth', '1');
var map;
var googleEarth;
var gmarkers = [];
var iconShadow = new google.maps.MarkerImage('icons/shadow.png',
new google.maps.Size(46, 42),
new google.maps.Point(0,0),
new google.maps.Point(13, 42));
var sites = [
['Apex Trail - Shelter',49.91174271, -119.48507050, 4, '<img src="images/apex_point_high.jpg">','magenta','14'],
['Apex Trail',49.91286999, -119.48413424, 3, '<img src="images/apex_point_low.jpg">','lemon','1'],
['Gordon Trail',49.91971281, -119.47954356, 2, '<img src="images/apex_point_low.jpg">','lemon','1'],
['Paul Tomb Bay',49.92555541, -119.47710250, 1, '<img src="images/tomb_bay.jpg">','lemon','1']
];
var infowindow = null;
var overlay;
// Used to make Google Map quard coords to MapCruncher/BingMaps quard coords
function TileToQuadKey ( x, y, zoom)
{
var quad = "";
for (var i = zoom; i > 0; i--)
{
var mask = 1 << (i - 1);
var cell = 0;
if ((x & mask) != 0)
cell++;
if ((y & mask) != 0)
cell += 2;
quad += cell;
}
return quad;
}
function init() {
var centerMap = new google.maps.LatLng(49.909671, -119.482241);
var myOptions = {
zoom: 10,
center: centerMap,
mapTypeId: google.maps.MapTypeId.SATELLITE
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
// Create the tile layers
// ASTER Tile Layer
myASTEROptions = {
getTileUrl : function (a,b) {
return "http://www.virtualbc.ca/knoxmountain/map/" + TileToQuadKey(a.x,a.y,b) + ".png";
},
isPng: true,
opacity: 1.0,
tileSize: new google.maps.Size(256,256),
name: "ASTER",
minZoom:13,
maxZoom:20
}
ASTERMapType = new google.maps.ImageMapType( myASTEROptions );
map.overlayMapTypes.insertAt(0, ASTERMapType);
// Aerial Tile Layer
myAerialOptions = {
getTileUrl : function (a,b) {
return "http://www.virtualbc.ca/knoxmountain/map/" + TileToQuadKey(a.x,a.y,b) + ".png";
},
isPng: true,
opacity: 1.0,
tileSize: new google.maps.Size(256,256),
name: "Aerial",
minZoom:15,
maxZoom:21
}
AerialMapType = new google.maps.ImageMapType( myAerialOptions );
map.overlayMapTypes.insertAt(1, AerialMapType);
var panorama = new google.maps.StreetViewPanorama(map.getDiv());
panorama.setVisible(false);
panorama.set('enableCloseButton', true);
map.setStreetView(panorama);
panorama.setPosition(centerMap);
setMarkers(map, sites);
setZoom(map, sites);
infowindow = new google.maps.InfoWindow({
content: "Loading..."
});
googleEarth = new GoogleEarth(map);
google.maps.event.addListenerOnce(map, 'tilesloaded', addOverlays);
}
/*
This functions sets the markers (array)
*/
function setMarkers(map, markers) {
for (var i = 0; i < markers.length; i++) {
var site = markers[i];
var siteLatLng = new google.maps.LatLng(site[1], site[2]);
var marker = new google.maps.Marker({
position: siteLatLng,
map: map,
title: site[0],
zIndex: site[3],
html: site[4],
// Markers drop on the map
animation: google.maps.Animation.DROP,
icon: 'http://www.virtualbc.ca/knoxmountain/icons/icon.png',
shadow: iconShadow
});
gmarkers.push(marker);
google.maps.event.addListener(marker, "click", function () {
infowindow.setContent(this.html);
infowindow.open(map, this);
});
}
}
/*
Set the zoom to fit comfortably all the markers in the map
*/
function setZoom(map, markers) {
var boundbox = new google.maps.LatLngBounds();
for ( var i = 0; i < markers.length; i++ )
{
boundbox.extend(new google.maps.LatLng(markers[i][1], markers[i][2]));
}
map.setCenter(boundbox.getCenter());
map.fitBounds(boundbox);
}
// This function picks up the click and opens the corresponding info window
function myclick(i) {
google.maps.event.trigger(gmarkers[i-1], "click");
}
google.maps.event.addDomListener(window, 'load', init);
The first issue I notice with your site is you are linking to http://www.virtualbc.ca/src/googleearth-compiled.js which does not exist.