d3js how to scroll or tween properties - scroll

I have a div, #scrollable, with a scrollbar and I want to scroll to the end.
I can do it by setting the div's "scrollTop" property to the value of the div's "scrollHeight" property thus:
var scrollable = d3.select("#scrollable");
scrollable.property("scrollTop", scrollable.property("scrollHeight"));
but I can't figure out how, if at all, I can tween it.
var scrollheight = scrollable.property("scrollHeight");
d3.select("#scrollable").transition().property("scrollTop", scrollheight);
doesn't work.
Thanks for any ideas.
Regards

You can use a custom d3 tween to transition arbitrary properties like scrollTop.
mbostock's Smooth Scrolling example demonstrates using a custom tween to scroll the entire document.
And here is the example adapted to your context (also viewable interactively on bl.ocks.org):
var scrollable = d3.select("#scrollable");
d3.select("#down").on('click', function() {
var scrollheight = scrollable.property("scrollHeight");
d3.select("#scrollable").transition().duration(3000)
.tween("uniquetweenname", scrollTopTween(scrollheight));
});
function scrollTopTween(scrollTop) {
return function() {
var i = d3.interpolateNumber(this.scrollTop, scrollTop);
return function(t) { this.scrollTop = i(t); };
};
}

Related

How to change geometry color on click in three.js

I am new to three.js. I found an example on the official website. I want to change the color of geometry by clicking the button. How can I do this? I tried to use the mouse click event to do it, but it was useless.
function init(){
......
......
......
$("red").onclick(function (e) {
rollOverMesh.material.color=0xff3333;
});
}
You just have to set color like this :
rollOverMesh.material.color = new THREE.Color(0xff3333);
Assuming rollOverMesh is a Mesh. Please try
var onClick = function() {
rollOverMesh.material.color = new THREE.Color(0xffffff * Math.random());
rollOverMesh.material.needsUpdate = true;
};
$('red').click(onClick);
If you want to change material in live scene, you must set material again.
JSFiddle: https://jsfiddle.net/bkr1gc4e/

Disable resize of brush on range chart from focus charts (dc.js, d3.js) - Solved

