titanium: Adding things to a scrollview - titanium

So i have this code:
var answerView = Ti.UI.createScrollView({ //var added
top: Ti.Platform.displayCaps.platformHeight*0.55,
left:Ti.Platform.displayCaps.platformWidth*0.1,
width: Ti.Platform.displayCaps.platformWidth*0.8,
backgroundImage: '/images/labelBackground.png',
borderRadius: 8,
height: Ti.Platform.displayCaps.platformHeight*0.5,
contentHeight:'auto',
showHorizontalScrollIndicator:true,
scrollType:'vertical',
});
for (var j = 0; j < question.answers.length; j++){
var row = createRow(question.answers[j]);
answerView.add(row);
}
and this function:
function createRow(answer) {
var row = Ti.UI.createView({
width:'100%',
height: 'auto',
});
var answerButton = Ti.UI.createButton({
top: '1%',
left: '1%',
title: answer.answer,
value: answer.order,
width:'98%',
font : {fontSize:'12sp'},
});
row.add(answerButton);
return row;
}
The problem is, the darn thing overlays all the buttons into one... that is, it isn't "pushing down" the rows. From the titanium tutorial here:
http://docs.appcelerator.com/titanium/2.1/index.html#!/api/Titanium.UI.ScrollView
I would have thought this would work, but it doesn't. I know i can do some magic with the numbers and send each row the position it should have, but I thought maybe titanium would be clever enough to do that? Am i missing something?

