Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 调整发散堆积条形图以使用通用更新模式_Javascript_D3.js - Fatal编程技术网

Javascript 调整发散堆积条形图以使用通用更新模式

Javascript 调整发散堆积条形图以使用通用更新模式,javascript,d3.js,Javascript,D3.js,我一直在使用具有以下代码的堆叠条形图示例: var data = [ {month: "Q1-2016", apples: 3840, bananas: 1920, cherries: -1960, dates: -400}, {month: "Q2-2016", apples: 1600, bananas: 1440, cherries: -960, dates: -400}, {month: "Q3-2016", apples: 640, bananas: 960, cher

我一直在使用具有以下代码的堆叠条形图示例:

var data = [
  {month: "Q1-2016", apples: 3840, bananas: 1920, cherries: -1960, dates: -400},
  {month: "Q2-2016", apples: 1600, bananas: 1440, cherries: -960, dates: -400},
  {month: "Q3-2016", apples:  640, bananas:  960, cherries: -640, dates: -600},
  {month: "Q4-2016", apples:  320, bananas:  480, cherries: -640, dates: -400}
];

var series = d3.stack()
    .keys(["apples", "bananas", "cherries", "dates"])
    .offset(d3.stackOffsetDiverging)
    (data);

var svg = d3.select("svg"),
    margin = {top: 20, right: 30, bottom: 30, left: 60},
    width = +svg.attr("width"),
    height = +svg.attr("height");

var x = d3.scaleBand()
    .domain(data.map(function(d) { return d.month; }))
    .rangeRound([margin.left, width - margin.right])
    .padding(0.1);

var y = d3.scaleLinear()
    .domain([d3.min(series, stackMin), d3.max(series, stackMax)])
    .rangeRound([height - margin.bottom, margin.top]);

var z = d3.scaleOrdinal(d3.schemeCategory10);

svg.append("g")
  .selectAll("g")
  .data(series)
  .enter().append("g")
    .attr("fill", function(d) { return z(d.key); })
  .selectAll("rect")
  .data(function(d) { return d; })
  .enter().append("rect")
    .attr("width", x.bandwidth)
    .attr("x", function(d) { return x(d.data.month); })
    .attr("y", function(d) { return y(d[1]); })
    .attr("height", function(d) { return y(d[0]) - y(d[1]); })

svg.append("g")
    .attr("transform", "translate(0," + y(0) + ")")
    .call(d3.axisBottom(x));

svg.append("g")
    .attr("transform", "translate(" + margin.left + ",0)")
    .call(d3.axisLeft(y));

function stackMin(serie) {
  return d3.min(serie, function(d) { return d[0]; });
}

function stackMax(serie) {
  return d3.max(serie, function(d) { return d[1]; });
}
示例中的代码不支持转换或重画,所以我一直在尝试将的原则应用于它,以便在我的应用程序中使用它

我不熟悉D3v4,而“附件”的性质让我感到困惑。我在同一个append方法链中看到两个“enter”,因此我尝试将它们分离到各自的声明中,如:

var join1 = .selectAll("g")
      .data(series)

var join2Update = .selectAll("rect")
      .data(function(d) { return d; })

var join2Enter= join2.enter()

join2Enter
 .append("rect")
 .merge(join2Update)
 .transition()
 .attr("width", x.bandwidth)
 .attr("x", function(d) { return x(d.data.month); })
 .attr("y", function(d) { return y(d[1]); })
 .attr("height", function(d) { return y(d[0]) - y(d[1]); })

但除了打破图表,它没什么作用!坦白地说,我对整个过程有点茫然,任何帮助都将不胜感激。

我对您的代码做了一些修改,以使其可更新,我将指出我所做的一些修改,如果还有什么不清楚的地方,您可以问

我更改的主要内容是,为了简单起见,在数据集中我们有两个类别,这样我们就可以根据这样的输入更新数据

var keys = ["apples" + input, "bananas" + input];
d3.selectAll(".opt").on("change", function() {
    update(data, this.value)
})
这里的输入变量最初是这样选择的

var input = d3.selectAll(".opt").property("value");
当我们手动更新它时,我们会得到这样的新数据

var keys = ["apples" + input, "bananas" + input];
d3.selectAll(".opt").on("change", function() {
    update(data, this.value)
})
我们创建了一个条形组来保存
系列
数据集,并在以后使用另一个变量引用它,而不是直接将g元素与rect一起添加

var barGroups = svg.selectAll("g.layer")
    .data(series);

barGroups.exit().remove();

barGroups.enter().insert("g", ".x-axis")
  .classed('layer', true);
下面是您前面提到的代码的更新模式部分:

var bars = svg.selectAll("g.layer").selectAll("rect")
  .data(function(d) { return d; });

bars.exit().remove();

bars = bars
    .enter()
.append("rect")
    .attr("width", x.bandwidth())
    .attr("x", d => x(d.data.month))
  .merge(bars)

bars.transition().duration(750)
    .attr("y", d => y(d[1]))
    .attr("height", d => Math.abs(y(d[0])) - y(d[1]));
应该就是这样,看看下面的代码片段,看看它是如何工作的

var数据=[
{月份:“2016年第一季度”,苹果1:400,香蕉1:920,苹果2:196,香蕉2:840},
{月份:“2016年第二季度”,苹果1:400,香蕉1:440,苹果2:960,香蕉2:600},
{月份:“2016年第三季度”,苹果1:-600,香蕉1:960,苹果2:-640,香蕉2:640},
{月份:“2016年第四季度”,苹果1:400,香蕉1:480,苹果2:640,香蕉2:320}
];
var margin={顶部:35,右侧:145,底部:35,左侧:45},
宽度=650-边距。左侧-边距。右侧,
高度=450-边距.顶部-边距.底部;
var svg=d3。选择(“图表”)
.attr(“宽度”,宽度+边距。左侧+边距。右侧)
.attr(“高度”,高度+边距。顶部+边距。底部)
.附加(“g”)
.attr(“转换”、“平移”(+margin.left+)、“+margin.top+”);
var x=d3.scaleBand()
.rangeRound([0,宽度])
.填充(0.1);
变量y=d3.scaleLinear()
.rangeRound([高度,0]);
var z=d3.scaleOrdinal()
.范围([“钢蓝”、“达科朗格”);
svg.append(“g”)
.attr(“类”、“x轴”);
svg.append(“g”)
.attr(“类”、“y轴”);
var输入=d3.selectAll(“.opt”).property(“value”);
d3.选择全部(“.opt”)。打开(“更改”,函数(){
更新(数据,此.value)
})
更新(数据、输入);
功能更新(数据、输入){
变量键=[“苹果”+输入,“香蕉”+输入];
var series=d3.stack()
.钥匙(钥匙)
.偏移(d3.堆栈偏移发散)
(数据);
x、 域(data.map(d=>d.month));
y、 领域([
d3.最小值(系列,最小值),
d3.max(系列,stackMax)
]).nice();
var barGroups=svg.selectAll(“g.layer”)
.数据(系列);
barGroups.exit().remove();
barGroups.enter().insert(“g”、“.x轴”)
.classed('层',真);
svg.selectAll(“g.layer”)
.transition().持续时间(750)
.attr(“填充”,d=>z(d.key));
var bar=svg.selectAll(“g.layer”).selectAll(“rect”)
.data(函数(d){返回d;});
bar.exit().remove();
钢筋=钢筋
.输入()
.append(“rect”)
.attr(“宽度”,x.带宽())
.attr(“x”,d=>x(d.data.month))
.合并(条)
bar.transition().持续时间(750)
.attr(“y”,d=>y(d[1]))
.attr(“height”,d=>Math.abs(y(d[0]))-y(d[1]);
svg.selectAll(“.x轴”).transition().持续时间(750)
.attr(“变换”、“平移(0)、+y(0)+”)
.call(d3.axisBottom(x));
svg.selectAll(“.y轴”).transition().持续时间(750)
.调用(d3.左(y));
函数stackMin(系列){
返回d3.min(序列,函数(d){返回d[0];});
}
函数stackMax(系列){
返回d3.max(序列,函数(d){返回d[1];});
}
}
正文{
保证金:自动;
宽度:850px;
}

挑选
1.
2.


这是一个极好的答案。谢谢你抽出时间来做这件事。我可以在代码中更清楚地看到更新模式的应用。不幸的是,我在转换方面遇到了问题,但这是因为我在一个Ember组件中实现了上述内容,这超出了原始问题的范围。@Abuelo没问题,很抱歉听到这个消息,我相信有人能够胜任Ember的工作,可以帮助您。