【问题标题】:add scrollbar and navigator, range selector functionality in d3.js在 d3.js 中添加滚动条和导航器、范围选择器功能
【发布时间】:2014-03-17 08:00:14
【问题描述】:

我想在我的折线图中包含滚动条和导航器、范围选择器功能。类似于 http://www.highcharts.com/products/highstock 的东西可以在 d3 上完成,如果可以的话,给我一个教程或代码的链接。

代码是

var margin = {top: 10, right: 10, bottom: 100, left: 40},
    margin2 = {top: 430, right: 10, bottom: 30, left: 40},
        width = 2000 - margin.left - margin.right,
        height = 500 - margin.top - margin.bottom,
        height2 = 500 - margin2.top - margin2.bottom;


var parseDate = d3.time.format("%Y-%m-%d").parse;
var formatTime = d3.time.format("%e %B");

var x = d3.time.scale().range([0, width]);
var x2= d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);
var y2 = d3.scale.linear().range([height2, 0]);

var xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(25);
var xAxis2 = d3.svg.axis().scale(x2).orient("bottom");

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

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


var valueline = d3.svg.line().defined(function(d) { return d.close != 0; }).x(function(d) { return x(d.date); }).y(function(d) { return y(d.close); });

var valueline2 = d3.svg.line().defined(function(d) { return d.close != 0; }).x(function(d) { return x2(d.date); }).y(function(d) { return y2(d.close); });

var brush = d3.svg.brush()
    .x(x2)
    .on("brush", brushed);
var svg = d3.select("body").append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom);



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

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


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

