为了账号安全,请及时绑定邮箱和手机立即绑定

如何使这个 D3 水平条形图工作?

如何使这个 D3 水平条形图工作?

杨__羊羊 2021-12-02 19:59:41
最近我开始学习 D3.js v5,我必须制作不同类型的图表。其中一个图形是堆叠的水平条形图。我在 Udemy 中学习了一个教程,但我无法使此图表正常工作。有人可以帮我吗?所以,我知道 d3 使用堆栈生成器来生成堆积条形图。我使用它并检查控制台中的值似乎数据格式很好并且可以开始生成堆积条形图但我似乎无法理解为什么它不起作用。<html><script src="https://d3js.org/d3.v5.min.js"></script><body></body><script type="text/javascript">var Margin = {top: 30, right: 20, bottom: 40, left: 110};var InnerWidth = 432 - Margin.left - Margin.right;var InnerHeight = 432 - Margin.top - Margin.bottom;var diff_variant=[{Missense_Mutation: 5, Silent: 4, Splice_Site: 0},      {Missense_Mutation: 8, Splice_Site: 0, Silent: 0},      {Splice_Site: 4, Missense_Mutation: 4, Silent: 0},      {Missense_Mutation: 4, Silent: 1, Splice_Site: 0},      {Missense_Mutation: 5, Splice_Site: 0, Silent: 0},      {Missense_Mutation: 5, Splice_Site: 0, Silent: 0},      {Missense_Mutation: 4, Splice_Site: 0, Silent: 0},      {Missense_Mutation: 4, Splice_Site: 0, Silent: 0},      {Silent: 1, Missense_Mutation: 1, Splice_Site: 0},      {Missense_Mutation: 1, Splice_Site: 0, Silent: 0}];var data1=[{name: "Missense_Mutation", count: 41},           {name: "Silent", count: 6},           {name: "Splice_Site", count: 4}];var variant_name=["Missense_Mutation", "Splice_Site", "Silent"];var stack = d3.stack().keys(variant_name);var x = d3.scaleLinear()          .domain([0, d3.max(data1, function(d){return d.count;})])          .range([0,InnerWidth]);var x_axis = d3.scaleLinear()               .domain([0, d3.max(data1, function(d){return d.count;})])               .range([0,InnerWidth]);var y_axis = d3.scaleLinear()               .domain([0, data1.length])               .range([0,InnerWidth]);var y = d3.scaleBand()          .domain(data1.map(function(d){return d.name;}))          .rangeRound([0,InnerHeight])          .padding(0.1);
查看完整描述

1 回答

?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

当你这样做...

var series = svg5.selectAll("g")//etc...

...您正在选择<g>SVG 中已经存在的元素(两个轴)并将数据绑定到它们。这就是为什么您的输入选择为空的原因。

您可以选择null在此处阅读更多相关信息):

var series = svg5.selectAll(null)

或者您可以按类别选择,稍后在输入选择中设置:

var series = svg5.selectAll(".foo")

但是,最好的解决方案是将轴组移到底部:这不仅可以解决您的问题,而且还会在矩形上方绘制轴。

这是带有该更改的代码:

<html>

  <script src="https://d3js.org/d3.v5.min.js"></script>


  <body></body>



  <script type="text/javascript">

    var Margin = {

      top: 30,

      right: 20,

      bottom: 40,

      left: 110

    };

    var InnerWidth = 432 - Margin.left - Margin.right;

    var InnerHeight = 432 - Margin.top - Margin.bottom;

    var diff_variant = [{

        Missense_Mutation: 5,

        Silent: 4,

        Splice_Site: 0

      },

      {

        Missense_Mutation: 8,

        Splice_Site: 0,

        Silent: 0

      },

      {

        Splice_Site: 4,

        Missense_Mutation: 4,

        Silent: 0

      },

      {

        Missense_Mutation: 4,

        Silent: 1,

        Splice_Site: 0

      },

      {

        Missense_Mutation: 5,

        Splice_Site: 0,

        Silent: 0

      },

      {

        Missense_Mutation: 5,

        Splice_Site: 0,

        Silent: 0

      },

      {

        Missense_Mutation: 4,

        Splice_Site: 0,

        Silent: 0

      },

      {

        Missense_Mutation: 4,

        Splice_Site: 0,

        Silent: 0

      },

      {

        Silent: 1,

        Missense_Mutation: 1,

        Splice_Site: 0

      },

      {

        Missense_Mutation: 1,

        Splice_Site: 0,

        Silent: 0

      }

    ];


    var data1 = [{

        name: "Missense_Mutation",

        count: 41

      },

      {

        name: "Silent",

        count: 6

      },

      {

        name: "Splice_Site",

        count: 4

      }

    ];


    var variant_name = ["Missense_Mutation", "Splice_Site", "Silent"];


    var stack = d3.stack().keys(variant_name);


    var x = d3.scaleLinear()

      .domain([0, d3.max(data1, function(d) {

        return d.count;

      })])

      .range([0, InnerWidth]);


    var x_axis = d3.scaleLinear()

      .domain([0, d3.max(data1, function(d) {

        return d.count;

      })])

      .range([0, InnerWidth]);


    var y_axis = d3.scaleLinear()

      .domain([0, data1.length])

      .range([0, InnerWidth]);


    var y = d3.scaleBand()

      .domain(data1.map(function(d) {

        return d.name;

      }))

      .rangeRound([0, InnerHeight])

      .padding(0.1);


    var svg5 = d3.select("body").append("svg")

      .attr("preserveAspectRatio", "xMinYMin meet")

      .attr("viewBox", `0 0 ${InnerWidth + Margin.left + Margin.right} ${InnerHeight + Margin.top + Margin.bottom}`)

      .style("background", "lightblue")

      .append("g")

      .attr("transform", "translate(" + Margin.left + "," + Margin.top + ")");


    var series = svg5.selectAll("g").data(stack(diff_variant))

      .enter().append("g")

      .style("fill", (d, i) => d3.schemeSet3[i]);


    series.selectAll("rect").data(function(d) {

        return d;

      })

      .enter().append("rect")

      .attr("height", 25)

      .attr("width", function(d) {

        return x(d[1]) - x(d[0]);

      })

      .attr("x", function(d) {

        return x(d[0]);

      })

      .attr("y", function(d, i) {

        return i * 40;

      });


    svg5.append("g").style("font", "12px sans").call(d3.axisLeft(y));

    svg5.append("g").attr('transform', `translate(0, ${InnerHeight})`).style("font", "12px times").call(d3.axisBottom(x_axis));


  </script>


</html>



查看完整回答
反对 回复 2021-12-02
  • 1 回答
  • 0 关注
  • 171 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信