I am trying to learn D3 and am looking at this example:
What I want to do now is change the shape of the dots, so I want circles, squares, and triangles based on the brand of the cereal in the data set instead of all circles as datapoints. This seems like it should be a simple change, but I can't get the shapes to show up when I make my change.
I know that this change needs to be made in this segment of the code:
svg.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 3.5)
.attr("cx", xMap)
.attr("cy", yMap)
.style("fill", function(d) { return color(cValue(d));})
.on("mouseover", function(d) {
tooltip.transition()
.duration(200)
.style("opacity", .9);
tooltip.html(d["Cereal Name"] + "<br/> (" + xValue(d)
+ ", " + yValue(d) + ")")
.style("left", (d3.event.pageX + 5) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
tooltip.transition()
.duration(500)
.style("opacity", 0);
});
I need to change the append of the circle and the attributes. I want to use a conditional so
.attr("d", function(d,i) {if (d["Cereal Name"] == "Nabisco" return d3.svg.symbol().type("circle");
else if (d["Cereal Name"] == "Post" return d3.svg.symbol().type("triangle-down");
else return d3.svg.symbol().type("circle")
However, this is not working for me. Does anyone have an insight in how to do this? I don't want to have all circles, I want different shapes depending on the brand name of the cereal in the example. Thank you.
Edit: I tried looking at this:
Filter data in d3 to draw either circle or square
But I couldn't get this to work
I am trying to learn D3 and am looking at this example:
http://bl.ocks/weiglemc/6185069
What I want to do now is change the shape of the dots, so I want circles, squares, and triangles based on the brand of the cereal in the data set instead of all circles as datapoints. This seems like it should be a simple change, but I can't get the shapes to show up when I make my change.
I know that this change needs to be made in this segment of the code:
svg.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 3.5)
.attr("cx", xMap)
.attr("cy", yMap)
.style("fill", function(d) { return color(cValue(d));})
.on("mouseover", function(d) {
tooltip.transition()
.duration(200)
.style("opacity", .9);
tooltip.html(d["Cereal Name"] + "<br/> (" + xValue(d)
+ ", " + yValue(d) + ")")
.style("left", (d3.event.pageX + 5) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
tooltip.transition()
.duration(500)
.style("opacity", 0);
});
I need to change the append of the circle and the attributes. I want to use a conditional so
.attr("d", function(d,i) {if (d["Cereal Name"] == "Nabisco" return d3.svg.symbol().type("circle");
else if (d["Cereal Name"] == "Post" return d3.svg.symbol().type("triangle-down");
else return d3.svg.symbol().type("circle")
However, this is not working for me. Does anyone have an insight in how to do this? I don't want to have all circles, I want different shapes depending on the brand name of the cereal in the example. Thank you.
Edit: I tried looking at this:
Filter data in d3 to draw either circle or square
But I couldn't get this to work
Share Improve this question edited May 23, 2017 at 10:34 CommunityBot 11 silver badge asked Sep 29, 2016 at 3:06 Mr.RobotoMr.Roboto 1913 silver badges14 bronze badges 01 Answer
Reset to default 5First, you have to set the symbol
generator (in d3 v4.x):
var symbol = d3.symbol();
And then appending a path
element:
var dots = svg.selectAll(".dots")
.data(data)
.enter()
.append("path");
After that, it es the most important part: you have to specify the type
of your symbol generator. In the following demo, we can set the shape depending on the name
of the brand (I'm using a dataset about chocolate that i found online):
dots.attr("d", symbol.type(function(d){
if(d.name == "Lindt"){ return d3.symbolCross
} else if (d.name == "Bournville"){ return d3.symbolDiamond
} else if (d.name == "Dolfin"){ return d3.symbolSquare
} else if (d.name == "Hershey"){ return d3.symbolStar
} else if (d.name == "Galaxy"){ return d3.symbolTriangle
} else if (d.name == "Dairy Milk"){ return d3.symbolCircle
}}))
Of course, you could avoid that ugly bunch of if...else
defining the symbol type in the dataset itself, or just using an ordinal scale.
Check the working demo (using manufacturer
instead, to have fewer shapes):
var data = [{
"name": "Dairy Milk",
"manufacturer": "cadbury",
"price": 45,
"rating": 2
}, {
"name": "Galaxy",
"manufacturer": "Nestle",
"price": 42,
"rating": 3
}, {
"name": "Lindt",
"manufacturer": "Lindt",
"price": 80,
"rating": 4
}, {
"name": "Hershey",
"manufacturer": "Hershey",
"price": 40,
"rating": 1
}, {
"name": "Dolfin",
"manufacturer": "Lindt",
"price": 90,
"rating": 5
}, {
"name": "Bournville",
"manufacturer": "cadbury",
"price": 70,
"rating": 2
}];
var w = 300, h = 300;
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
var xScale = d3.scaleLinear().domain([0, d3.max(data, function(d){ return d.price})]).range([30,w*0.9]);
var yScale = d3.scaleLinear().domain([d3.max(data, function(d){ return d.rating})*1.1, 0]).range([10,h*0.9]);
var symbol = d3.symbol();
var dots = svg.selectAll(".dots")
.data(data)
.enter()
.append("path");
dots.attr("d", symbol.type(function(d){if(d.manufacturer == "Lindt"){ return d3.symbolCross} else if (d.manufacturer == "cadbury"){ return d3.symbolDiamond} else if (d.manufacturer == "Nestle"){ return d3.symbolSquare} else if (d.manufacturer == "Hershey"){ return d3.symbolStar} }))
.attr('fill', "teal")
.attr('stroke','#000')
.attr('stroke-width',1)
.attr('transform',function(d){ return "translate("+xScale(d.price)+","+yScale(d.rating)+")"; });
var xAxis = d3.axisBottom(xScale);
var yAxis = d3.axisLeft(yScale);
var gX = svg.append("g")
.call(xAxis)
.attr("transform", "translate(0," + w*0.9 + ")");
var gY = svg.append("g")
.call(yAxis)
.attr("transform", "translate(30,0)");
<script src="https://d3js/d3.v4.min.js"></script>
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745257128a4619023.html
评论列表(0条)