在d3.js中添加滚动条和导航器,范围选择器功能

时间:2014-03-17 08:00:14

标签: d3.js line

我想在线图中包含滚动条和导航器,范围选择器功能。与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;
}

上面的代码是整个代码的片段。这里当我执行im得到一个解析错误d =&#34;&#34;。哪里错了。并且我在图中绘制了一些限制线,我没有包含在上面的代码中。底部画笔正在工作,但主图表没有按照画笔更新。 我也想更新点。我应该包括什么拉丝功能。

2 个答案:

答案 0 :(得分: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
}

答案 1 :(得分:0)

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;
}