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' });
});
Related
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.
I'm really into Google's Polymer and I love GSAP - and so far I've been using the two in conjunction without a hitch. Unfortunately I have now hit a problem - how do I use GSAP (TweenMax to be specific) with custom css variables?
For example:
To change someCssProperty of someElement I would
TweenMax.to(someElement, 1, someCssProperty: "value");
but the someCssProperty becomes an issue when I'm trying to animate a css variable, which take on the form --some-custom-css-variable .
I have tried to use
TweenMax.to(someElement, 1, --some-custom-css-Property: "value");
(obviously gives me errors) and I also tried to use TweenMax.to(someElement, 1, "--some-custom-css-Property": "value");
(quotes around the some-custom-Css-property) - however this results in
no change/animation and an invalid tween value error message on the developer console.
So the question is: how would I go about animating custom css variables with TweenMax (GSAP)?
Thanks for any help :)
EDIT:
I have tried using classes through
TweenMax.to("SomeElement", 5, {className:"class2"});
But this changed the element style as if I had declared it in css with a
SomeElement:hover {}
style (as in it does not animate, just changes immediately)
For now, you're going to have to manually update the variable using a generic object.
var docElement = document.documentElement;
var tl = new TimelineMax({ repeat: -1, yoyo: true, onUpdate: updateRoot });
var cs = getComputedStyle(docElement, null);
var blur = {
value: cs.getPropertyValue("--blur")
};
tl.to(blur, 2, { value: "25px" });
function updateRoot() {
docElement.style.setProperty("--blur", blur.value);
}
:root {
--blur: 0px;
}
img {
-webkit-filter: blur(var(--blur));
filter: blur(var(--blur));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.4/TweenMax.min.js"></script>
<img src="http://lorempixel.com/400/400/" />
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.
I'm embedding Youtube's experimental HTML5 iframe capabilities in a website through use of the javascript API:
YouTube Player API Reference for <ifram> Embeds
I'm aware of the z-index issues this brings about, and the fix that involves adding wmode=opaque (or wmode=transparent) to the iframe url:
Fixed. My Youtube iframe z-index is ignored and is above a fixed div
When just using the javascript API, how do you set wmode to opaque:
function onYouTubePlayerAPIReady() {
var player;
player = new YT.Player('player', {
width: 1280,
height: 720,
videoId: 'u1zgFlCw8Aw',
// if I try adding wmode: opaque here, it breaks
playerVars: {
controls: 0,
showinfo: 0 ,
modestbranding: 1
// if I try adding wmode: opaque as a playerVar here, it breaks
},
events: {
'onReady': onPlayerReady,
'onPlaybackQualityChange': onPlayerPlaybackQualityChange
}
});
}
Any ideas?
Hmmmm...
Well, it appears I was hasty in posting the question. It appears that the correct form for setting wmode within the API is:
function onYouTubePlayerAPIReady() {
var player;
player = new YT.Player('player', {
width: 1280,
height: 720,
videoId: 'u1zgFlCw8Aw',
playerVars: {
controls: 0,
showinfo: 0 ,
modestbranding: 1,
wmode: "opaque"
},
events: {
'onReady': onPlayerReady,
'onPlaybackQualityChange': onPlayerPlaybackQualityChange
}
});
}
Hopefully this helps someone else.
As far as I can tell it is the default to be opaque. I tested changing wmode to transparent, opaque and removed it. When it wasn't specified it was automatically set to opaque.
I'm not sure if this always was the case, but it definitely is now.
Also remember this only applies when using the Flash player. You can disable the HTML 5 player to test this which is the default with the 'Disable Youtube™ HTML5 Player' plugin. Then just inspect element and drill down till you find the EMBED tag.
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.