Oh jesus.
Titanium is moronic in this instance - the problem was I had
height: 'auto' in the definition of each row - that is:
function createRow(answer) {
var row = Ti.UI.createView({
width:'100%',
height: 'auto',
});
...
And funnily enough, that makes each row REALLY BIG, probably as big as the entire space alloted for the row. I don't know, i never tried to scroll through it. So just change the height value for the row to something sane - i always base mine off the display height.
Now I have
function createRow(answer) {
var row = Ti.UI.createView({
width:'100%',
height: Ti.Platform.displayCaps.platformHeight*0.1,
});
...
and all is well.

Related

dc.js composite chart toggle legend loses its translucence upon filtering

I have used this solution to get a toggle legend for a composite line chart and it works perfectly fine.
However, after i added a range chart to this composite chart, the deselected legend loses its translucence and becomes normal.
How can i keep the deselected legend object in faded state while filtering?
Here are screenshots for reference:
Before filter:
After filter:
This is the code I'm using for charts:
multiLineChart
.width(1000)
.height(300)
.transitionDuration(1000)
.margins({top: 30, right: 50, bottom: 40, left: 40})
.x(d3.time.scale().domain([startDate,endDate]))
.yAxisLabel("Data (Scaled)")
.xAxisLabel("Date And Time")
.rangeChart(timeSlider)
.legend(dc.legend().x(800).y(20).itemHeight(13).gap(5))
.renderHorizontalGridLines(true)
//.dimension(DateDim)
.compose([
dc.lineChart(multiLineChart)
.dimension(DateDim)
.colors('red')
.group(Line1Grp, 'Line1'),
dc.lineChart(multiLineChart)
.dimension(DateDim)
.colors('blue')
.group(Line2Grp, 'Line2')
])
.brushOn(false)
.on('pretransition.hideshow', function(chart) {
chart.selectAll('g.dc-legend .dc-legend-item')
.on('click.hideshow', function(d, i) {
var subchart = chart.select('g.sub._' + i);
var visible = subchart.style('visibility') !== 'hidden';
subchart.style('visibility', function() {
return visible ? 'hidden' : 'visible';
});
d3.select(this).style('opacity', visible ? 0.2 : 1);
});
});
//.xAxis().tickFormat(d3.time.format("%b %d %H:%M"));
timeSlider
.width(1000)
.height(50)
.margins({top: 0, right: 50, bottom: 20, left: 40})
.dimension(DateDim)
.group(Line1Grp)
.x(d3.time.scale().domain([startDate, endDate]))
.on("filtered", function (chart) {
dc.events.trigger(function () {
multiLineChart.focus(chart.filter());
dc.redrawAll(chart.chartGroup());
});
})
.xAxis().tickFormat(d3.time.format("%b %d"));
Here is a fiddle for the same.
Any help is appreciated.
Thanks for pointing this out - there was a bad practice in my earlier answer, and I went back and corrected it.
It's always better style, and more robust, to separate event handling and drawing, and always draw everything based on the data, not some event that is in flight.
If you follow these practices, then the code looks more like this:
function drawLegendToggles(chart) {
chart.selectAll('g.dc-legend .dc-legend-item')
.style('opacity', function(d, i) {
var subchart = chart.select('g.sub._' + i);
var visible = subchart.style('visibility') !== 'hidden';
return visible ? 1 : 0.2;
});
}
function legendToggle(chart) {
chart.selectAll('g.dc-legend .dc-legend-item')
.on('click.hideshow', function(d, i) {
var subchart = chart.select('g.sub._' + i);
var visible = subchart.style('visibility') !== 'hidden';
subchart.style('visibility', function() {
return visible ? 'hidden' : 'visible';
});
drawLegendToggles(chart);
})
drawLegendToggles(chart);
}
multiLineChart
.on('pretransition.hideshow', legendToggle);
Now, whenever we redraw the composite chart and its legend - no matter what the cause - all of the items in the legend will be updated based on whether the corresponding child chart has been hidden.
And the event handler is only concerned with hiding and showing charts, not drawing.
Fork of your fiddle.

Greensock Animation Platform - is it possible to reverse nested timelines?

Is it possible to reverse a master timeline within GSAP? I know you can reverse a timeline that is not nested.
Here's the code:
// hide copy content divs
const hideCopyContentDivsTl = new TimelineMax()
hideCopyContentDivsTl.to(copyContentDivs, 1, {
height: 0,
width: 0,
autoAlpha: 0
})
// shrink copy wrapper div
const shrinkCopyWrapperTL = new TimelineMax()
shrinkCopyWrapperTL.to(copyWrapperDiv, 1, {
width: '2%',
height: '4%'
})
// fade remove bg and change to white
const fadeLargeBgImgTl = new TimelineMax()
fadeLargeBgImgTl.to(largeImage, 1, {
backgroundColor: "#fff"
})
// the master timeline to manage the parts
const masterTimeline = new TimelineMax({paused: true})
masterTimeline.add(hideCopyContentDivsTl)
.add(shrinkCopyWrapperTL)
.add(fadeLargeBgImgTl)
// assume that there is a mechanism to change the state of playVideo between true and false
if (this.state.playVideo === false) {
console.log("should play: ", masterTimeline)
masterTimeline.play()
} else {
console.log("should reverse: ", masterTimeline)
masterTimeline.reverse()
}
I can get it to play forwards, just not in reverse. Do I need to tell the browser where to start in the timeline so that it can play in reverse?
The problem is with my code and not with GSAP. I have new timelines created on every click. How will it reverse something that it doesn't have a previous reference to? The solution would be to create the timelines outside of the click event and then based on the state, play forward or reverse the animation.

Titanium adding a label to a view

Okay, guys -- I have to admit that my frustration level is growing as Titanium development continues to kick my backside. Every change I make, however innocuous it may appear, seems to break something else in a completely unexpected way.
Today, I'm simply trying to add a label to a view, but it's not displaying.
// UI Factory Include
var Inova = {};
Ti.include( '_ui.js' );
var win = Ti.UI.currentWindow;
win.layout = 'vertical';
// Header
win.add( Inova.ui.createHeaderView() );
// body
var body = Ti.UI.createView({
backgroundColor:'#00f', // Should see no blue
backgroundImage: '/images/body.png',
height: 350,
layout: 'vertical',
});
var label = Ti.UI.createLabel({
color: '#000',
text: 'Show me the label...please?',
textAlign: 'center',
});
body.add( label );
win.add( body );
I know I have to be missing something incredibly stupid and basic, but I think I've lost all ability to see the obvious. Help?
I think you need to explicitly set the width/height in the label. You can set it to width: 'auto', height: 'auto' but it has to be set.
(Oddly enough this is not true in Andriod, from my experiences).
Whenever I get flummoxed by the API, I return to the basics. Try this:
Create a new project called myTest. In the apps.js file add the following code to the bottom of the file above the last line
var win3 = Titanium.UI.createWindow({
title:'Tab 3',
backgroundColor:'#fff'
});
var tab3 = Titanium.UI.createTab({
icon:'KS_nav_ui.png',
title:'Tab 3',
window:win3
});
var label3 = Titanium.UI.createLabel({
color:'#999',
text:'I am Window 3',
font:{fontSize:20,fontFamily:'Helvetica Neue'},
textAlign:'center',
width:'auto'
});
var txtLabel = Ti.UI.createLabel({
color: '#000',
text: 'Show me the label...please?',
textAlign: 'center',
left: 100,
top: 50
});
win3.add( txtLabel );
win3.add(label3);
Your label, txtLabel, will now appear below label3 on tab3. I tried using the code you provided, but failed to get it to work as well. So, start with a basic page that shows the label, then add the other components until you get the expected results.
Hope that helps.

Dojo - How to to position object relative to another object

Just like the title says. Because buildin widgets do not really fit, what I want to do, I need to make my own tooltipdialog implementation:
To start simple:
dojo.query(".small-avatar").connect("onmouseenter", function () {
var pos = dojo.position(this, true);
dojo.query("#user-tooltip").style({ left: pos.x, top: pos.y, visibility:"visible" });
});
I've come with this. Well I guess the problem is with pos. I've tried to digg with documentation, but honestly there is no word, on how access x and y position so I assumed it's with ".".
UPDATE:
After more checking, I figured out that problem lie in position it self, or style.
For some reason Dojo do not add coordinates to targeted node "#user-tooltip". It just change visibility.
You have the pos.x and pos.y correctly referenced since dojo.position() returns an object literal. From the Dojo docs, The return object looks like:
{ w: 300: h: 150, x: 700, y: 900, }
You may need to set position: absolute or position: relative on #user-tooltip.
I finally got it working:
dojo.query(".small-avatar").connect("onmouseenter", function (e) {
var pos = dojo.position(this, true);
dojo.style(dojo.byId('user-tooltip'), { visibility: "visible", "left": pos.x+pos.w+'px', "top": pos.y+pos.h+'px' });
});

jquery animation help

I have two circles, one is small (thumb) another one is big (info), and when the user hover over the small (thumb), then the small icon need to resize in to big one. I also need to show the new information in the big. I think I have to do this by width and height animation, because small is 100px X 100px, and big is 200 X 200 size.
Please advice on the best way to do this. I would like to avoid using plug-ins.
using jquery 1.4.2 or up, you can achieve this by using:
$(".smallCircle").hover(
function () {
$(this).animate({
width: '200px',
height: '200px'
}, 200, function() {
// Animation complete.
//do whatever
});
},
function () {
$(this).animate({
width: '100px',
height: '100px'
}, 200, function() {
// Animation complete.
//do whatever
});
});
put the class "smallCircle" in the small circle.
P.S. in each state of the hover, you can control what happens after the animation is done (the place where I put "//do whatever"), that's the place where you could insert the content of the big cicrle.