gpt4 book ai didi

javascript - D3刷分组条形图

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:50:26 25 4
gpt4 key购买 nike

我正在尝试使刷亮工作类似于此示例,但使用分组条形图:http://bl.ocks.org/mbostock/1667367

我真的不太了解刷牙的工作原理(我一直找不到任何好的教程),所以我对出了什么问题有点不知所措。我将尝试在下面包含相关的代码。该图表按天跟踪修复损坏构建的时间,然后按投资组合分组。到目前为止,画笔已创建,用户可以移动和拖动它,但主图表中的条形图被奇怪地重新绘制并且 x 轴根本没有更新。您能提供的任何帮助将不胜感激。谢谢。

// x0 is the time scale on the X axis
var main_x0 = d3.scale.ordinal().rangeRoundBands([0, main_width-275], 0.2);
var mini_x0 = d3.scale.ordinal().rangeRoundBands([0, main_width-275], 0.2);

// x1 is the portfolio scale on the X axis
var main_x1 = d3.scale.ordinal();
var mini_x1 = d3.scale.ordinal();

// Define the X axis
var main_xAxis = d3.svg.axis()
.scale(main_x0)
.tickFormat(dateFormat)
.orient("bottom");

var mini_xAxis = d3.svg.axis()
.scale(mini_x0)
.tickFormat(dateFormat)
.orient("bottom");

绑定(bind)数据后...

// define the axis domains
main_x0.domain(data.result.map( function(d) { return d.date; } )
.sort(d3.ascending));
mini_x0.domain(data.result.map( function(d) { return d.date; } )
.sort(d3.ascending));

main_x1.domain(data.result.map( function(d) { return d.portfolio; } )
.sort(d3.ascending))
.rangeRoundBands([0, main_x0.rangeBand() ], 0);
mini_x1.domain(data.result.map( function(d) { return d.portfolio; } )
.sort(d3.ascending))
.rangeRoundBands([0, main_x0.rangeBand() ], 0);

// Create brush for mini graph
var brush = d3.svg.brush()
.x(mini_x0)
.on("brush", brushed);

添加轴等后

// Create the bars
var bar = main.selectAll(".bars")
.data(nested)
.enter().append("g")
.attr("class", function(d) { return d.key + "-group bar"; })
.attr("fill", function(d) { return color(d.key); } );

bar.selectAll("rect").append("rect")
.data(function(d) { return d.values; })
.enter().append("rect")
.attr("class", function(d) { return d.portfolio; })
.attr("transform", function(d) { return "translate(" + main_x0(d.date) + ",0)"; })
.attr("width", function(d) { return main_x1.rangeBand(); })
.attr("x", function(d) { return main_x1(d.portfolio); })
.attr("y", function(d) { return main_y(d.buildFixTime); })
.attr("height", function(d) { return main_height - main_y(d.buildFixTime); });

这里是画笔功能(尝试几个不同的选项)...

function brushed() {
main_x1.domain(brush.empty() ? mini_x1.domain() : brush.extent());

//main.select("rect")
//.attr("x", function(d) { return d.values; })
//.attr("width", function(d) { return d.values; });
bar.select("rect")
.attr("width", function(d) { return main_x1.rangeBand(); })
.attr("x", function(d) { return main_x1(d.portfolio); });
//.attr("y", function(d) { console.log(d); return main_y(d.buildFixTime); })
//.attr("height", function(d) { return main_height - main_y(d.buildFixTime); });

main.select(".x.axis").call(main_xAxis);
}

最佳答案

问题来自尝试使用笔刷设置 x 尺度域,而您的 x 尺度是序数尺度。换句话说,您的 x 轴的预期域是类别列表,而不是最大-最小数值范围。所以问题就出在刷机功能的最上面:

function brushed() {
main_x0.domain(brush.empty() ? mini_x0.domain() : brush.extent());

brush.extent()设置的域是一个由两个数字组成的数组,然后它会完全摆脱您的序数比例。

According to the wiki , 如果附加到画笔函数的尺度之一是序数尺度,brush.extent() 返回的值是输出范围内的值,而不是输入域内的值。 Ordinal scales don't have an invert() method将范围值转换为域值。

因此,您有几个关于如何进行的选择:

您可以为您的主要 x 轴使用线性时间尺度而不是顺序尺度来重新绘制整个图表。但是你必须编写自己的函数来计算该轴上每一天的宽度,而不是能够使用 .rangeBand() .

您可以创建自己的“反转”函数来确定哪些分类值(mini_x0.domain 上的日期)包含在 brush.extent() 返回的范围内.然后你将不得不两者重置main_x0.domain为了仅在轴上包含那些日期,过滤掉您的矩形以仅绘制这些矩形。

或者您可以离开main_x0.是,并改为更改范围。通过扩大图表的范围,您可以将条形间隔得更大。结合剪切路径以切断绘图区域外的条形图,这具有仅显示特定条形图子集的效果,这正是您想要的。

但是新范围应该是多少? brush.extent() 返回的范围是刷涂矩形的开始和结束位置。如果您将这些值用作主图上的范围,则整个图将被压缩到该宽度。这与你想要的相反。您想要的是最初填充该宽度的图形区域被拉伸(stretch)以填充整个绘图区域。

因此,如果您原来的 x 范围是从 [0,100] 开始,而画笔覆盖了区域 [20,60],那么您需要一个满足这些条件的新范围:

  • 新范围宽度的 20% 标记为 0;
  • 新范围宽度的 60% 标记为 100。

因此,

  • 新范围的总宽度为 ( (100-0)/(60-20) )*(100-0) = 250;
  • 新范围的起点是 (0 - (20/100)*250) = -50;
  • 新范围的终点是 (-50) + 250 = 200。

现在您可以自己计算所有代数来计算此转换。但这实际上只是另一种比例方程,所以为什么不创建一个比例函数来在旧范围和放大范围之间进行转换。

具体来说,我们需要一个线性刻度,其输出范围设置为绘图区域的实际范围。然后根据我们要拉伸(stretch)覆盖绘图区域的画笔区域范围设置domain。最后,我们通过使用线性刻度计算出范围的原始最大值和最小值离屏幕有多远,从而计算出序数刻度的范围。从那里,我们可以调整其他序号的大小并重新定位所有矩形。

在代码中:

//Initialization:
var main_xZoom = d3.scale.linear()
.range([0, main_width - 275])
.domain([0, main_width - 275]);

//Brushing function:
function brushed() {
var originalRange = main_xZoom.range();
main_xZoom.domain(brush.empty() ?
originalRange:
brush.extent() );

main_x0.rangeRoundBands( [
main_xZoom(originalRange[0]),
main_xZoom(originalRange[1])
], 0.2);

main_x1.rangeRoundBands([0, main_x0.rangeBand()], 0);

bar.selectAll("rect")
.attr("transform", function (d) {
return "translate(" + main_x0(d.date) + ",0)";
})
.attr("width", function (d) {
return main_x1.rangeBand();
})
.attr("x", function (d) {
return main_x1(d.portfolio);
});

main.select("g.x.axis").call(main_xAxis);
}

基于简化代码的工作 fiddle (注意:您仍然需要在主图上设置一个剪辑矩形):
http://fiddle.jshell.net/CjaD3/1/

关于javascript - D3刷分组条形图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21485339/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com