Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/377.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.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 在交互式多系列折线图中使用brushed()时,为什么只有一条线被延长_Javascript_Svg_D3.js - Fatal编程技术网

Javascript 在交互式多系列折线图中使用brushed()时,为什么只有一条线被延长

Javascript 在交互式多系列折线图中使用brushed()时,为什么只有一条线被延长,javascript,svg,d3.js,Javascript,Svg,D3.js,我正在使用d3.js制作一个多系列的折线图,并试图实现如中所示的焦点和上下文缩放。我已将示例中的面积图转换为一个单一系列的折线图,但我无法理解为什么在使用笔刷扩展x域时,我的所有线都没有得到扩展x域和一行将根据新的x域范围进行扩展 这是我正在使用的代码 var margin = { top: 20, right: 200, bottom: 100, left: 100 }, margin2 = { t

我正在使用d3.js制作一个多系列的折线图,并试图实现如中所示的焦点和上下文缩放。我已将示例中的面积图转换为一个单一系列的折线图,但我无法理解为什么在使用笔刷扩展x域时,我的所有线都没有得到扩展x域和一行将根据新的x域范围进行扩展

这是我正在使用的代码

var margin = {
        top: 20,
        right: 200,
        bottom: 100,
        left: 100
    },
    margin2 = {
        top: 430,
        right: 10,
        bottom: 20,
        left: 100
    },
    height = 500 - margin.top - margin.bottom,
    height2 = 500 - margin2.top - margin2.bottom,
    legendPanel = {
        width: 80
    },
    width = 960 - margin.left - margin.right - legendPanel.width;

var data = [{
    "symbol": "Banker",
    "date": "20000112",
    "earnedpts": "30",
    "redeemedpts": "15"
}, {
    "symbol": "Banker",
    "date": "20000810",
    "earnedpts": "10",
    "redeemedpts": "8"
}, {
    "symbol": "Banker",
    "date": "20010618",
    "earnedpts": "50",
    "redeemedpts": "20"
}, {
    "symbol": "Banker",
    "date": "20011220",
    "earnedpts": "40",
    "redeemedpts": "20"
}, {
    "symbol": "Banker",
    "date": "20020220",
    "earnedpts": "30",
    "redeemedpts": "20"
}, {
    "symbol": "Banker",
    "date": "20021130",
    "earnedpts": "10",
    "redeemedpts": "5"
}, {
    "symbol": "Health",
    "date": "20000112",
    "earnedpts": "20",
    "redeemedpts": "15"
}, {
    "symbol": "Health",
    "date": "20000810",
    "earnedpts": "40",
    "redeemedpts": "28"
}, {
    "symbol": "Health",
    "date": "20010618",
    "earnedpts": "30",
    "redeemedpts": "20"
}, {
    "symbol": "Health",
    "date": "20011220",
    "earnedpts": "60",
    "redeemedpts": "35"
}, {
    "symbol": "Health",
    "date": "20020220",
    "earnedpts": "30",
    "redeemedpts": "25"
}, {
    "symbol": "Health",
    "date": "20021130",
    "earnedpts": "20",
    "redeemedpts": "15"
}, {
    "symbol": "Govt",
    "date": "20000112",
    "earnedpts": "80",
    "redeemedpts": "65"
}, {
    "symbol": "Govt",
    "date": "20000810",
    "earnedpts": "60",
    "redeemedpts": "48"
}, {
    "symbol": "Govt",
    "date": "20010618",
    "earnedpts": "60",
    "redeemedpts": "40"
}, {
    "symbol": "Govt",
    "date": "20011220",
    "earnedpts": "30",
    "redeemedpts": "15"
}, {
    "symbol": "Govt",
    "date": "20020220",
    "earnedpts": "40",
    "redeemedpts": "25"
}, {
    "symbol": "Govt",
    "date": "20021130",
    "earnedpts": "30",
    "redeemedpts": "5"
}, {
    "symbol": "BPO",
    "date": "20000112",
    "earnedpts": "70",
    "redeemedpts": "45"
}, {
    "symbol": "BPO",
    "date": "20000810",
    "earnedpts": "60",
    "redeemedpts": "30"
}, {
    "symbol": "BPO",
    "date": "20010618",
    "earnedpts": "40",
    "redeemedpts": "25"
}, {
    "symbol": "BPO",
    "date": "20011220",
    "earnedpts": "70",
    "redeemedpts": "50"
}, {
    "symbol": "BPO",
    "date": "20020220",
    "earnedpts": "40",
    "redeemedpts": "25"
}, {
    "symbol": "BPO",
    "date": "20021130",
    "earnedpts": "50",
    "redeemedpts": "30"
}];

var parsedate = d3.time.format("%Y%m%d").parse;
var x = d3.time.scale().range([0, width]);
x2 = d3.time.scale()
    .range([0, width]);
var y = d3.scale.linear().range([height, 0]);
y2 = d3.scale.linear().range([height2, 0]);

var xAxis = d3.svg.axis().scale(x)
    .orient("bottom");

var xAxis2 = d3.svg.axis()
    .scale(x2)
    .orient("bottom");

var yAxis = d3.svg.axis().scale(y)
    .orient("left");

var color = d3.scale.ordinal()
    .range(["#04b0ff", "#04ffa8", "#ff5404", "#8a89a6", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

var brush = d3.svg.brush()
    .x(x2)
    .on("brush", brushed);

var extent = brush.extent();
var rangeExtent = [x2(extent[0]), x2(extent[1])];
var rangeWidth = rangeExtent[1] - rangeExtent[0];

var priceline1 = d3.svg.line()
    .x(function(d) {
        return x(d.date);
    })
    .y(function(d) {
        return y(d.earnedpts);
    })
    .interpolate("linear");

var priceline2 = d3.svg.line()
    .x(function(d) {
        return x(d.date);
    })
    .y(function(d) {
        return y(d.redeemedpts);
    })
    .interpolate("linear");

var svg = d3.select("body")
    .append("svg")
    .attr("width", width + margin.left + margin.right + legendPanel.width)
    .attr("height", height + margin.top + margin.bottom);

var focus = svg.append("g")
    .attr("class", "focus")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var context = svg.append("g")
    .attr("transform", "translate(" + margin2.left + "," + margin2.top + ")")
    .attr("class", "context");

svg.append("defs")
    .append("clipPath")
    .attr("id", "clip")
    .append("rect")
    .attr("width", width)
    .attr("height", height);

data.forEach(function(d) {
    d.date = parsedate(d.date);
    d.earnedpts = +d.earnedpts;
    d.redeemedpts = +d.redeemedpts;
});

x.domain(d3.extent(data, function(d) {
    return d.date;
}));
x2.domain(x.domain());
y.domain([0, d3.max(data, function(d) {
    return Math.max(d.earnedpts, d.redeemedpts);
})]);
y2.domain(y.domain());

var dataNest = d3.nest()
    .key(function(d) {
        return d.symbol;
    })
    .entries(data);

dataNest.forEach(function(d) {
    focus.append("path")
        .attr("class", "line")
        .style("stroke", function() {
            return d.color = color(d.key);
        })
        .attr("d", priceline1(d.values))
});

dataNest.forEach(function(d) {
    focus.append("path")
        .attr("class", "line")
        .style("stroke", function() {
            return d.color = color(d.key);
        })
        .style("stroke-dasharray", ("3, 3"))
        .attr("d", priceline2(d.values))
});

context.append("g")
    .attr("class", "x axis1")
    .attr("transform", "translate(0," + height2 + ")")
    .call(xAxis2);

var contextArea = d3.svg.area()
    .interpolate("monotone")
    .x(function(d) {
        return x2(d.date);
    })
    .y0(height2)
    .y1(0);

context.append("path")
    .attr("class", "area")
    .attr("d", contextArea(dataNest[0].values))
    .attr("fill", "#F1F1F2");

context.append("g")
    .attr("class", "x brush")
    .call(brush)
    .selectAll("rect")
    .attr("height", height2)
    .attr("fill", "#E6E7E8");

focus.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis)
    .append("text")
    .attr("x", -30)
    .attr("y", 6)
    .attr("dy", ".71em")
    .style("text-anchor", "end")
    .text("Days");

focus.append("g")
    .attr("class", "y axis")
    .call(yAxis)
    .append("text")
    .attr("transform", "rotate(-90)")
    .attr("x", 0)
    .attr("y", -40)
    .attr("dy", ".71em")
    .style("text-anchor", "end")
    .text("Average points Earned & Redeemed");


dataNest.forEach(function(d, i) {
    focus.append("text")
        .attr("transform", "translate(" + width + "," + y(data[dataNest[i].values.length + i * 6 - 1].earnedpts) + ")")
        .attr("dy", ".35em")
        .attr("text-anchor", "start")
        .style("fill", function() {
            return d.color = color(d.key);
        })
        .text(d.key);
});

focus.append("text")
    .attr("transform", "translate(" + (width - 20) + ",5)")
    .attr("dy", ".35em")
    .attr("text-anchor", "start")
    .style("fill", "black")
    .text("Points Earned");

focus.append("text")
    .attr("transform", "translate(" + (width - 20) + "," + (y(data[0].redeemedpts) - 245) + ")")
    .attr("dy", ".35em")
    .attr("text-anchor", "start")
    .style("fill", "black")
    .text("Points Redeemed");

function brushed() {
    x.domain(brush.empty() ? x2.domain() : brush.extent());
    focus.select(".x.axis").transition().call(xAxis);
    focus.select(".y.axis").transition().call(yAxis);
    dataNest.forEach(function(d) {
        focus.selectAll("path")
            .style("stroke", function() {
                return d.color = color(d.key);
            })
            .transition()
            .attr("d", priceline1(d.values))
    });
}

我认为这里有一些问题

首先,使用两种不同的线方法创建两种类型的线(虚线和实线)。那很好。但是,在最后的更新方法中,您选择了所有这些方法,并仅使用一种绘图方法(
priceline
)。我建议作出以下修改:

  • 将类标识符添加到每行,例如
    line1
    line2
    ,如下所示:

    dataNest.forEach(function (d) {
     focus.append("path")
       .attr("class", "line line1-" + d.key)
       .style("stroke", function () {
       return color(d.key);
     })
    .attr("d", priceline1(d.values));
    });
    
    // First define a formatting method such as
    var axisFormat = d3.time.format("%b")
    
    // Then apply your tickFormat to your scale
    var xAxis = d3.svg.axis()
                      .scale(x)
                      .orient("bottom")
                      .tickFormat(function(d) {
                          v=axisFormat(d); 
                          return v.substr(0,1) // you can adjust this.
                       });
    

  • 然后,在笔刷事件中,选择一个并更新行。(抱歉,我不知道您要更新哪一个,因此我已将它们都包括在内)

  • 小提琴是一种乐器

    关于您的比例格式,您可以使用
    tickFormat
    方法,如下所示:

    dataNest.forEach(function (d) {
     focus.append("path")
       .attr("class", "line line1-" + d.key)
       .style("stroke", function () {
       return color(d.key);
     })
    .attr("d", priceline1(d.values));
    });
    
    // First define a formatting method such as
    var axisFormat = d3.time.format("%b")
    
    // Then apply your tickFormat to your scale
    var xAxis = d3.svg.axis()
                      .scale(x)
                      .orient("bottom")
                      .tickFormat(function(d) {
                          v=axisFormat(d); 
                          return v.substr(0,1) // you can adjust this.
                       });
    

    希望这有帮助

    这是我的JSFIDLE链接我还有一个疑问..这里我用时间刻度()表示x轴。所以我在x轴上得到“2000年4月至7月…”但我的要求是在x轴上得到“2000 F M A M J A S O N D 2001 F”…如此以此类推..那么我如何才能得到x轴上每个月名字的第一个字母呢???嗨,我已经调整了我的答案。谢谢Nikos…但我真正想要的是月份的第一个字母,带有年边界,如“2000 F M A M J A S O N D 2001 F…等等”…但是如果我使用xaxis的tickFormat()中的任何函数,我不会得到“J F M A M J A S O N D…”这样的年边界…只有我得到的是月份名称。有人能帮我在x轴上获得上述格式(月份名称的第一个字母和年份边界)的代码吗…我已经尽了最大努力,但无法获得此格式…我认为这是不可行的。