D3.js and dragdealer JS - javascript

I am using dragdealer JS with D3.js. What i am doing is that when You drag the slider made by dragdealer JS the elements made by D3.js will move like a picture slider.
Here is the code which which i wrote : code.
Now there are two problems with this code:
1) This code is working in FireFox but not in Chrome & IE 10?
2) How to configure the slider so that on one slide, only one tile will move into the view and only one will move out?
The number of tiles or rectangles are not fixed. There can be any number of tiles depending on the user.
Code:
var width = 4000,
height = 200,
margin = 2,
nRect = 20,
rectWidth = (width - (nRect - 1) * margin) / nRect,
svg = d3.select('#chart').append('svg')
.attr('width', width);
var data = d3.range(nRect),
posScale = d3.scale.linear()
.domain(d3.extent(data))
.range([0, width - rectWidth]);
console.log(rectWidth)
svg.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr('x', posScale)
.attr('width', rectWidth)
.attr('height', height);
function redraw(x)
{
svg.transition()
.ease("linear")
.attr("transform", "translate(" + -(x*rectWidth) + ")" );
console.log(-(x*rectWidth));
}
var step = nRect/2;
new Dragdealer('magnifier',
{
steps: step,
snap: true,
animationCallback: function(x, y)
{ console.log(x*10)
redraw(x*step);
}
});
i am trying to devise a way so that the value of steps will change according to the number of tiles.
Please help me.

You had a few problems that I've fixed here: http://jsfiddle.net/SqKZv/1/
In Chrome your svg element needed the height property set
In Chrome/IE, it doesn't appear that you can apply the transform attribute to your SVG element, I'm actually surprised this works in FireFox. I wrapped all of your rect elements in a g element and transformed that.
D3 does dragging very well by itself, so you don't need Dragdealer to do this. In addition to d3.behavior.drag, you can check out d3.svg.brush, specifically these examples of snapping to get what you want:
Brush Snapping http://bl.ocks.org/mbostock/6232537
Brush Snapping II http://bl.ocks.org/mbostock/6232620

You may also want to try out the new D3 feature called brush: https://github.com/mbostock/d3/wiki/SVG-Controls
Here is an example I made using brush to implement a similar feature as you mentioned.
https://github.com/CSE512-14W/a3-chaoyu-aniket

Related

Brush functionality in my d3 line chart is not working as expected

My implementation for Brush & Zoom functionality in my d3 line chart is not working as expected,
I followed this link - https://bl.ocks.org/EfratVil/92f894ac0ba265192411e73f633a3e2f,
Problems what I am facing is -
chart is not showing all the values, I have 4 data but it only shows 3 data
onClick of dot I am showing the rect which is not moving with the brush functionality
minor thing but chart always goes out of the box
My code sandbox - https://codesandbox.io/s/proud-firefly-xy1py
Can someone point out what I am doing wrong? thanks.
Please suggest me what I am doing wrong, thanks.
Your first point is going behind your clip area. For example, if you right click on the first visible circle and inspect element you will see all 4 circle elements are present in the dom. The first circle element is behind the axis.
This means you have to move your plot to the right. Unfortunately, the way you have coded the chart you have not appended a g element for the main chart and then appended the circles and path to that g element. As a result this has to be done in multiple places.
First we adjust your clip path as:
svg
.append("defs")
.append("SVG:clipPath")
.attr("id", "clip")
.append("SVG:rect")
.attr("width", containerWidth)
.attr("height", height)
.attr("x", 40)
.attr("y", 0);
next we adjust your circles
scatter
.selectAll(".foo")
.data(data)
.enter()
.append("circle")
.attr("class", "foo")
.attr("transform", "translate(40,0)")
and then your line
scatter
.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line)
.attr("transform", "translate(40,0)");
You will have to account for this 40 px translate for your other elements as well. Although I am having a hard time destructuring your svg. I think this should give you the idea though. Check the axis matches the time points as well.
Check the code sand box
Update
To make the rectangles move with the brush, you will have to add code to your brushed const function to recalculate the x, y, width and height using the updated scales.
Update2
After going through the codesandbox presented in the comments I was able to add the code to update the rectangles to the brushed const as below to make the rects also move with the brushing:
// update rectangles
scatter
.selectAll(".rect-elements")
.attr("x", d => {
console.log(d);
return xScale(d.startTime) - 12.5;
})
.attr("y", 0)
.attr("width", 24)
.attr("height", height + 5);
Full working Code Sandbox.

How to translate SVG and all its children

