javascript - D3 Scatterplot from all circles to different shapes - Stack Overflow

I am trying to learn D3 and am looking at this example: What I want to do now is change the shape of th

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 0
Add a ment  | 

1 Answer 1

Reset to default 5

First, 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条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信