I have an adjacency chart which has about 1000 nodes and to make it readable I need the chart to be scrollable on the x-axis. I have the below which outputs the chart by using the div's scroll bars though this is cumbersome.
How do I change the below to allow the chart to pan left and right on mouse click / zoom?
Cheers
var x = d3.scale.ordinal().rangeBands([0, width]),
z = d3.scale.linear().domain([0, 4]).clamp(true),
c = d3.scale.category10().domain(d3.range(10));
var svg = d3.select("#graph-item").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
Related
I am currently trying to draw a map of the US with the counties-albers-10m.json file found on the topojson repo. I initially got a solid rectangle and, after changing fill to none, I am getting specks here and there. Going through stack, I found that the winding order may be wrong so I incorporated turf.js, but nothing is really changing. Here is the code:
var margin = {top: 0, left: 0, right: 0, bottom: 0},
height = 600 - margin.top - margin.bottom,
width = 1200 - margin.left - margin.right;
var svg = d3.select("#map")
.append("svg")
.attr("height", height + margin.top + margin.bottom)
.attr("width", width + margin.left + margin.right)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top +")");
d3.json("counties-albers-10m.json").then(function(data) {
console.log(data);
var projection = d3.geoAlbersUsa();
var path = d3.geoPath()
.projection(projection);
var counties = topojson.feature(data, data.objects.counties).features
console.log(counties)
counties.forEach(function(feature) {
feature.geometry = turf.rewind(feature.geometry, {reverse:true});
})
svg.selectAll(".county")
.data(counties)
.enter().append("path")
.attr("class", "county")
.attr("fill", "none")
.attr("stroke", "black")
.attr("d", path);
})
The dreaded black box
I'm trying to implement box plots as part of a data visualization interface that uses d3 and AngularJS. I'm working with this box plot package: https://bl.ocks.org/mbostock/4061502.
However, I can't figure out which part of the sample code controls the positioning of the box plots. In the example, the five box plots are arranged sequentially. When I try to generate my plots, they all appear on top of each other.
Here is the code that I'm using to generate the box plots:
boxplots = svg.selectAll("svg")
.data(boxPlotData)
.enter().append("svg")
.attr("class", "box")
.attr("width", boxWidth + margin.left + margin.right)
.attr("height", boxHeight + margin.bottom + margin.top)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(chart);
Here's the code for how my svg canvas is created. This is done in an angular directive:
template:"<svg width='825' height='600'></svg>",
link: function($scope, elem){
var d3 = $window.d3;
var rawSvg=elem.find('svg'); // this is the svg created in the template
var width = rawSvg[0].attributes[0].value;
var height = rawSvg[0].attributes[1].value;
var svg = d3.select(rawSvg[0]);
Edit: not perfect yet but getting there:
What you need is an ordinal scale to position the svg-elements for the boxes within the parent svg. Assuming width represents the width of your parent svg element and data is an array of your data elements, you can use this to create the scale:
const x = d3.scaleBand()
.range( [0, width] )
.domain( data.map( (el,i) => i ) );
Within the svg creation you can now use
boxplots = svg.selectAll("svg")
.data(boxPlotData)
.enter().append("svg")
.attr( "x", (d,i) => x(i) ) // this is added
.attr("class", "box")
.attr("width", boxWidth + margin.left + margin.right)
.attr("height", boxHeight + margin.bottom + margin.top)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(chart);
PS: This assumes you use v4 of d3js. The syntax in v3 for the scale is different.
PPS: I currently can not test the code, but it should work like described.
I have this d3 code, but I'm having trouble to align the bars to the x-axis.
I want the number, which represents an hour (range 0h-23h) to appear in the middle of the number of hours, which is the y-value.
The variable times gets instantiated with 24 values (indexes 0 to 23 h).
Any response or ideas are welcome.
What it looks like now;
http://i.imgur.com/PLu7Uv2.png?1
var times = buildTimeTable(data);
var margin = {top: 20, right: 10, bottom: 20, left: 10};
var width = 500- margin.left - margin.right, height = 200- margin.top - margin.bottom;
var x = d3.scale.linear().domain([0, 23]).range([0, width]);
var y = d3.scale.linear().domain([0, Math.max.apply(Math, times)]).range([height, 0]);
var xAxis = d3.svg.axis().orient("bottom").scale(x).ticks(24);
var yAxis = d3.svg.axis().orient("left").scale(y);
d3.select("#statistics-hours > svg").remove();
var svg = d3.select("#statistics-hours").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");;
var bar = svg.selectAll(".bar").data(times).enter().append("rect")
.attr("class", "bar")
.attr("width", (width)/times.length - 5)
.attr("height", function(d){return height - y(d);})
.attr("x", function(d, i){return i * (width/times.length);})
.attr("y", function(d){return y(d);})
.attr("fill", "steelblue");
svg.append("g").attr("class", "axis").attr("transform", "translate("+ margin.left +"," + (height) + ")").call(xAxis);
svg.append("g").attr("class", "axis").attr("transform", "translate(" + (margin.left) + ",0)").call(yAxis);
You probably want to consider using an ordinal scale.
var x = d3.scale.ordinal().domain(d3.range[0,24]).rangeRoundBands([0,width],.1)
Now, x is just
.attr('x',function(d){return x(d);})
And the width is just...
.attr('width',function(d){return x.rangeBand();})
I am using D3.js to draw a tree,same with this chart:
http://bl.ocks.org/mbostock/7809166
But the height and width are fixed, I wanna the height can be auto adjust by the content.
My code:
var svg = d3.select("#feature_tree").append("svg")
.attr("width", width + margin.right + margin.left)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
If i do not define the height, the tree cannot be showed fully, unless I enlarge the browser, the missing tree nodes can be shown.
If i define the height, e.g. height = 2400px; if the content is very short. there will be a big blank.
You can measure the height of the content and adjust the SVG element accordingly:
var svgEl = document.getElementById("my-svg"),
bb = svgEl.getBBox();
svgEl.style.height = bb.y + bb.height;
svgEl.style.width = bb.x + bb.width;
Simple demo here: http://codepen.io/anon/pen/gpwbKd
I'm creating a diagram with D3 and JSON which is based on this:
http://bl.ocks.org/mbostock/4063550
I'm completely new to this...and I just can't seem to figure out how to move the position of the tree to the right or left of the page. Seems simple enough?
Reason I'm asking is because some of my text are cut out on the left side of screen.
Any help appreciated!
The easiest way to do this is to adjust the transform parameter of the top-level g element. In the example, it is created like this.
var svg = d3.select("body").append("svg")
.attr("width", diameter)
.attr("height", diameter - 150)
.append("g")
.attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")");
To move everything to the right, you would need to add something to the x translation, e.g.
var svg = d3.select("body").append("svg")
.attr("width", diameter)
.attr("height", diameter - 150)
.append("g")
.attr("transform", "translate(" + (diameter / 2 + 10) + "," + diameter / 2 + ")");