Add <id> + <data> to an ARC of a D3-PIE-chart - javascript

I happened to play around with the D3js-Library to visualize some SQL-JSON_LD data and want to do the following:
attach individual id-TAG as well as data-set (Matrix with various elements) to each slice
My Code right now looks like this
<!DOCTYPE html>
<meta charset="utf-8">
<style>
path {
fill: #ccc;
stroke: #333;
stroke-width: 1.5px;
transition: fill 250ms linear;
transition-delay: 150ms;
}
path:hover {
fill: #999;
stroke: #000;
transition-delay: 0;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var data = {
{"year":"2017-07-01","value":"1"},
{"year":"2017-07-02","value":"1"},
{"year":"2017-07-03","value":"2"},
{"year":"2017-07-04","value":"3"},
{"year":"2017-07-05","value":"5"},
{"year":"2017-07-06","value":"8"},
{"year":"2017-07-07","value":"13"},
{"year":"2017-07-08","value":"21"},
{"year":"2017-07-09","value":"24"},
{"year":"2017-07-10","value":"55"},
{"year":"2017-07-11","value":"89"},};
var width = 960,
height = 500;
arc_ids = d3.range(data.length); // for naming the arcs
var outerRadius = height / 2 - 20,
innerRadius = outerRadius / 3,
cornerRadius = 10;
var pie = d3.layout.pie()
.padAngle(.02);
var arc = d3.svg.arc()
.padRadius(outerRadius)
.innerRadius(innerRadius);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.attr("id","viz_pieChart") // adds an ID to the whole chart
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
svg.selectAll("path")
.data(pie(data.map(function(d) { return parseInt(d.value); })))
.attr("id", function(d, i) { console.log('CP1'); return "arc-" + arc_ids[i]; }) // This was intended to add an individual id to each arc, but it doesn't
.attr("data", function(d) { return d.data; }) // attach data to arc according to value, as e.g.: {"year":"2017-07-01","value":"1"}
.enter().append("path")
.each(function(d) {
d.outerRadius = outerRadius - 20;
})
.attr("d", arc)
.on("mouseover", arcTween(outerRadius, 0))
on("click", function(d){console.log(d.id);console.log(d.data.toString())}); //print id of the clicked arc as well as saved data
.on("mouseout", arcTween(outerRadius - 20, 150));
function arcTween(outerRadius, delay) {
return function() {
d3.select(this).transition().delay(delay).attrTween("d", function(d) {
var i = d3.interpolate(d.outerRadius, outerRadius);
return function(t) {
d.outerRadius = i(t);
return arc(d);
};
});
};
}
//test whether an arc can be reached, e.g. the 2nd Element
console.log(document.getElementById('slice-1')); // gives an error
</script>
I also checked this1, this2 and this3 as they seemed promising, but it still does not work for me.
Afterwards I want to use the attached data of an arc to print it into another svg-graphic. But first adressing has to work.
And I'm sorry for the post with more than one specific question!
Thank you for your help!

you must append the path before give it an id or data
<!DOCTYPE html>
<meta charset="utf-8">
<style>
path {
fill: #ccc;
stroke: #333;
stroke-width: 1.5px;
transition: fill 250ms linear;
transition-delay: 150ms;
}
path:hover {
fill: #999;
stroke: #000;
transition-delay: 0;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var data = [
{"year":"2017-07-01","value":"1"},
{"year":"2017-07-02","value":"1"},
{"year":"2017-07-03","value":"2"},
{"year":"2017-07-04","value":"3"},
{"year":"2017-07-05","value":"5"},
{"year":"2017-07-06","value":"8"},
{"year":"2017-07-07","value":"13"},
{"year":"2017-07-08","value":"21"},
{"year":"2017-07-09","value":"24"},
{"year":"2017-07-10","value":"55"},
{"year":"2017-07-11","value":"89"}];
var width = 960,
height = 500;
arc_ids = d3.range(data.length); // for naming the arcs
var outerRadius = height / 2 - 20,
innerRadius = outerRadius / 3,
cornerRadius = 10;
var pie = d3.layout.pie()
.padAngle(.02);
var arc = d3.svg.arc()
.padRadius(outerRadius)
.innerRadius(innerRadius);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.attr("id","viz_pieChart") // adds an ID to the whole chart
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
svg.selectAll("path")
.data(pie(data.map(function(d) {
return parseInt(d.value);
})))
.enter().append("path")
.each(function(d) {
d.outerRadius = outerRadius - 20;
})
.attr("id", function(d, i) { return "arc-" + arc_ids[i]; })
// This was intended to add an individual id to each arc, but it doesn't
.attr("data", function(d) { return d.data; }) // attach data to arc according to value, as e.g.: {"year":"2017-07-01","value":"1"}
.attr("d", arc)
.on("mouseover", arcTween(outerRadius, 0))
.on("click", function(d){
console.log(this.id);
console.log(d.data.toString())
}) //print id of the clicked arc as well as saved data
.on("mouseout", arcTween(outerRadius - 20, 150));
function arcTween(outerRadius, delay) {
return function() {
d3.select(this).transition().delay(delay).attrTween("d", function(d) {
var i = d3.interpolate(d.outerRadius, outerRadius);
return function(t) {
d.outerRadius = i(t);
return arc(d);
};
});
};
}
//test whether an arc can be reached, e.g. the 2nd Element
console.log(document.getElementById('slice-1')); // gives an error
</script>

Related

Lasso and D3.js

I thought i had a similar issues to this SO user here, but after swapping out the minified lasso library for the actual lasso code, I'm still not getting a working output.
My code is more or less the same as the example code on lasso's git hub (I've made the required changes for my set up), so theoretically i shouldn't be having any issues, right?
I just want to get the lasso itself working before appending my own styles and returning any data.
<script>
var data = [["Arsenal",-0.0032967741593940836, 0.30399753945657115],["Chelsea", 0.2752159801936051, -0.0389675484210763], ["Liverpool",-0.005096951348655329, 0.026678627680541075], ["Manchester City",-0.004715381791104284, -0.12338379196523988], ["Manchester United",0.06877966010653305, -0.0850615090351779], ["Tottenham",-0.3379518099485709, -0.09933664174939877]];
const colours = d3.scaleOrdinal()
.domain(data)
.range(["#F8B195", "#F67280", "#C06C84", "#6C5B7B", "#355C7D", "#2A363B"]);
var canvasW = 675;
var canvasH = 400;
var w = 365;
var h = 365;
var xPadding = 30;
var yPadding = 20;
var padding = 10;
var xScale = d3.scaleLinear()
.range([xPadding, w - padding])
.domain([-1, 1]);
var yScale = d3.scaleLinear()
.range([h - yPadding, padding])
.domain([-1, 1]);
var svg = d3.select('body')
.append("svg")
.attr('width', canvasW)
.attr('height', canvasH);
var lasso_start = function() {
lasso.items()
.attr("r",7)
.classed("not_possible",true)
.classed("selected",false);
};
var lasso_draw = function() {
lasso.possibleItems()
.classed("not_possible",false)
.classed("possible",true);
lasso.notPossibleItems()
.classed("not_possible",true)
.classed("possible",false);
};
var lasso_end = function() {
lasso.items()
.classed("not_possible",false)
.classed("possible",false);
lasso.selectedItems()
.classed("selected",true)
.attr("r",7);
lasso.notSelectedItems()
.attr("r",3.5);
};
svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("r", 7)
.attr("cx", function(d) { return xScale(d[1]); })
.attr("cy", function(d) { return yScale(d[2]); })
.attr("fill", function(d) {
var result = null;
if (data.indexOf(d) >= 0) {
result = colours(d);
} else {
result = "white";
}
return result;
});
var legend = svg.selectAll(".legend")
.data(colours.domain())
.enter()
.append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 29 + ")"; });
legend.append("rect")
.attr("x", canvasW - 184)
.attr("y", 11)
.attr("width", 18)
.attr("height", 18)
.style("fill", colours);
legend.append("text")
.attr("x", canvasW - 194)
.attr("y", 20)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return d[0];})
var lasso = d3.lasso()
.closePathDistance(75)
.closePathSelect(true)
.area(svg)
.items("circle")
.on("start",lasso_start)
.on("draw",lasso_draw)
.on("end",lasso_end);
svg.call(lasso);
CSS
<style>
#import url('https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300');
#import url("https://fonts.googleapis.com/css?family=Lato:300");
text {
font-family: "Open Sans Condensed";
}
.axis path {
stroke: black;
}
.tick line {
visibility: hidden;
}
.border {
margin-top: 9px;
margin-left: 29px;
border: .5px solid black;
width: 325px;
height: 335px;
position: absolute;
}
.lasso path {
stroke: rgb(80,80,80);
stroke-width:2px;
}
.lasso .drawn {
fill-opacity:.05 ;
}
.lasso .loop_close {
fill:none;
stroke-dasharray: 4, 4;
}
.lasso .origin {
fill:#3399FF;
fill-opacity:.5;
}
.not_possible {
fill:rgb(200,200,200);
}
.possible {
fill:#EC888C;
}
</style>
I never used d3.lasso before but looking at this bl.ock using d3 v4, looks like your code is missing a few minor things:
Area to be passed to d3 lasso is now done using targetArea
var lasso = d3.lasso()
.targetArea(svg)
Items passed to d3 lasso must be a d3 selection and not a string
var circles = svg.selectAll("circle")...
var lasso = d3.lasso()
.items(circles)
And of course, using the actual minified lasso code in a script tag, here's a snippet:
https://bl.ocks.org/shashank2104/f878d660bd9013faa6d48236b5fe9502/67d50a5c7a21c0adfa5ed66ce3dc725f0a45c8c2
Also, I've added some CSS to the selected circles just to differentiate when compared with others:
.selected {
fill: steelblue;
}
Hope this helps.