Please note - there is a solution for part of this problem by Gordon Woodhull in Disable brush on range chart before selecting a scale from the dropdown/on page load(dc.js,d3.js)
In addition,there is a partial solution at the end this question.
Furthermore there are two fiddles:
1) https://jsfiddle.net/dani2011/4dsjjdan/1/
2) https://jsfiddle.net/dani2011/uzg48yk7/1/ (with partial solution)
Need to disable resize of the brush on range chart (timeSlider) by dragging the line within the focus charts (bitChart,bitChart2). As Gordon Woodhull suggested (Disable brush resize (DC.js, D3.js) try to enable only pan without zoom.
Current behavior:
1)
Dragging the line on bitChart2 (focus chart) pans the brush until the borders of the timeChart. Once reaching the borders,the brush shrinks. The other focus chart (bitChart) resizes the brush of the range chart during drag of its line.
2)
When selecting a span for the brush from the dropdown only the .on('zoomed', function (chart, filter) { of bitChart2 is loaded and not the .on("zoomed"... of bitChart.
Print screens from the console:
a) Selecting scale from the dropdown
b) Dragging line on bitChart:
c) Dragging line on bitChart2:
3)
For both bitChart and bitChart2 the value of scale is 1 and the position
is 0,0:
.on('zoomed', function (chart, filter) {
//var zoom = d3.behavior.zoom()
// .translate([0, 0])
//.scale(1).scaleExtent([1, 1])
var zoom = d3.behavior.zoom()
var scale = zoom.scale(); var position = zoom.translate();
js file
The following implementations did not solve the issue:
**option 1**
bitChart.on('zoomed', function (chart, filter) {
d3.behavior.zoom().on("zoom", null);//doesn't stop zoom
//event needs svg element(tried different options),doesn't work
d3.behavior.zoom().scale(1).scaleExtent([1,1]).translate([0,0]).event(chart.select('g.stack_0')))
**option 2**
//Applied on timeslider,bitChart,bitChart2 to eliminate zoom and
//maintain pan
.zoomScale([1, 1])//dc.js
//And also
.on('zoomed', function (chart, filter) {
bitChart.zoomScale([1, 1]);
//Nothing pans with
chart.focus(chart.xOriginalDomain())
**option 3**
bitChart.on('zoomed', function (chart, filter) {
var svg = d3.select("body")
.append("svg")
.call(d3.behavior.zoom().on("zoom", function () {
svg.attr("transform", "translate(" + d3.event.translate + ")" +"
scale(" + 1 + ")")
}))
//.append("g")
**option 4**
.on('zoomed', function (chart, filter) {
var chartBody = chart.select('g.stack _0');
var path = chartBody.selectAll('path.line').data([extra_data]);
path.enter().append('path').attr({
class: 'line',
});
path.attr('transform', 'translate(0,50)');
**option 5**
bitChart.on('zoomed', function (chart, filter) {
var zoom = d3.behavior.zoom()
.scaleExtent([1, 1])
chart.select('g.stack _0').call(zoom);
zoom.scale(1);
zoom.event(chart.select('g.stack _0'));
**option 6**
bitChart.on('zoomed', function (chart, filter) {
svg.call(d3.behavior.zoom().scale(1));
**option 7**
var min_zoom = 1;
var max_zoom = 1;
var svg = d3.select("body").append("svg");
var zoom = d3.behavior.zoom().scaleExtent([min_zoom, max_zoom])
bitChart.on('zoomed', function (chart, filter) {
svg.call(zoom);
My fiddle:
https://jsfiddle.net/dani2011/4dsjjdan/1/ was forked from https://jsfiddle.net/gordonwoodhull/272xrsat/9/.
When selecting span from the dropdown and clicking on the range chart,The range chart (timeSlider) acts strange on the fiddle, but behaves as expected when run it in my environment. Please note in this fiddle that bitChart2 pans the brush as expected.The resize of the brush when reaching the edge happens in my enviroment. bitChart still resizes the brush.
A partial solution:
To enable multi focus charts on a single range chart as in https://github.com/dc-js/dc.js/blob/master/web/examples/multi-focus.html written by Gordon Woodhull.Used the focus chart which worked properly in my code (bitChart2) as the main reference chart:
bitChart2.focusCharts = function (chartlist) {
if (!arguments.length) {
return this._focusCharts;
}
this._focusCharts = chartlist; // only needed to support the getter above
this.on('filtered', function (range_chart) {
if (!range_chart.filter()) {
dc.events.trigger(function () {
chartlist.forEach(function(focus_chart) {
focus_chart.x().domain(focus_chart.xOriginalDomain());
});
});
} else chartlist.forEach(function(focus_chart) {
if (!rangesEqual(range_chart.filter(), focus_chart.filter())) {
dc.events.trigger(function () {
focus_chart.focus(range_chart.filter());
});
}
});
});
return this;
};
bitChart2.focusCharts([bitChart]);
My second fiddle:
https://jsfiddle.net/dani2011/uzg48yk7/1/ was forked from https://jsfiddle.net/gordonwoodhull/272xrsat/9/.
1) When clicking on the range chart in the fiddle it does not function properly, but works in my environment.
2) The brush does not resize at the edges of the range chart in the fiddle as it does in my environment
3) It does show in the fiddle that the whole range chart is selected when panning/clicking on the lines in the focus charts and when clicking in the range chart
4) It does show in the fiddle that after selecting the brush span from the dropdown, panning the lines in the focus charts moves the brush properly on the range chart.
5) It does show in the fiddle that dragging the brush on the range chart is possible again in no span is selected from the dropdown
Still needs to solve:
1) When reaching the ends of the range chart (timeSlider) the brush resizes
solved by updating versions to be the same as the version of the external resources in the fiddle https://jsfiddle.net/gordonwoodhull/272xrsat/9/. Thank you Gordon!
2) Before selecting a scale from the dropdown:
a) When panning /translating the line of the focus charts(bitChart,bitChart2) the brush resizes
b) It is possible again to drag the brush on the range chart
Any help would be appreciated !

Skrollr: Smooth scrolling

I would like to achieve a smooth scrolling when turning a mouse wheel. Currently, when I do one turn, the scrollbar kinda jumps and the animation is jumpy.
Example of this behaviour:
http://areaaperta.com/nicescroll/
Can this scrolling be achieved using skrollr only? If so, how?
I tried following code
var s = skrollr.init({
render: function(data) {
//Debugging - Log the current scroll position.
console.log(data.curTop);
},
smoothScrolling: true,
smoothScrollingDuration: 500,
easing: {
WTF: Math.random,
inverted: function(p) {
return 1-p;
}
}
});
but it doesn't make a big difference. The animation is little bit smoother (i.e. background slides for a while and then stops), but the scrolling itself is still jumpy.
I would prefer to solve this with skrollr only as I think it is prepared for it instead of adding another plugin.
This is a quote from Petr Tichy (ihatetomatoes.net):
For smooth animations, animate cheap properties.
The best result you'll get, when you keep animating only the cheap CSS
properties.
transform: scale(1.2)
transform: translateX(100px)
transform: rotate(90deg)
opacity: 0.5
These 4 properties will let you change the size, position, rotation
and opacity of your elements.
Combination of these CSS properties will enable you to create pretty
much most of you ideas and will get you the best results.
If you come across lagging and choppy scrolling animations, give the
animated element transform: translateZ(0).
This will promote the element into composite layers and will get rid
of the lag.
Try to include this script
jQuery(function () {
var $window = jQuery(window);
var scrollTime = 0.5;
var scrollDistance = 150;
$window.on("mousewheel DOMMouseScroll", function (event) {
event.preventDefault();
var delta = event.originalEvent.wheelDelta / 120 || -event.originalEvent.detail / 3;
var scrollTop = $window.scrollTop();
var finalScroll = scrollTop - parseInt(delta * scrollDistance);
TweenMax.to($window, scrollTime, {
scrollTo: {
y: finalScroll,
autoKill: true
},
ease: Power1.easeOut,
overwrite: 5
});
});
});
I had this problem also (With Chrome on Mac)
I solved by this plug-in :
https://github.com/simov/simplr-smoothscroll
<!-- After jQuery -->
<script src="jquery.mousewheel.min.js"></script>
<script src="jquery.simplr.smoothscroll.min.js"></script>
<script type="text/javascript">$.srSmoothscroll();</script>

KineticJS change color of text onclick

I am working on KineticJS(Latest version) and i have issue regarding change text color which drawn by drawFunc() shape object.
1)Here is the code of Shpae Object.
var sampleText = new Kinetic.Shape({
x:380,
y:700,
drawFunc: function(context) {
context.beginPath();
var x = 0;
var y = 0;
var text = 'Sample Text';
context.setAttr("font", '15pt Calibri');
context.setAttr('fillStyle','black');
context.fillText(text, x, y)
context.closePath();
// KineticJS specific context method
context.fillStrokeShape(this);
},
id:"sampleText"
});
2)I want to change color of "sample text" on click event which is written using core html5 code (context object).
colorTabViews.on('click', function (e) {
sampleText.sceneFunc(function(context) {
context.beginPath();
//how can i get text which already displayed in shape object("Sample text")?
//or to change color of "sample text"
context.setAttr('fillStyle','green');
context.closePath();
context.fillStrokeShape(this);
});
verticalText.draw();
});
But issue is ,it removes whole text nothing displayed instead of just changing "sample text" color.
Please advice either get text filled by context.fillText() function or alternate way that i can change text color on particular event.
Thanks for your time and consideration in advance.
-Naitik
To programatically change fillStyle inside a Kinetic.Shape
Attach a fill property to your shape object and reference your fill property inside the Kinetic.Shape:
var sampleText = new Kinetic.Shape({
x:10,
y:15,
sceneFunc: function(context) {
context.beginPath();
var x = 0;
var y = 0;
var text = 'Sample Text';
context.setAttr("font", '15pt Calibri');
context.setAttr('fillStyle',this.myFillStyle);
context.fillText(text, x, y)
context.closePath();
// KineticJS specific context method
context.fillStrokeShape(this);
},
id:"sampleText",
fill:"blue"
});
// add a property to sampleText that's used in its sceneFunc
sampleText.myFillStyle="black";
Then you can change that fill property in your click handler:
colorTabViews.on('click', function (e) {
sampleText.myFillStyle="red";
verticalText.draw();
});

HTML 5 Canvas Mouse over event on element (show tooltip)

I am working on a visualization project. Based on my data I am plotting hundreds of small circle on canvas. I want to add a mouse over event so that whenever a mouse is the enclosing area of a circle it will show some node property from my data as a tool tip or as text on the canvas.
My current drawCircle method
function drawCircle(canvas,x,y,r)
{
canvas.strokeStyle = "#000000";
canvas.fillStyle = "#FFFF00";
canvas.lineWidth = 2;
canvas.beginPath();
canvas.arc(x,y,r,0,Math.PI*2,true);
canvas.stroke();
canvas.fill();
canvas.closePath();
}
I have looked into kinetic.js
But can't figure it out how I can call my drawCircle [repetitively] method using their library.
Any help will be highly appreciated.
If you still want to use KineticJS, you would put the Kinetic shape stuff inside your drawCircle routine. This is basically pulled out of their tutorial and stripped down:
function drawCircle(stage,x,y,r) {
var circle = new Kinetic.Shape(function(){
var context = this.getContext();
// draw the circle here: strokeStyle, beginPath, arc, etc...
});
circle.addEventListener("mouseover", function(){
// do something
});
stage.add(circle);
}
If you don't want to use KineticJS after all, you will need to remember for yourself the positions and radii of every circle you drew, and then do something like this:
canvas.onmouseover = function onMouseover(e) {
var mx = e.clientX - canvas.clientLeft;
var my = e.clientY - canvas.clientTop;
// for each circle...
if ((mx-cx)*(mx-cx)+(my-cy)*(my-cy) < cr*cr)
// the mouse is over that circle
}

Resources