d3.json("data/data2.php", function(error, data) { data.forEach(function(d,i) {

    //document.write(d.date);
    d.date = parseDate(d.date);
    //document.write(d.date);
        d.close = +d.close;

    //document.write(d.close);
    arr[i]=d.close;


    len=i+1;


    });

// Scale the range of the data
    x.domain(d3.extent(data, function(d) { return d.date; }));
    y.domain([min-10, max+10]);
    x2.domain(x.domain());
     y2.domain(y.domain());

focus.append("path")        // Add the valueline path.
    .datum(data)
        .attr("class","valueline")
    .attr("d", valueline);

focus.selectAll("dot")
        .data(data)
    .enter().append("a")
    .attr("xlink:href",function(d,i){if(d.close>=usl||d.close<=lsl||signal8[i]==8||signal8dw[i]==8||signal6up[i]==6||signal6dw[i]==6)return "http://en.wikipedia.org";})
    .append("circle")
        .attr("r", 2)
    .style("fill", function(d,i) {            // <== Add these
        if(d.close==0) {return "none"}              
        if((ul[i]==9999)||(dl[i]==9999)) {return "red"}
        else if(signal8[i]==8 ){ return "orange" }
        else if(signal8dw[i]==8 ){return "gold"}
        else if(signal6up[i]==6 ){return "indianred"}
        else if(signal6dw[i]==6 ){return "#FF5C33"}
            else    { return "steelblue" }          // <== Add these
        ;})  
        .attr("cx", function(d) { return x(d.date); })
        .attr("cy", function(d) { return y(d.close); })
    .on("mouseover", function(d,i) {

            div.transition()        
                .duration(200)      
                .style("opacity", .9);      
                div.html(function(){
    if(d.close==0)
    {return}
    if(ul[i]==9999)
    {return formatTime(d.date) + "<br/><b>"  + d.close+ "</b><br/>"  + " UPPER "}
    else if(dl[i]==9999)
    {return formatTime(d.date) + "<br/><b>"  + d.close+ "</b><br/>"  + "  LOWER "}
    else if(signal8[i]==8)
    {return formatTime(d.date) + "<br/><b>"  + d.close+ "</b><br/>"  + " ( hello1 )"}
    else if(signal8dw[i]==8)
    {return formatTime(d.date) + "<br/><b>"  + d.close+ "</b><br/>"  + " ( hello1  )"}
    else if(signal6up[i]==6)
    {return formatTime(d.date) + "<br/><b>"  + d.close+ "</b><br/>"  + " ( hello1 )"}
    else if(signal6dw[i]==6)
    {return formatTime(d.date) + "<br/><b>"  + d.close+ "</b><br/>"  + " ( hello1 )"}
    else {return formatTime(d.date) + "<br/><b>"  + d.close+ "</b>"}
;})



context.append("path")      // Add the valueline path.
        .attr("d", valueline2(data));

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


context.append("g")
      .attr("class", "x brush")
      .call(brush)
    .selectAll("rect")
      .attr("y", -6)
      .attr("height", height2 + 7);
});


function brushed() {
  x.domain(brush.empty() ? x2.domain() : brush.extent());
  focus.select(".valueline").attr("d",valueline);
  focus.select(".x.axis").call(xAxis);
}

function type(d) {
  d.date = parseDate(d.date);
  d.close = +d.close;
  return d;
}

以上代码是整体代码的一个sn-p。这里当我执行我得到一个解析错误 d=""。我哪里错了。我在图中画了几条限制线,我没有包含在上面的代码中。底部画笔正在工作,但主图没有按照画笔更新。 我也想更新点。我应该包括什么刷功能。

【问题讨论】:

  • 您可以使用 d3 brush control 执行此操作。您可能希望从 this example 开始。
  • 这里画笔正在工作,但我的主折线图中的数据并没有按照滑块图发生变化。我认为有问题的代码是。功能刷过(){ x.domain(brush.empty()?x2.domain():brush.extent()); focus.select(".valueline").attr("d",valueline(data)); focus.select(".x.axis").call(xAxis); } 函数类型(d) { d.date = parseDate(d.date); d.close = +d.close;返回 d; }
  • 将 valueline 定义为 var valueline = d3.svg.line().defined(function(d) { return d.close != 0; }).x(function(d) { return x (d.date); }).y(function(d) { return y(d.close); });
  • @AmeliaBR 你能帮我解决这个问题吗stackoverflow.com/questions/22448936/…
  • Problem parsing d="" 是我开始使用滑块时遇到的错误

标签: d3.js line


【解决方案1】:

对于点标记,你又需要一个selectAll,然后重置cx属性以匹配修改后的x比例:

function brushed() {
  x.domain(brush.empty() ? x2.domain() : brush.extent()); 
     //change the x-scale on the focus graph to match the brush extent
     //(or reset it to the full domain if the brush is empty)

  focus.selectAll(".valueline").attr("d",valueline); 
    // redraw the lines (using the updated scale)

  focus.selectAll("dot").select("circle")
     .attr("cx", function(d) { return x(d.date); });
    //update the x position of the dots based on the updated x-scale

  focus.select(".x.axis").call(xAxis); 
   //redraw the x-axis based on the updated x-scale
}

【讨论】:

  • 在包含 selectAll("dot") 行代码后它没有改变。点保持在相同的位置,只有线条发生变化。为什么会这样?
  • 部分是一个简单的错字,部分是你的原始代码的问题:它应该是 selectAll(".dot") 来选择类名 -- 并且你应该更新原始代码图表代码实际上为您的&lt;a&gt; 元素提供了该类! focus.selectAll(".dot").data(data).enter().append("a").attr("class", "dot")
  • 你可以检查这个问题stackoverflow.com/questions/22653412/…
【解决方案2】:
var margin = {top: 10, right: 10, bottom: 100, left: 40},
    margin2 = {top: 430, right: 10, bottom: 30, left: 40},
        width = 2000 - margin.left - margin.right,
        height = 500 - margin.top - margin.bottom,
        height2 = 500 - margin2.top - margin2.bottom;


var parseDate = d3.time.format("%Y-%m-%d").parse;
var formatTime = d3.time.format("%e %B");

var x = d3.time.scale().range([0, width]);
var x2= d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);
var y2 = d3.scale.linear().range([height2, 0]);

var xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(25);
var xAxis2 = d3.svg.axis().scale(x2).orient("bottom");

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

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


var valueline = d3.svg.line().defined(function(d) { return d.close != 0; }).x(function(d) { return x(d.date); }).y(function(d) { return y(d.close); });

var valueline2 = d3.svg.line().defined(function(d) { return d.close != 0; }).x(function(d) { return x2(d.date); }).y(function(d) { return y2(d.close); });

var brush = d3.svg.brush()
    .x(x2)
    .on("brush", brushed);
var svg = d3.select("body").append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom);



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

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


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

d3.json("data/data2.php", function(error, data) { data.forEach(function(d,i) {

    //document.write(d.date);
    d.date = parseDate(d.date);
    //document.write(d.date);
        d.close = +d.close;

    //document.write(d.close);
    arr[i]=d.close;


    len=i+1;


    });

// Scale the range of the data
    x.domain(d3.extent(data, function(d) { return d.date; }));
    y.domain([min-10, max+10]);
    x2.domain(x.domain());
     y2.domain(y.domain());

focus.append("path")        // Add the valueline path.
    .datum(data)
        .attr("class","valueline")
    .attr("d", valueline);

context.append("path")      // Add the valueline path.
        .attr("d", valueline2(data));

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


context.append("g")
      .attr("class", "x brush")
      .call(brush)
    .selectAll("rect")
      .attr("y", -6)
      .attr("height", height2 + 7);
});


function brushed() {
  x.domain(brush.empty() ? x2.domain() : brush.extent());
  focus.selectAll(".valueline").attr("d",valueline); // selectAll is the answer
  focus.select(".x.axis").call(xAxis);
}

function type(d) {
  d.date = parseDate(d.date);
  d.close = +d.close;
  return d;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-21
    • 2014-05-04
    • 2019-08-23
    • 2019-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多