Paths not drawn after dragging in parallel coordinate in d3 V4

Here is a simple parallel coordinate in d3 V4
http://plnkr.co/edit/Ejg7CI7STPqXKB2tot51?p=preview
It is similar to https://bl.ocks.org/jasondavies/1341281 , which is in V3.
Following are the steps to reproduce the issue:
Step1. Brush some area (say 0.8 to 0.4) in column1....
Step2. Brush some area (say 0.7 to 0.4) in column3....
Step3. Now drag the axis column3 to the position of column2. (So basically axis ordering will get changed, from Column1, 2 , 3, 4 .. it will change to column1, 3 ,2, 4.
Step4. Brush column3 (which is now next to column1) again. You will see no paths are being drawn.
Any help would be appreciated.
Thanks
<!DOCTYPE html>
<meta charset="utf-8">
<style>
svg {
font: 10px sans-serif;
}
.background path {
fill: none;
stroke: #ddd;
stroke-opacity: .4;
shape-rendering: crispEdges;
}
.foreground path {
fill: none;
stroke: steelblue;
stroke-opacity: .7;
}
.brush .extent {
fill-opacity: .3;
stroke: #fff;
shape-rendering: crispEdges;
}
.axis line,
.axis path {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.axis text {
text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff;
cursor: move;
}
</style>
<body>
<script src="http://d3js.org/d3.v4.min.js"></script>
<script>
var margin = {top: 30, right: 10, bottom: 10, left: 10},
width = 600 - margin.left - margin.right,
height = 200 - margin.top - margin.bottom;
var x = d3.scalePoint().rangeRound([0, width]).padding(1),
y = {},
dragging = {};
var line = d3.line(),
//axis = d3.axisLeft(x),
background,
foreground,
extents;
var container = d3.select("body").append("div")
.attr("class", "parcoords")
.style("width", width + margin.left + margin.right + "px")
.style("height", height + margin.top + margin.bottom + "px");
var svg = container.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 quant_p = function(v){return (parseFloat(v) == v) || (v == "")};
d3.json("convertcsvSO.json", function(error, cars) {
dimensions = d3.keys(cars[0]);
x.domain(dimensions);
dimensions.forEach(function(d) {
var vals = cars.map(function(p) {return p[d];});
if (vals.every(quant_p)){
y[d] = d3.scaleLinear()
.domain(d3.extent(cars, function(p) {
return +p[d]; }))
.range([height, 0])
}
else{
vals.sort();
y[d] = d3.scalePoint()
.domain(vals.filter(function(v, i) {return vals.indexOf(v) == i;}))
.range([height, 0],1);
}
})
extents = dimensions.map(function(p) { return [0,0]; });
// Add grey background lines for context.
background = svg.append("g")
.attr("class", "background")
.selectAll("path")
.data(cars)
.enter().append("path")
.attr("d", path);
// Add blue foreground lines for focus.
foreground = svg.append("g")
.attr("class", "foreground")
.selectAll("path")
.data(cars)
.enter().append("path")
.attr("d", path);
// Add a group element for each dimension.
var g = svg.selectAll(".dimension")
.data(dimensions)
.enter().append("g")
.attr("class", "dimension")
.attr("transform", function(d) { return "translate(" + x(d) + ")"; })
.call(d3.drag()
.subject(function(d) { return {x: x(d)}; })
.on("start", function(d) {
dragging[d] = x(d);
background.attr("visibility", "hidden");
})
.on("drag", function(d) {
dragging[d] = Math.min(width, Math.max(0, d3.event.x));
foreground.attr("d", path);
dimensions.sort(function(a, b) { return position(a) - position(b); });
x.domain(dimensions);
g.attr("transform", function(d) { return "translate(" + position(d) + ")"; })
})
.on("end", function(d) {
delete dragging[d];
transition(d3.select(this)).attr("transform", "translate(" + x(d) + ")");
transition(foreground).attr("d", path);
background
.attr("d", path)
.transition()
.delay(500)
.duration(0)
.attr("visibility", null);
}));
// Add an axis and title.
var g = svg.selectAll(".dimension");
g.append("g")
.attr("class", "axis")
.each(function(d) { d3.select(this).call(d3.axisLeft(y[d]));})
//text does not show up because previous line breaks somehow
.append("text")
.attr("fill", "black")
.style("text-anchor", "middle")
.attr("y", -9)
.text(function(d) { return d; });
// Add and store a brush for each axis.
g.append("g")
.attr("class", "brush")
.each(function(d) {
if(y[d].name == 'r'){
// console.log(this);
d3.select(this).call(y[d].brush = d3.brushY().extent([[-8, 0], [8,height]]).on("start", brushstart).on("brush", brush_parallel_chart));
}
})
.selectAll("rect")
.attr("x", -8)
.attr("width", 16);
}); // closing
function position(d) {
var v = dragging[d];
return v == null ? x(d) : v;
}
function transition(g) {
return g.transition().duration(500);
}
// Returns the path for a given data point.
function path(d) {
return line(dimensions.map(function(p) { return [position(p), y[p](d[p])]; }));
}
// brush start function
function brushstart() {
d3.event.sourceEvent.stopPropagation();
}
// Handles a brush event, toggling the display of foreground lines.
function brush_parallel_chart() {
for(var i=0;i<dimensions.length;++i){
if(d3.event.target==y[dimensions[i]].brush) {
extents[i]=d3.event.selection.map(y[dimensions[i]].invert,y[dimensions[i]]);
}
}
foreground.style("display", function(d) {
return dimensions.every(function(p, i) {
if(extents[i][0]==0 && extents[i][0]==0) {
return true;
}
return extents[i][1] <= d[p] && d[p] <= extents[i][0];
}) ? null : "none";
});
}
</script>
In the drag callbacks, the dimensions are being sorted BUT the extents aren't. I've added a few lines that sorts extents array based on the new dimensions (by using origDimensions which is the original array)
Here's a fork of your plunkr: http://plnkr.co/edit/DquAXNv2mbbok7ssNuoX?p=preview
Relevant code:
var origDimensions = dimensions.slice(0);
And within the dragend callback:
// one way of sorting the extents array based on dimensions
var new_extents = [];
for(var i=0;i<dimensions.length;++i){
new_extents.push(extents[origDimensions.indexOf(dimensions[i])]);
}
extents = new_extents;
origDimensions = dimensions.slice(0); // setting origDimensions to the new array
Hope this helps. (and btw seems like the brushstart is empty which leads to showing NO curves on brush reset - try resetting brush on any axis).

how to plot the image inside the polygon in d3

hi all i am using d3 chart with polygon i have one map structure d3 chart and plot one circle for the purpose of show tooltip now my need is i need to show one image 'https://i.stack.imgur.com/O9xB5.png' to replace the circle so when mouse over the image i shown tooltip and another need show 'State Abbr' inside polygon like Ak,TD,PD...
.help ow to do this here i attached my code files
code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="http://d3js.org/d3.v3.min.js"></script>
<style type="text/css">
/* On mouse hover, lighten state color */
path:hover {
fill-opacity: .7;
}
/* Style for Custom Tooltip */
div.tooltip {
position: absolute;
text-align: center;
width: 60px;
height: 28px;
padding: 2px;
font: 12px sans-serif;
background: white;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
/* Legend Font Style */
body {
font: 11px sans-serif;
}
/* Legend Position Style */
.legend {
position:absolute;
left:800px;
top:350px;
}
</style>
</head>
<body>
<script type="text/javascript">
//Width and height of map
var width = 960;
var height = 500;
// D3 Projection
var projection = d3.geo.albersUsa()
.translate([width/2, height/2])
.scale([1000]);
// Define path generator
var path = d3.geo.path()
.projection(projection);
// Define linear scale for output
var color = d3.scale.linear()
.range(["green","red"]);
var legendText = ["Population Present", "Population Absent"];
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var div = d3.select("body")
.append("div")
.attr("class", "tooltip")
.style("opacity", 0);
// Load in my states data!
d3.csv("Population_education.csv", function(data) {
// Load GeoJSON data and merge with states data
d3.json("us-states.json", function(json) {
// Loop through each state data value in the .csv file
for (var i = 0; i < data.length; i++) {
// Grab State Name
var dataState = data[i].SiteState;
// Get Population
var dataPop = data[i].Population;
// Grab data value
if(data[i].Members > 0) {
var dataValue = 1;
}
else { var dataValue = 0;}
// Find the corresponding state inside the GeoJSON
for (var j = 0; j < json.features.length; j++) {
var jsonState = json.features[j].properties.name;
if (dataState == jsonState) {
// Copy the data value into the JSON
json.features[j].properties.MembersPresent = dataValue;
json.features[j].properties.pop = +dataPop;
// Stop looking through the JSON
break;
}
}
}
// Get Max and Min Population and update colorscale
var max = d3.max(json.features, function(d) { return d.properties.pop });
var min = d3.min(json.features, function(d) { return d.properties.pop })
color.domain([min, max]); // setting the range of the input data
// Bind the data to the SVG and create one path per GeoJSON feature
svg.selectAll("path")
.data(json.features)
.enter().append("path")
.attr("d", path)
.style("stroke", "#fff")
.style("stroke-width", "1")
.style("fill", function(d) {
return color(d.properties.pop)
});
// Map the cities I have lived in!
d3.csv("Population_education.csv", function(data) {
svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) {
if (d.AvgLng != 0 && d.AvgLat != 0)
return projection([d.AvgLng, d.AvgLat])[0];
})
.attr("cy", function(d) {
if (d.AvgLng != 0 && d.AvgLat != 0)
return projection([d.AvgLng, d.AvgLat])[1];
})
.attr("r", function(d) {
return 3;
})
.style("fill", "rgb(217,91,67)")
.style("opacity", 0.45)
.on("mouseover", function(d) {
div.transition()
.duration(200)
.style("opacity", .9);
div.html("State:" + d['State Abbr'] + "<br/>" + "Pop:" + d.Population)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
});
var legend = d3.select("body").append("svg")
.attr("class", "legend")
.attr("width", 140)
.attr("height", 200)
.selectAll("g")
.data(color.domain().slice().reverse())
.enter()
.append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.data(legendText)
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".35em")
.text(function(d) { return d; });
});
});
</script>
</body>
</html>
Data
Population_education.csv
RowID,SiteState,State Abbr,AvgLat,AvgLng,Population
1,Alabama,AL,32.806671,-86.79113,28
2,Arizona,AZ,33.729759,-111.431221,11704
3,California,CA,36.116203,-119.681564,4356448
4,Colorado,CO,39.059811,-105.311104,374435
5,Connecticut,CT,41.597782,-72.755371,455966
6,Florida,FL,27.766279,-81.68678300000001,442537
7,Georgia,GA,33.040619,-83.643074,1339081
8,Illinois,IL,40.349457,-88.986137,29
9,Indiana,IN,39.849426,-86.258278,1525124
10,Iowa,IA,42.011539,-93.210526,185146
11,Kansas,KS,38.5266,-96.72648599999999,129301
12,Kentucky,KY,37.66814,-84.670067,621047
13,Louisiana,LA,31.169546,-91.867805,170568
14,Maine,ME,44.693947,-69.381927,222966
15,Maryland,MD,39.063946,-76.80210099999999,256966
16,Massachusetts,MA,42.230171,-71.530106,27
17,Michigan,MI,43.326618,-84.536095,27
18,Minnesota,MN,45.694454,-93.900192,11
19,Missouri,MO,38.456085,-92.28836800000001,420415
20,Nevada,NV,38.313515,-117.055374,309799
21,New Hampshire,NH,43.452492,-71.563896,195948
22,New Jersey,NJ,40.298904,-74.521011,241039
23,New Mexico,NM,34.840515,-106.248482,1945
24,New York,NY,42.165726,-74.94805100000001,1075153
25,North Carolina,NC,35.630066,-79.80641900000001,14
26,Ohio,OH,40.388783,-82.764915,1526404
27,Oregon,OR,44.572021,-122.070938,11
28,Pennsylvania,PA,40.590752,-77.209755,197
29,South Carolina,SC,33.856892,-80.945007,45
30,Tennessee,TN,35.747845,-86.692345,446667
31,Texas,TX,31.054487,-97.563461,736672
32,Vermont,VA,37.769337,-78.169968,2324640
33,Washington,WA,47.400902,-121.490494,141319
34,West Virginia,WV,38.491226,-80.954453,128275
35,Wisconsin,WI,44.268543,-89.616508,405942
36,Alaska,AK,0,0,0
37,Arkansas,AR,0,0,0
38,Delaware,DE,0,0,0
39,District of Columbia,DC,0,0,0
40,Hawaii,HI,0,0,0
41,Idaho,ID,0,0,0
42,Mississippi,MS,0,0,0
43,Montana,MT,0,0,0
44,Nebraska,NE,0,0,0
45,North Dakota,ND,0,0,0
46,South Dakota,SD,0,0,0
47,Utah,UT,0,0,0
48,Virginia,VT,0,0,0
49,Wyoming,WY,0,0,0
50,Oklahoma,OK,0,0,0
51,Rhode Island,RI,0,0,0
My us-states.json is as in the following link https://raw.githubusercontent.com/alignedleft/d3-book/master/chapter_12/us-states.json
Code to add image and tooltip to each polygon.
paths.each(function(d) {
if (this.getTotalLength() > 0) {
var midPoint = path.centroid(d);
svg.append("svg:image")
.attr("height", "15px")
.attr("width", "15px")
.attr("xlink:href", "https://i.stack.imgur.com/O9xB5.png")
.attr("transform", "translate(" + midPoint[0] + ", " + midPoint[1] + ")")
.append("title")
.text(d.properties.abbr);
svg.append("svg:text")
.attr("x", midPoint[0])
.attr("y", midPoint[1])
.text(d.properties.abbr);
}
});
JSFiddle
To include abbr details to the data, code as shown below.
// Find the corresponding state inside the GeoJSON
for (var j = 0; j < json.features.length; j++) {
var jsonState = json.features[j].properties.name;
if (dataState == jsonState) {
// Copy the data value into the JSON
json.features[j].properties.MembersPresent = dataValue;
json.features[j].properties.pop = +dataPop;
json.features[j].properties.abbr = data[i]["State Abbr"];
// Stop looking through the JSON
break;
}
}

d3.js zoomable map too small in the beginning

I'm trying to modify the example of a zoomable map of the United States, provided by mbostock to fit with Europe.
At the point I've been able to get it sort of, it's so small in the beginning!
I've looked at everything trying to change the presentation size in the beginning, i.e. before the zoom, to be larger, but I've not been able to figure it out. How to achieve this?
All the code is here.
But really, it's just the following short file and an eu.json file:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.background {
fill: none;
pointer-events: all;
}
#states {
fill: #aaa;
}
#states .active {
fill: orange;
}
#state-borders {
fill: none;
stroke: #fff;
stroke-width: 0.5px;
stroke-linejoin: round;
stroke-linecap: round;
pointer-events: none;
}
</style>
<body>
<div id="map"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.19/topojson.min.js"></script>
<script>
var width = 960;
var height = 500;
var centered;
var projection = d3.geo.mercator();
var path = d3.geo.path()
.projection(projection);
var svg = d3.select("#map")
.append("svg")
.attr("width", width)
.attr("height", height);
svg.append("rect")
.attr("class", "background")
.attr("width", width)
.attr("height", height)
.on("click", clicked);
var g = svg.append("g");
d3.json("eu.json", function(error, data) {
if (error) throw error;
g.append("g")
.attr("id", "states")
.selectAll("path")
.data(topojson.feature(data, data.objects.europe).features)
.enter().append("path")
.attr("d", path)
.on("click", clicked);
g.append("path")
.datum(topojson.mesh(data, data.objects.europe, function(a, b) { return a !== b; }))
.attr("id", "state-borders")
.attr("d", path);
});
function clicked(d) {
var x, y, k;
if (d && centered !== d) {
var centroid = path.centroid(d);
x = centroid[0];
y = centroid[1];
k = 4;
centered = d;
} else {
x = width / 2;
y = height / 2;
k = 1;
centered = null;
}
g.selectAll("path")
.classed("active", centered && function(d) { return d === centered; });
g.transition()
.duration(750)
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(" + k + ")translate(" + -x + "," + -y + ")")
.style("stroke-width", 1.5 / k + "px");
}
</script>

glowing sphere - d3 orthographic projection cant get css to work

I'm trying to combine these two d3 examples:
http://bl.ocks.org/mbostock/4183330
http://bl.ocks.org/mbostock/2206590
I have a sphere with the projection displaying correctly, and the zoom working correctly. All I'm trying to do now is style it.
I got the world tour example working previously, it uses canvas and I was able to give it a shadow to create a glow effect that I really liked.
After merging these two code pieces I'm now using svg elements and I cannot seem to get the glow effect to work.
Here is my code (the fill attribute of the .globe class seems to be working):
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
background: #000000;
}
.background {
fill: none;
pointer-events: all;
}
.feature {
fill: #ccc;
cursor: pointer;
}
.feature.active {
fill: #00FF15;
}
.globe
{
fill:#fff;
strokeStyle: #35C441;
lineWidth: 5;
shadowColor: #35C441;
shadowBlur: 40;
shadowOffsetX: 0;
shadowOffsetY: 0;
}
.mesh {
fill: none;
stroke: #fff;
stroke-linecap: round;
stroke-linejoin: round;
}
</style>
<body>
<script src="d3/d3.v3.min.js"></script>
<script src="d3/topojson.v1.min.js"></script>
<script>
var width = 960,
height = 720;
active = d3.select(null);
var globe = {type: "Sphere"};
var projection = d3.geo.orthographic()
.scale(height / 2.1)
.translate([width / 2, height / 2])
.clipAngle(90)
.precision(.5);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
//append a rectange to the svg element. give it the background css style class.
//on click do reset?
svg.append("rect")
.attr("class", "background")
.attr("width", width)
.attr("height", height)
.on("click", reset);
//append "g" to the svg element
var g = svg.append("g")
.style("stroke-width", "1.5px");
var path = d3.geo.path()
.projection(projection)
d3.json("./world-110m.json", function(error, world) {
g.append("path")
.datum(globe)
.attr("class", "globe")
.attr("d", path);
g.selectAll("path")
.data(topojson.feature(world, world.objects.countries).features)
.enter().append("path")
.attr("d", path)
.attr("class", "feature")
.on("click", clicked);
g.append("path")
.datum(topojson.mesh(world, world.objects.countries, function(a, b) { return a !== b; }))
.attr("class", "mesh")
.attr("d", path);
});
function clicked(d) {
if (active.node() === this) return reset();
active.classed("active", false);
active = d3.select(this).classed("active", true);
var bounds = path.bounds(d),
dx = bounds[1][0] - bounds[0][0],
dy = bounds[1][1] - bounds[0][1],
x = (bounds[0][0] + bounds[1][0]) / 2,
y = (bounds[0][1] + bounds[1][1]) / 2,
scale = .9 / Math.max(dx / width, dy / height),
translate = [width / 2 - scale * x, height / 2 - scale * y];
g.transition()
.duration(750)
.style("stroke-width", 1.5 / scale + "px")
.attr("transform", "translate(" + translate + ")scale(" + scale + ")");
}
function reset() {
active.classed("active", false);
active = d3.select(null);
g.transition()
.duration(750)
.style("stroke-width", "1.5px")
.attr("transform", "");
}
</script>
</body>
</html>
If anyone can help that would be great, or if the answer already exists on here could you please point me in the right direction
Thanks!
It would have helped if you included a picture of the effect you want.
That said, your CSS is simply not valid with SVG elements:
The first two have corresponding styles:
.globe {
fill:#fff;
stroke: #35C441;
stroke-width: 5;
}
Shadows, though, are a bit trickier.

Categories

Resources