I´m using appcelerator studio %.2.0 GA webView with chartjs plugin line update.
With this code below, I have a perfect view in web browser like Chrome (without webview), but on android smartphone or emulator it not runs correctly. Appears a red line on the bottom and double line on the strokeGrid.
Does anybody help ?
This is the code:
Javascript-
var count = 0;
//
// create base UI tab and root window
//
var win = Titanium.UI.createWindow({
title:'BtTest',
backgroundColor:'#eff2d8',
layout: 'vertical'
});
var mainView = Ti.UI.createView({
top: 0,
width: Ti.UI.SIZE,
height: Ti.UI.SIZE,
backgroundColor: '#7cd0F7',
});
var webView = Ti.UI.createWebView({
backgroundColor: '#F0F8FF',
top:100,
left: 0,
height: Ti.UI.FILL,
width: Ti.UI.FILL,
cacheMode: Ti.UI.Android.WEBVIEW_LOAD_NO_CACHE,
borderColor: 'black',
url: 'html/lineChart.html'
});
mainView.add(webView);
function send(value)
{
Ti.App.fireEvent("app:fromChart", {message: value});
Ti.API.info('Sent: ', value);
count ++;
Ti.API.info("Count: " + count);
}
function interval()
{
setInterval(function()
{
send(Math.floor(Math.random() * 100));
}, 500);
}
interval();
win.add(mainView);
win.open();
HTML-
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<script src="../js/Chart.min.js"></script>
</head>
<body>
<canvas id="updating-chart" width="320" height="220"> </canvas>
<script>
var N = 20;
var zero_array = [];
for (i = 0; i < N; i++)
zero_array.push("");
var canvas = document.getElementById('updating-chart'),
ctx = canvas.getContext('2d'),
startingData = {
labels: zero_array,
datasets: [
{
strokeColor: "rgba(255,0,0,1)",
data: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
}]
},
latestLabel = startingData.labels[0];
var lineOptions = {
bezierCurve: false,
scaleOverlay : false,
scaleOverride : false,
scaleSteps : null,
scaleStepWidth : null,
scaleStartValue : null,
scaleLineColor : "rgba(0,0,0,1)",
scaleLineWidth : 1,
scaleShowLabels : true,
scaleLabel : "<%=value%>",
scaleFontFamily : "'Arial'",
scaleFontSize : 12,
scaleFontStyle : "normal",
scaleFontColor : "#666",
scaleShowGridLines : true,
scaleGridLineColor : "rgba(0,0,0,1)",
scaleGridLineWidth : 1,
pointDot : true,
pointDotRadius : 0,
pointDotStrokeWidth : 1,
datasetStroke : true,
datasetStrokeWidth : 2,
datasetFill : false,
animation : false,
responsive: false,
maintainAspectRatio: true
};
// We wait for everything to be loaded
window.onload = function main()
{
// Get the context of the canvas
var ctx = document.getElementById("line_example").getContext("2d");
// Create the Chart object
var line_example_chart = new Chart(ctx).Line(data,lineOptions);
// Used for the labels on the X axis
var label_idx = 1;
Ti.App.addEventListener("app:fromChart", function(e)
{
var msg = e.message;
if(msg == 0) msg = 1;
line_example_chart.removeData();
line_example_chart.addData([msg], label_idx++);
});
window();
};
</script>
If you are building for an older version of android, the webview for appcelerator was not Chromium based which might cause things to look a bit different. You can read more about it here.
A quote from the WebView documentation for appcelerator:
Starting with Android 4.4 (API Level 19), the WebView component is based off of Chromium, introducing a number of changes to its rendering engine. Web content may look or behave differently depending on the Android version. The WebView does not have full feature parity with Chrome for Android.
Related
So I have this quite CPU-consuming app: https://codepen.io/team/amcharts/pen/47c41af971fe467b8b41f29be7ed1880
It's a Canvas on which things are drawn (a lot).
HTML:
<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/themes/Animated.js"></script>
<div id="chartdiv" style="width:100%; height:400px"></div>
JavaScript:
/**
* ---------------------------------------
* This demo was created using amCharts 5.
*
* For more information visit:
* https://www.amcharts.com/
*
* Documentation is available at:
* https://www.amcharts.com/docs/v5/
* ---------------------------------------
*/
// Create root element
// https://www.amcharts.com/docs/v5/getting-started/#Root_element
var root = am5.Root.new("chartdiv");
// Set themes
// https://www.amcharts.com/docs/v5/concepts/themes/
root.setThemes([
am5themes_Animated.new(root)
]);
// Generate random data
var value = 100;
function generateChartData() {
var chartData = [];
var firstDate = new Date();
firstDate.setDate(firstDate.getDate() - 1000);
firstDate.setHours(0, 0, 0, 0);
for (var i = 0; i < 50; i++) {
var newDate = new Date(firstDate);
newDate.setSeconds(newDate.getSeconds() + i);
value += (Math.random() < 0.5 ? 1 : -1) * Math.random() * 10;
chartData.push({
date: newDate.getTime(),
value: value
});
}
return chartData;
}
var data = generateChartData();
// Create chart
// https://www.amcharts.com/docs/v5/charts/xy-chart/
var chart = root.container.children.push(am5xy.XYChart.new(root, {
focusable: true,
panX: true,
panY: true,
wheelX: "panX",
wheelY: "zoomX",
scrollbarX:am5.Scrollbar.new(root, {orientation:"horizontal"})
}));
var easing = am5.ease.linear;
// Create axes
// https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
var xAxis = chart.xAxes.push(am5xy.DateAxis.new(root, {
maxDeviation: 0.5,
groupData: false,
extraMax:0.1, // this adds some space in front
extraMin:-0.1, // this removes some space form th beginning so that the line would not be cut off
baseInterval: {
timeUnit: "second",
count: 1
},
renderer: am5xy.AxisRendererX.new(root, {
minGridDistance: 50
}),
tooltip: am5.Tooltip.new(root, {})
}));
var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
renderer: am5xy.AxisRendererY.new(root, {})
}));
// Add series
// https://www.amcharts.com/docs/v5/charts/xy-chart/series/
var series = chart.series.push(am5xy.ColumnSeries.new(root, {
name: "Series 1",
xAxis: xAxis,
yAxis: yAxis,
valueYField: "value",
valueXField: "date",
tooltip: am5.Tooltip.new(root, {
pointerOrientation: "horizontal",
labelText: "{valueY}"
})
}));
series.data.setAll(data);
// Add cursor
// https://www.amcharts.com/docs/v5/charts/xy-chart/cursor/
var cursor = chart.set("cursor", am5xy.XYCursor.new(root, {
xAxis: xAxis
}));
cursor.lineY.set("visible", false);
// Update data every second
setInterval(function () {
addData();
}, 100)
function addData() {
var lastDataItem = series.dataItems[series.dataItems.length - 1];
var lastValue = lastDataItem.get("valueY");
var newValue = value + ((Math.random() < 0.5 ? 1 : -1) * Math.random() * 5);
var lastDate = new Date(lastDataItem.get("valueX"));
var time = am5.time.add(new Date(lastDate), "second", 1).getTime();
series.data.removeIndex(0);
series.data.push({
date: time,
value: newValue
})
var newDataItem = series.dataItems[series.dataItems.length - 1];
newDataItem.animate({
key: "valueYWorking",
to: newValue,
from: lastValue,
duration: 600,
easing: easing
});
var animation = newDataItem.animate({
key: "locationX",
to: 0.5,
from: -0.5,
duration: 600
});
if (animation) {
var tooltip = xAxis.get("tooltip");
if (tooltip && !tooltip.isHidden()) {
animation.events.on("stopped", function () {
xAxis.updateTooltip();
})
}
}
}
setTimeout(function(){
xAxis.zoom(0.5, 1)
}, 1500)
After some time of running it, all Chromium browsers crash. Even though Dev tools does not show any memory leak - number of listeners, nodes and heap size remains the same (the heap might increase a bit initially but then stabilizes). But the task manager shows memory growing. Important thing - the browser window must be focused. The strange thing is that if I zoom-out the chart using scrollbar or resize window or close and open the tab, the memory could drop to a normal level. This thing happens both with dev tools opened and closed.
This does not happen on Firefox, so I believe it's some browser issue. Appreciate for any insights.
So we found out that this is indeed a Chromium issue, calling setTransform on a context (if nothing else is done) results to leak (which is not visible when profiling) and a crash. We reported it as a bug and hopefully it will be fixed. Meanwhile we are working on a workaround to avoid this situation.
var canvas = document.createElement('canvas');
document.body.appendChild(canvas);
var context = canvas.getContext('2d');
function loop() {
requestAnimationFrame(() => {
loop();
for (var j = 0; j < 10000; ++j) {
context.setTransform(0.5, 1, 1, 0.5, 1, 1);
}
});
}
loop();
I have installed the crosshair plugin and am using chartJS 3.0 to take advantage of the candlestick charts but the crosshair does not appear. are these things compatible together? my data appear no problem but the crosshair never appears. how do i use these two things together? are there any working examples?
the tags i am using
<script src="https://cdn.jsdelivr.net/npm/luxon#1.24.1"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.0.0-beta.9/dist/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon#0.2.1"></script>
<script src="https://dd7tel2830j4w.cloudfront.net/f1614793727236x392906938665549250/chartjs-chart-financial.js"></script>
<script scr="https://cdn.jsdelivr.net/npm/chartjs-plugin-crosshair"></script>
and the chart code which also works
var divID = "chartContainer" + properties.chartid
var chartID = "myChart" + properties.chartid
instance.canvas.append('<div id="' + divID + '"></div>')
document.getElementById(divID).innerHTML = ' ';
document.getElementById(divID).innerHTML = '<canvas id=' + chartID + ' width="' + properties.bubble.width() + '" height="' + properties.bubble.height() + '"></canvas>';
var ctx = document.getElementById(chartID).getContext('2d');
var chart = new Chart(ctx, {
type: 'candlestick',
data: {
datasets: [{
label: 'CHRT - Chart.js Corporation',
data: getData()
}]
},
options: {
scales: {
y: {
min: 0,
max: 500
}
},
tooltips: {
mode: "interpolate",
intersect: false
},
plugins: {
crosshair: {
line: {
color: '#F66', // crosshair line color
width: 3, // crosshair line width
dashPattern: [5, 5] // crosshair line dash pattern
},
sync: {
enabled: true, // enable trace line syncing with other charts
group: 1, // chart group
suppressTooltips: false // suppress tooltips when showing a synced tracer
},
zoom: {
enabled: true, // enable zooming
zoomboxBackgroundColor: 'rgba(66,133,244,0.2)', // background color of zoom box
zoomboxBorderColor: '#48F', // border color of zoom box
zoomButtonText: 'Reset Zoom', // reset zoom button text
zoomButtonClass: 'reset-zoom', // reset zoom button class
},
callbacks: {
beforeZoom: function(start, end) { // called before zoom, return false to prevent zoom
return true;
},
afterZoom: function(start, end) { // called after zoom
}
}
}
}
}
});
function getData() {
var dates = properties.time.get(0, properties.time.length())
var opens = properties.open.get(0, properties.open.length())
var highs = properties.high.get(0, properties.high.length())
var lows = properties.low.get(0, properties.low.length())
var closes = properties.close.get(0, properties.close.length())
let data = []
for (i = 0; i < dates.length; i++) {
data.push({
t: dates[i].valueOf(),
o: opens[i],
h: highs[i],
l: lows[i],
c: closes[i]
})
}
console.log(data)
return data
}
chart.update()
The crosair plugin is not yet compatible with the new beta of version 3. They have a pr to be up to date with beta 11 but after that there have been breaking changes again. So you will have to update the plugin yourself or wait till it has been updated to support v3
This is the first time I'm using ChartJS v2.
I creating a simple line chart with several datasets.
I have 3 problems:
1 - It has the correct data shown, but I have a problem with the legends, as they appear left aligned with the color box out of the canvas, and one per line like in the image bellow (https://i.stack.imgur.com/c9qBe.png).
I want the legends like float: left; in css.
2 - Other problem is the tooltips, they're very big.. like shown in the image bellow. (https://i.stack.imgur.com/txXCF.png)
I tried to find the options to achieve this but it hard for me to make it work.
3 - I want the interval in the y-axis to be 1 not 0.1.
Bellow is the JS code used to create the chart:
var scripts = $(".sending-data");
var datasets = [];
var days = [];
var counter = 0;
scripts.each(function (index, script){
var json = JSON.parse(script.innerHTML);
var data = [];
for (var i = 0; i<json.DATA.length; i++) {
data.push(json.DATA[i][2]);
if (counter === 0)
days.push(json.DATA[i][1].substr(8, 2));
}
var r = Math.floor((Math.random() * 255) + 1);
var g = Math.floor((Math.random() * 255) + 1);
var b = Math.floor((Math.random() * 255) + 1);
var rgbStr = r+ ", " +g + ", " + b;
console.log(rgbStr);
datasets.push({
label: "## " + $(script).attr("data-send-id"),
backgroundColor: 'rgba('+rgbStr+', 0.2)',
borderColor: 'rgba('+rgbStr+', 1)',
borderWidth: 2,
lineTension: 0.1,
data: data,
fill: false
});
counter++;
});
var config ={
type: 'line',
data: {
labels: days,
datasets: datasets
},
options: {
title: {
display: true,
text: 'Custom Chart Title'
},
responsive : true,
legend: {
fullWidth: false,
boxWidth: 50,
padding: 40,
position: "top",
display: true
},
scales: {
yAxes: [{
ticks: {
beginAtZero:true,
stepSize: 1
}
}]
}
}
};
var ctx = document.querySelector("##canvas-chart").getContext("2d");
console.log(document.querySelector("##canvas-chart"));
var myLine = new Chart(ctx, config);
Dont mind the '##' selector, I'm using CFusion.
Any help from you guys?
--DISCLAIMER--
I managed to set the stepSize: 1 so the interval is 1. But still have the problem (1) and (2)
Thanks in advance!
Happy Programming!
So the problem is this - I'm dumb..
hahaha
The dataset labels had a lot of whitespace... so I just replaced all " " by "" and it showed correctly..
Thanks to all of you.
Cheers and happy programming!
I have been playing around with Cesium and have been able to plot points on a globe. In the sample code the pdata array holds the latitude, longitude data.
Sample Code:
for ( var i = 0; i < pdata.length; i++ ) {
viewer.entities.add({
position : Cesium.Cartesian3.fromDegrees(pdata[i].longitude, pdata[i].latitude),
point : {
pixelSize : 5,
color : CESIUM.Color.RED,
outlineWidth: 0
}
});
}
Am trying to animate the points (like show pulsating points). How can I add animations to the plotted points? Is there any way I can add a CSS keyframe animation on the plotted points to produce a pulse effect on each point rendered?
Cesium is rendered to a WebGL canvas, so CSS (and CSS animations) are not available within the render. However, Cesium includes many forms of animations, interpolation, and the like.
One option is to use a SampledProperty in place of the constant value 5 for your pixelSize.
Here's an example of such a replacement, click Run code snippet at the bottom of this:
var viewer = new Cesium.Viewer('cesiumContainer', {
navigationInstructionsInitiallyVisible: false, animation: false, timeline: false,
// These next 6 lines are just to avoid Stack Snippet error messages.
imageryProvider : Cesium.createTileMapServiceImageryProvider({
url : Cesium.buildModuleUrl('Assets/Textures/NaturalEarthII')
}),
baseLayerPicker : false,
geocoder : false,
infoBox : false,
shouldAnimate : true
});
var start = Cesium.JulianDate.fromIso8601('2018-01-01T00:00:00.00Z');
var mid = Cesium.JulianDate.addSeconds(start, 0.5, new Cesium.JulianDate());
var stop = Cesium.JulianDate.addSeconds(start, 1, new Cesium.JulianDate());
var clock = viewer.clock;
clock.startTime = start;
clock.currentTime = start;
clock.stopTime = stop;
clock.clockRange = Cesium.ClockRange.LOOP_STOP;
var pulseProperty = new Cesium.SampledProperty(Number);
pulseProperty.setInterpolationOptions({
interpolationDegree : 3,
interpolationAlgorithm : Cesium.HermitePolynomialApproximation
});
pulseProperty.addSample(start, 7.0);
pulseProperty.addSample(mid, 15.0);
pulseProperty.addSample(stop, 7.0);
viewer.entities.add({
position : Cesium.Cartesian3.fromDegrees(-95, 40),
point : {
pixelSize : pulseProperty,
color : Cesium.Color.ORANGERED
}
});
viewer.entities.add({
position : Cesium.Cartesian3.fromDegrees(-85, 40),
point : {
pixelSize : pulseProperty,
color : Cesium.Color.LIME
}
});
viewer.entities.add({
position : Cesium.Cartesian3.fromDegrees(-75, 40),
point : {
pixelSize : pulseProperty,
color : Cesium.Color.STEELBLUE
}
});
html, body, #cesiumContainer {
width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden;
font-family: sans-serif;
}
<link href="http://cesiumjs.org/releases/1.31/Build/Cesium/Widgets/widgets.css"
rel="stylesheet"/>
<script src="http://cesiumjs.org/releases/1.31/Build/Cesium/Cesium.js">
</script>
<div id="cesiumContainer"></div>
I'm stuck trying to get a very simple task to work on my app. Essentially, I want to be able to add view to a ScrollView when users click a button. Let's call this first view added a "Card". Inside this card, I also have another scrollview which is supposed to then dynamically receive and display "categories" views.
For the most part everything is working fine: when the "Add" button at the top is clicked, the "card" is created and I am able to see all of the information, HOWEVER, the problem is that each time I "Add" a card, I end up not only adding "categories" views to the current created card by a factor of 2, but also the same happens to the previously added cards. Like the following:
I hope this makes sense.
Here's my code (my button event listener):
addViewButton.addEventListener('click', function(e) {
var url = "https://my.apilink.com";
var xhr = Titanium.Network.createHTTPClient();
xhr.open('GET', url);
xhr.onload = function() {
var response = JSON.parse(this.responseText);
var t = response.data.categories;
var bons = [];
for (var item in t) {
bons.push(t[item]);
}
Ti.API.info("Data received" + bons);
var resp = {
response : bons
};
createCard(resp);
};
xhr.send();
}
And here's where it all happens (creating the views (cards)):
var catScrollView = Titanium.UI.createScrollView({
top : 130,
left : 0,
right : 0,
contentWidth : '100%',
showHorizontalScrollIndicator : false,
showVerticalScrollIndicator : true,
});
var scrollView = Ti.UI.createScrollView({
top : 130,
left : 0,
right : 0,
backgroundColor : 'white',
contentWidth : '100%',
showHorizontalScrollIndicator : false,
showVerticalScrollIndicator : true,
});
var topPosition = 20;
var leftPosition = 20;
var topPositionCat = 30;
var i = 0;
function createCard(_args) {
var response = _args.response;
Ti.API.info("Response" + response);
var colorArr = ["red", "orange", "blue", "green", "pink", "yellow"];
var fakeArray = ["card 0", "card 1", "card 2", "card 3"];
var ranIndex = getRandom(colorArr.length);
i++;
for (var d = 0; d < response.length; d++) {
var panelImage = Ti.UI.createView({
backgroundColor : colorArr[ranIndex],
top : topPosition + (i * 60),
borderRadius : 5,
borderColor : 'white',
borderWidth : 2,
id : i,
bit : false,
active : false,
height : 350,
width : 290,
});
//add a few attributes to the card
var cardTitle = Ti.UI.createLabel({
text : "I am card # " + i,
top : 10,
left : 0,
color : 'black'
});
panelImage.add(cardTitle);
//Add the EventListener for the view.
panelImage.addEventListener('singletap', cardButtonHandler);
//Add scrollview and a card here
var leftPosition = 20;
if (d % 2 == 0) {
leftPosition = 20;
} else {
leftPosition = 180;
}
var panelImageCat = Ti.UI.createView({
backgroundImage : '/images/row_bg.png',
top : topPositionCat,
left : leftPosition,
height : 100,
width : 100,
});
var catImageButton = Ti.UI.createImageView({
image : response[d].icon,
name : response[d].name,
id : response[d].id,
icon : response[d].icon,
width : 90,
height : 90,
top : 4
});
panelImageCat.add(catImageButton);
var catName = Ti.UI.createLabel({
text : response[d].name,
textAlign : 'center',
color : 'black',
top : 3,
font : {
fontWeight : 'bold'
}
});
panelImageCat.add(catName);
if (leftPosition == 180) {
topPositionCat += panelImageCat.height + 10;
}
// add the view in scroll view
catScrollView.add(panelImageCat);
panelImage.add(catScrollView);
// Add the EventListener for the view.
catImageButton.addEventListener('click', function(e) {
alert(e.source.name);
});
}// END FOR LOOP
catScrollView.contentHeight = topPositionCat + 20;
// add the view in scroll view
scrollView.add(panelImage);
}
Of course there's more code for when users tap on each "card" etc. But that's irrelevant.
This is probably very simple to solve. I suspect it has to do with how I am setting up the loops to create each card and its corresponded categories views etc.
Any help, guidance is highly appreciated.
Thank you!
I guess that the main problem of your code is the way you are adding cards to the row. You shouldn't add a card for each category, but only create a card, add each category to that card, and then, add the card to the parent scrollView.
Nevertheless, in order to improve the readability of your code (and thus, your capability to maintain it), you should consider doing two things :
Move all the code that concern styling inside a separated file.
Create "builders" to instantiate views components so that, your main code only contains relevant information.
Here is an example on TiFiddle, and right below, explanation about it.
Move styling in a separated file
Just make a really easy-to-use commonJS-like module. Titanium supports them, do not be shy.
styles.js
/* ------ Top Level Components ------ */
exports.mainWindow = {
backgroundColor: "#ffffff",
layout: "vertical"
};
exports.topLevelScrollView = {
width: Ti.UI.FILL,
height: Ti.UI.FILL,
contentWidth : '100%',
showHorizontalScrollIndicator : false,
showVerticalScrollIndicator : true
};
exports.addButton = {
width: Ti.UI.FILL,
backgroundColor: "#999999",
color: "#ffffff",
font: { fontSize: 14 },
height: 50
};
/* ------ Card ----*/
exports.cardContainer = {
borderRadius : 5,
borderColor : '#ffffff',
borderWidth : 2,
top: 0,
height : 350,
width : Ti.UI.FILL,
};
exports.cardTitle = {
top : 10,
left : 10,
height: Ti.UI.SIZE,
width: Ti.UI.FILL,
color : '#141414'
};
exports.cardScrollView = {
layout: "horizontal",
contentWidth : '100%',
showHorizontalScrollIndicator : false,
showVerticalScrollIndicator : true,
top: 50,
height: Ti.UI.SIZE,
width: Ti.UI.SIZE
};
/* ------ Category ------*/
exports.categoryContainer = {
backgroundColor: "#cccccc",
opacity: "0.8",
left: 30,
right: 30,
top: 10,
bottom: 10,
height : 100,
width : 100,
};
exports.categoryImage = {
width : 90,
height : 90,
top : 4
};
exports.categoryTitle = {
textAlign : 'center',
color : 'black',
top : 3,
font : {
fontWeight : 'bold'
}
};
/* TIPS: Always use fancy colors for your tests <3 */
exports.colors = [
"#c0392b",
"#e67e22",
"#3498db",
"#2ecc71",
"#9b59b6",
"#f1c40f"
];
Create also some utils
The way you are creating card and categories has nothing to go alongside the other function. So, let's create another module.
ui_utils.js
exports.pickColor = function (colors) {
var randomIndex = Math.floor(Math.random() * colors.length);
return colors[randomIndex];
};
/* Create and return a cardContainer that may hold several categoryContainers */
exports.createCardView = function (id, title, color, styles, listener) {
var cardContainer = Ti.UI.createView(styles.cardContainer),
cardTitle = Ti.UI.createLabel(styles.cardTitle),
cardScrollView = Ti.UI.createScrollView(styles.cardScrollView);
cardContainer.id = id;
cardContainer.bit = false;
cardContainer.active = false;
cardContainer.backgroundColor = color;
cardContainer.cardScrollView = cardScrollView;
cardTitle.text = title;
cardContainer.addEventListener(listener.eventName, listener.listener);
cardContainer.add(cardTitle);
cardContainer.add(cardScrollView);
return cardContainer;
};
/* Create and return a categoryContainer */
exports.createCategoryView = function (category, styles, listener) {
var categoryContainer = Ti.UI.createView(styles.categoryContainer),
categoryTitle = Ti.UI.createLabel(styles.categoryTitle),
categoryImage = Ti.UI.createImageView(styles.categoryImage);
categoryTitle.text = category.name;
categoryImage.id = category.id;
categoryImage.name = category.name;
categoryImage.image = category.icon;
categoryImage.addEventListener(listener.eventName, listener.listener);
categoryContainer.add(categoryTitle);
categoryContainer.add(categoryImage);
return categoryContainer;
};
Rewrite your main file
And finally, the main function with just the minimal amount of code.
app.js
/* Start by requiring defined modules, and creating different views */
var styles = require('styles'),
uiUtils = require('ui_utils'),
mainWindow = Ti.UI.createWindow(styles.mainWindow),
topLevelScrollView = Ti.UI.createScrollView(styles.topLevelScrollView),
addButton = Ti.UI.createButton(styles.addButton);
/* The famous one */
function createCard(_args) {
var response = _args.response;
Ti.API.info("Response :" + response);
/* Create the new card */
var id = topLevelScrollView.children.length, /* Ugly .. find another way */
title = "I am card #" + id,
color = uiUtils.pickColor(styles.colors),
listener = {
eventName: "singleTap",
listener: function () { } /* Just supply a listener */
},
cardContainer = uiUtils.createCardView(id, title, color, styles, listener);
cardContainer.top = 50 * id;
/* Iterate over each category that we have in response */
for (var i = 0, category; category = response[i]; i++) {
/* Create the category view */
var listener = {
eventName: "click",
listener: function(e) { alert(e.source.name); }
},
categoryContainer = uiUtils.createCategoryView(category, styles, listener);
/* Add it to the card scrollView */
cardContainer.cardScrollView.add(categoryContainer);
}
/* Dont forget to add the card to the topLevelScrollView */
topLevelScrollView.add(cardContainer);
}
/* Initialize the different views */
addButton.title = "ADD";
mainWindow.add(addButton);
mainWindow.add(topLevelScrollView);
mainWindow.open();
Enjoy!