【问题标题】:d3.js Box Plot Positioning Issue with box.jsd3.js box.js 的箱线图定位问题
【发布时间】:2017-03-01 20:45:10
【问题描述】:

我正在尝试将箱线图作为使用 d3 和 AngularJS 的数据可视化界面的一部分来实现。我正在使用这个箱线图包:https://bl.ocks.org/mbostock/4061502

但是,我无法确定示例代码的哪一部分控制箱形图的定位。在示例中,五个箱形图按顺序排列。当我尝试生成我的图时,它们都出现在彼此之上。

这是我用来生成箱线图的代码:

            boxplots = svg.selectAll("svg")
                .data(boxPlotData)
                .enter().append("svg")
                .attr("class", "box")
                .attr("width", boxWidth + margin.left + margin.right)
                .attr("height", boxHeight + margin.bottom + margin.top)
                .append("g")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
                .call(chart);

这是我的 svg 画布创建方式的代码。这是在一个角度指令中完成的:

template:"<svg width='825' height='600'></svg>",
    link: function($scope, elem){

        var d3 = $window.d3;
        var rawSvg=elem.find('svg'); // this is the svg created in the template

        var width = rawSvg[0].attributes[0].value;
        var height = rawSvg[0].attributes[1].value;

        var svg = d3.select(rawSvg[0]);

编辑:还不完美,但已经到了:

【问题讨论】:

  • 您创建的&lt;svg&gt; 元素的父元素是什么?请注意,在示例中,父元素是 HTML 元素而不是 SVG 元素。所以基本上他们为每个盒子创建了一个单独的图像,它们会自动放置在彼此旁边。
  • 我用创建我的 SVG 画布的代码更新了我的原始帖子。由于我有一个 SVG 元素作为箱形图的父元素,因此它们似乎都只是默认为 (0, 0) 的起始位置。我假设我需要将它们翻译到正确的位置?那个代码去哪儿了?它们都是同时创建的,所以我不知道如何给它们不同的翻译坐标。

标签: javascript angularjs d3.js boxplot


【解决方案1】:

您需要一个序数比例来定位父 svg 中框的 svg 元素。假设 width 代表您的父 svg 元素的宽度,data 是您的数据元素的数组,您可以使用它来创建比例:

const x = d3.scaleBand()
              .range( [0, width] )
              .domain( data.map( (el,i) => i ) );

现在可以在创建 svg 时使用

boxplots = svg.selectAll("svg")
                .data(boxPlotData)
                .enter().append("svg")
                .attr( "x", (d,i) => x(i) ) // this is added
                .attr("class", "box")
                .attr("width", boxWidth + margin.left + margin.right)
                .attr("height", boxHeight + margin.bottom + margin.top)
                .append("g")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
               .call(chart);

PS:这假设您使用 d3js 的 v4。 v3 中用于刻度的语法不同。

PPS:我目前无法测试代码,但它应该像描述的那样工作。

【讨论】:

  • 我在你的代码中添加了。需要一些调整——每个箱线图的宽度由一个变量定义(boxWidth,现在应该是 80 像素),所以它们至少需要移动这么多。如果我玩一下,我相信我可以得到它。
  • 后续问题:我可以使用 scaleBand 创建两组不同的箱线图吗?最终,我需要四个地块,屏幕两侧各有两个。
  • 我明天再试一次。我目前没有时间。
  • 奇怪的是,将域上的最大值设置为大约 10000 个空格,框会正确绘制。设置 x 属性允许添加标量值。奇怪的是,将附加值设置为 width/2 会将箱形图放置在 SVG 的大约 3/4 处,而不是一半处。将偏移设置为 300 像素似乎可以解决问题。我想知道为什么会这样
  • 我在 jsfiddle.net/cLeqx2eh/1 为我的代码创建了一个小小提琴。它还没有包括实际的箱线图,而是在每个波段中间的一条线。似乎工作得很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多