I have been playing with this fiddle : https://jsfiddle.net/thatOneGuy/8k8ggpcn/4/
Majority of it is not my code, but from line 330-345 I have added, tried to, the ability to move the SVG by a certain amount. But this is not working. I can't seem to figure out why.
I have tried using D3. So added an ID of mainSVGContainer to the SVG at the start :
svg = d3.select("#svg1")
.append("svg").attr('id', 'mainSVGContainer')
And used this to translate :
d3.select('#mainSVGContainer').style('fill','blue').attr("transform", "translate(0 "+difference +")")
Difference is an integer worked out before this call, its around 130. But this doesn't seem to work. It gets written to the DOM but doesn't look like it's affecting the SVG.
I have tried with vanilla JavaScript :
var svgContainer = document.getElementById('mainSVGContainer');
svgContainer.offsetLeft = 1000;
This doesn't work either
And I have tried with inline JS to alter the styling :
svgContainer.style.left = 1000;
Still no luck. I presumed it was due to it being an SVG element but I tried doing the same with the container of this SVG which was a div and no luck.
Any ideas ?
As JSBob and others from the following :
d3 Workaround for svg transform in chrome
d3 Nested SVG plots differently in firefox than in Chrome
I found out Chrome, along with other browsers, don't support the translation of SVG elements. So, as a work around, I appended a g element to the SVG and translated that :
Appending g :
svg = d3.select("#svg1")
.append("svg").attr("height", h)
.attr("width", w)
.append('g')
.attr('id', 'mainSVGContainer')
.attr("height", h)
.attr("width", w)
.attr("class", "graph-svg-component")
Translating g :
d3.select('#mainSVGContainer').transition().duration(1000).attr("transform", "translate(0 "+(-difference) +")")
Added the transition so you can see before and after :)
Updated fiddle : https://jsfiddle.net/thatOneGuy/8k8ggpcn/7/

Programatic zoom in D3

Using the code pattern here, I want to programmatically achieve semantic zooming (in or out). I'm unsure how to get the proper x, y, and scaleExtent terms that are augmented via the zoom:
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.call(d3.behavior.zoom().x(x).y(y).scaleExtent([1, 8]).on("zoom", zoom));
See JSfiddle here. The zoomIn and zoomOut functions should simulate the mousewheel events centered in the SVG.
Here's a solution based on the answer below: http://jsbin.com/dociwuvacu/1
I believe I successfully updated your fiddle, but in case not, here is the type of code you would need:
function zoomIn() {
zoomer.scale(zoomer.scale()+.1);
zoomer.event(svg);
}
function zoomOut() {
zoomer.scale(zoomer.scale()-.1);
zoomer.event(svg);
}

Zooming issues with Force Directed

I've generated a D3 visualization (a force directed graph) that requires zooming and panning. I've got 2 problems however when it comes to zooming, and I can't find any decent examples on how I might overcome these problems:
The first problem is I've followed all the examples I can find about zooming, which involves adding groupings and adding a rectangle to ensure that the entire area is zoomeable. If I style the rectangle a slightly opaque blue then I get SVG that looks like this when I zoom out:
The problem with this is that I can zoom in/out absolutely fine while I've got my mouse over the blue rectangle area. The problem is I want this to be fully opaque, which means that when I zoom right out, it's very easy to place the cursor outside of this box and then you're unable to zoom in. Is there a way I can make the SVG itself zoomeable or pick up on these events?
This is how I go about generating the various layers and the zoomed function:
function zoomed() {
group2.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
svg = d3.select(target)
.attr("pointer-events", "all")
.append("svg");
group = svg.append('svg:g')
.call(d3.behavior.zoom().on('zoom', zoomed))
.on("dblclick.zoom", null);
group2 = group.append("g");
rect = group2.append('svg:rect')
.style("opacity", 0.3)
.attr('width', width)
.attr('height', height);
The second problem I have is that I'm trying to automatically size my text based on this http://bl.ocks.org/mbostock/1846692 example. When I've tried this however I seem to be getting text that renders really poorly. It seems to suffer from:
Being difficult to read
Not appearing contained within the circle
Being so small the entire thing compresses (image 2)
var texts = planets.append("text")
.text(function(d) { return d.name; })
.style("font-size", "24px") // initial guess
.style("font-size", function(d) {
return Math.min( 2 * d.size, (2 * d.size - 8) / this.getComputedTextLength() * 24) + "px";
})
.attr("dx", function(d) { return -d.size; })
.attr("dy", ".35em")
.style("fill", "white");
I thought that SVG would just handle this, I understand that some of the font-sizes can come out small, but if you zoom in should that not all sort itself out?
I've got a JSFiddle http://jsfiddle.net/IPWright83/vo7Lpefs/22/ to demonstrate.
I've not yet managed to work out a resolution to my first issue (regarding the zooming box) however I did manage to track down the text rendering issue.
This was actually because the each circle/node had a stroke property to provide the white border. This was also applying to the text element, and when the font was very small the stroke was much larger than the overall fill of the text. Removing the stroke from the text elements ensured that they rendered even when very small.

d3.js network diagram zoom

I have probably a relativly simple question.
Here is my simple diagram enter link description here
And I would love to implement zooming in and out functionality, using the behaviour descibed here
enter link description here. But I cant make it work, maybe You would spot the problem.
Thanks for Your time.
The whole zooming in functionality seems to be handled with this assignment and function:
svg = d3.select("body").append("svg").attr("width", width).attr("height", height)
.call(d3.behavior.zoom().x(x).y(y).scaleExtent([1, 8]).on("zoom", zoom));
function zoom() {
svg.clearRect(0, 0, width, height);
}
The code you have tried for zooming is used for canvas. You can use transform attribute for zooming in svg.
You can put the whole graph in a (group) element and apply transform attribute to element.
svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
.call(d3.behavior.zoom().x(x).y(y).scaleExtent([1, 8]).on("zoom", zoom))
.append("g");
function zoom() {
svg.attr("transform","translate("+ d3.event.translate+") scale("+d3.event.scale+")");
}
Here is the fiddle

Categories

Resources