简体   繁体   English

D3中的嵌套图和折线图

[英]Nested plot and line graph in d3

I have the correct plot graph with the correlating colors. 我有正确的绘图图和相关的颜色。 However, I am supposed to connect each plot with a line. 但是,我应该将每个图用一条线连接起来。 There are two groups of plots. 有两组情节。 So there will be two separate line groups (otherwise known as being nested). 因此,将有两个单独的线组(也称为嵌套)。 I'm not sure how to go about that. 我不确定该怎么做。

<!DOCTYPE html>
<html>
 <head>
<meta charset="utf-8">
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3-legend/1.1.0/d3-legend.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3-tip/0.6.3/d3-tip.min.js"></script>
   <style>
    h1 { border-bottom: solid 3px #EBEBED; color: #545c61; font-size: 20px; padding-left: 35px; font-family: sans-serif; padding-bottom: 17px; font-weight: 500; margin-bottom: 37px; padding-top: 8px;}

    circle{ fill:white; stroke-width: 3px;}

    path { stroke: red; stroke-width: 2; fill: none; }

    .axis text {
    font-family: 'Open Sans', sans-serif;
    font-size: 14pt;
  }

  .axis path, .axis line {
    fill: none;
    stroke: none;
    shape-rendering: crispEdges;
  }
    .y.axis { stroke: #babfc5; }
    .y.axis text{ font-weight:100; transform: translate(-24px,0px); }
    .y.axis line { stroke: #EBEBED; stroke-width: 2; }
    .x.axis { stroke: #8e8e8e; }
    .x.axis text{ font-weight: 500; transform:translate(0px,14px)}


  </style>
 </head>
  <body>
  <h1>Example</h1>
<script>
    var outerWidth = 1080;
    var outerHeight = 330;
    var margin = { left: 190, top: 30, right: 30, bottom: 40 };
    var padding = 1.0;
    var circleRadius = 8;
    var xColumn = "month";
    var yColumn = "amount";
    var colorColumn = "monthv";
    var yAxisTitlesOffset = { top: 10 }


    var innerWidth = outerWidth - margin.left - margin.right;
    var innerHeight = outerHeight - margin.top - margin.bottom;



  var svg = d3.select("body").append("svg")
    .attr("width", outerWidth)
    .attr("height", outerHeight);
  var g = svg.append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
  var xAxisG = g.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + innerHeight + ")");
  var yAxisG = g.append("g")
    .attr("class", "y axis");




    var xScale = d3.scale.ordinal()
        .rangeBands([0, innerWidth],padding);
    var yScale = d3.scale.linear()
        .range([innerHeight,0]);
    var colorScale = d3.scale.ordinal()
        .domain(["top", "bot"])
        .range(["#43B365", "#DA5A60" ])




    var xAxis = d3.svg.axis().scale(xScale).orient("bottom")
    .outerTickSize(0);          // Turn off the marks at the end of the axis.
    var yAxis = d3.svg.axis().scale(yScale).orient("left")
    .ticks(4)            
    .tickSize(-innerWidth)
    .outerTickSize(0)
    .tickFormat( function(d) { return "$" + d} );

    var format = d3.format(",");
    var formattedX = format(yAxis);



    function render(data){

        xScale.domain(       data.map( function (d){ return d[xColumn]; }));
        yScale.domain([0, 2000]);
        //if this code is inserted in the max value instead of 2000 - it will show the max data value d3.max(data, function (d){ return d[yColumn]; })
        xAxisG.call(xAxis);
        yAxisG.call(yAxis);

        svg.append("path")
        .attr("class", "line")
        .attr("d", valueline(data));

        //bind data
        var circles = g.selectAll("circle").data(data);
        //Enter
        circles.enter().append("circle")
            .attr("r", circleRadius);
        //update
        circles
            .attr("cx", function (d){ return xScale(d[xColumn]); })
            .attr("cy", function (d){ return yScale(d[yColumn]); })
            .style("stroke", function (d){ return  colorScale(d[colorColumn]); })
        //exit 
        circles.exit().remove();
    }




  function type(d){
    d.amount = +d.amount;
    return d;
  }

  var data = [
    {
      "month": "Jan",
      "monthv": "top",
      "amount": 400
    },
    {
      "month": "Jan",
      "monthv": "bot",
      "amount": 100
    },
    {
      "month": "Feb",
      "monthv": "top",
      "amount": 800
    },
    {
      "month": "Feb",
      "monthv": "bot",
      "amount": 250
    },
    {
      "month": "Mar",
      "monthv": "top",
      "amount": 750
    },
    {
      "month": "Mar",
      "monthv": "bot",
      "amount": 200
    },
    {
      "month": "Apr",
      "monthv": "top",
      "amount": 850
    },
      {
      "month": "Apr",
      "monthv": "bot",
      "amount": 250
    },
    {
      "month": "May",
      "monthv": "top",
      "amount": 800
    },
      {
      "month": "May",
      "monthv": "bot",
      "amount": 250
    },
    {
      "month": "Jun",
      "monthv": "top",
      "amount": 850
    },
      {
      "month": "Jun",
      "monthv": "bot",
      "amount": 250
    },
    {
      "month": "Jul",
      "monthv": "top",
      "amount": 1000
    },
      {
      "month": "Jul",
      "monthv": "bot",
      "amount": 300
    },
    {
      "month": "Aug",
      "monthv": "top",
      "amount": 1050
    },
    {
      "month": "Aug",
      "monthv": "bot",
      "amount": 300
    },
    {
      "month": "Sep",
      "monthv": "top",
      "amount": 1000
    },
    {
      "month": "Sep",
      "monthv": "bot",
      "amount": 300
    },
    {
      "month": "Oct",
      "monthv": "top",
      "amount": 1200
    },
    {
      "month": "Oct",
      "monthv": "bot",
      "amount": 300
    },
    {
      "month": "Nov",
      "monthv": "top",
      "amount": 1100
    },
    {
      "month": "Nov",
      "monthv": "bot",
      "amount": 250
    },
    {
      "month": "Dec",
      "monthv": "top",
      "amount": 1250
    },
    {
      "month": "Dec",
      "monthv": "bot",
      "amount": 250
    }
  ];

  render(data);
</script>
</body>
</html>

I would like something to look like this http://bl.ocks.org/d3noob/38744a17f9c0141bcd04 . 我想看起来像这样http://bl.ocks.org/d3noob/38744a17f9c0141bcd04 However when I define the line in my code and it to the path, I am getting an error. 但是,当我在代码中定义该行并将其定义到路径时,出现了错误。 Not sure how to go about this. 不知道如何去做。

First, you have to separate the data for the two lines. 首先,您必须将两行的数据分开。 There are several ways for doing that. 有几种方法可以做到这一点。 Here, I'm using a filter : 在这里,我正在使用filter

var dataTop = data.filter(function(d){ return d.monthv == "top"});
var dataBot = data.filter(function(d){ return d.monthv == "bot"});

Then, you use this data for each line: 然后,将这些数据用于每一行:

g.append("path").attr("d", valueline(dataTop));
g.append("path").attr("d", valueline(dataBot));

I'm using this solution because you have only 2 lines. 我正在使用此解决方案,因为您只有2行。 If you have several lines, a different approach could be better (unless you want a lot of redundant code). 如果您有多行代码,则不同的方法可能更好(除非您想要大量的冗余代码)。

Here is your fiddle: https://jsfiddle.net/jh3foyn6/ 这是您的小提琴: https : //jsfiddle.net/jh3foyn6/

You forgot to define valueline, the path generator: d3.svg.line : 您忘记定义值线,即路径生成器: d3.svg.line

var valueline = d3.svg.line()
    .x(function(d) { return xScale(d[xColumn]); })
    .y(function(d) { return yScale(d[yColumn]); });

Note for the way your data is defined, you need to call the path generator twice filtering the data for the top line and for the bottom line.You could also prepare the data to have one object for each month with values for the top and bottom line: 请注意,对于数据的定义方式,您需要调用路径生成器两次,以对顶行和底行的数据进行过滤。您还可以准备将​​数据设置为每个月有一个对象,并在顶部和底部使用值线:

g.append("path")
.attr("class", "line")
.attr("d", valueTopline(data.filter( e => e[colorColumn] === "top")))
.style("stroke", colorScale("top"));

g.append("path")
.attr("class", "line")
.attr("d", valueTopline(data.filter( e => e[colorColumn] === "bot")))
.style("stroke", colorScale("bot"));

You also need to append the paths to the group <g> instead of appending direct to the svg for the scales to match. 您还需要将路径附加到组<g>而不是直接附加到svg以便比例匹配。

Here is the updated jsbin code : 这是更新的jsbin代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM