2016-08-04 54 views
1

我正在嘗試將標記繪製到可縮放/可平移圖。 我現在的版本可在https://jsfiddle.net/n2enn80o/如何使用d3js動態創建附加svg行?

raw = {"l2":[-58,-44,-31,-21,-17,-16,-16,-15,-15,-14,-13,-12,-11,-10,-9,-7,-5,-3,-1,2,4,8,11,14,17,20,24,28,32,37,41,46,51,56,60,64,69,73,77,82,84,87,87,87,87,85,82,77,73,66,60,53,46,39,33,26,20,13,8,4,-1,-6,-10,-14,-16,-19,-22,-25,-26,-27,-28,-29,-30,-31,-31,-32,-32,-32,-32,-31,-31,-31,-31,-31,-30,-31,-30,-30,-30,-30,-29,-28,-27,-27,-27,-27,-27,-26,-26,-26,-26,-26,-26,-26,-26,-25,-25,-25,-25,-25,-25,-25,-25,-25,-24,-24,-24,-25,-25,-24,-23,-23,-23,-23,-23,-23,-23,-23,-23,-22,-22,-22,-22,-22,-22,-21,-21,-21,-21,-20,-20,-20,-20,-19,-18,-16,-13,-10,-6,-2,1,4,7,9,12,14,16,16,16,15,13,9,6,2,-1,-4,-7,-10,-11,-12,-14,-15,-16,-17,-18,-19,-19,-20,-20,-20,-20,-20,-20,-20,-24,-32,-45,-54,-50,-25,25,97,182,252,270,220,126,35,-25,-53,-65,-71,-70,-60,-46,-32,-22,-18,-16,-16,-15,-14,-13,-13,-12,-11,-10,-8,-7,-5,-3,-1,1,4,7,10,14,17,21,24,28,32,36,40,45,50,55,59,64,69,72,77,81,84,87,88,88,87,84,82,77,73,67,61,54,47,39,33,26,20,14,9,4,-1,-6,-9,-13,-16,-19,-22,-24,-26,-28,-29,-29,-30,-30,-31,-32,-32,-32,-31,-31,-32,-31,-31,-31,-31,-30,-30,-29,-29,-29,-29,-28,-28,-27,-27,-28,-28,-26,-26,-26,-26,-26,-26,-26,-26,-25,-25,-25,-25,-25,-25,-26,-26,-25,-24,-24,-24,-24,-24,-24,-24,-23,-23,-23,-23,-23,-23,-23,-24,-22,-22,-22,-22,-22,-22,-22,-21,-22,-20,-20,-20,-20,-20,-19,-18,-16,-13,-10,-8,-3,0,4,7,9,11,13,15,16,16,16,14,11,6,2,-2,-4,-7,-9,-11,-12,-14,-16,-17,-18,-19,-19,-19,-19,-20,-20,-20,-20,-20,-20,-23,-30,-43,-54,-53,-30,17,88,172,245,271,230,138,45,-19,-50,-63,-70,-70,-61,-48,-34,-23,-18,-17,-16,-16,-15,-14,-13,-13,-11,-10,-8,-7,-5,-3,-1,1,4,7,9,13,16,20,23,27,31,36,40,44,49,54,59,63,68,73,76,81,83,86,88,87,87,85,82,78,73,68,62,55,48,40,33,27,20,14,9,4,0,-5,-9,-13,-16,-19,-22,-24,-26,-28,-29,-29,-29,-30,-31,-31,-32,-31,-32,-32,-32,-32], "startts":1357714800000,"marker1":[50,100]}; 

var data =[]; 
for(var i=0;i<raw.l2.length;i++) 
{ 
    var marker = Number.NaN; 

    for(var j=0;j<raw.marker1.length;j++) 
    { 
     if(i==raw.marker1[j]) 
     { 
      marker=i; 
      break; 
     } 
    } 
    var obj = {"date":raw.startts+(1/244.140625*1000)*i, "value":raw.l2[i]/75,"marker":marker} 
    data.push(obj) 
} 

margin = { 
    top: 20, 
    right: 20, 
    bottom: 20, 
    left: 45 
}; 

width = 1800 - margin.left - margin.right; 
height = 600 - margin.top - margin.bottom; 

var x = d3.time.scale() 
    .domain(d3.extent(data, function (d) { 
    return d.date; 
})) 
    .range([0, width]); 

var y = d3.scale.linear() 
    .domain(d3.extent(data, function (d) { 
    return d.value; 
})) 
    .range([height, 0]); 

var line = d3.svg.line() 
    .x(function (d) { 
    return x(d.date); 
}) 
    .y(function (d) { 
    return y(d.value); 
}); 



var zoom = d3.behavior.zoom() 
    .x(x) 
    .y(y) 
    .on("zoom", zoomed); 

svg = d3.select('#chart') 
    .append("svg:svg") 
    .attr('width', width + margin.left + margin.right) 
    .attr('height', height + margin.top + margin.bottom) 
    .append("svg:g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 
    .call(zoom); 

svg.append("svg:rect") 
    .attr("width", width) 
    .attr("height", height) 
    .attr("class", "plot"); 

var make_x_axis = function() { 
    return d3.svg.axis() 
     .scale(x) 
     .orient("bottom") 
     .ticks(5); 
}; 

var make_y_axis = function() { 
    return d3.svg.axis() 
     .scale(y) 
     .orient("left") 
     .ticks(5); 
}; 

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

svg.append("svg:g") 
    .attr("class", "x axis") 
    .attr("transform", "translate(0, " + height + ")") 
    .call(xAxis); 

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

svg.append("g") 
    .attr("class", "y axis") 
    .call(yAxis); 


var marker = svg.append("line") 
    .attr("x1",100) 
    .attr("y1", 0)  
    .attr("x2",100) 
    .attr("y2", height) 
    .attr("class", "marker") 

svg.append("text") 
    .attr("x", 100) 
    .attr("y", 0) 
    .attr("dy", ".35em") 
    .attr("dx", 5) 
    .attr("class", "marker-text") 
    .text(function(d) { return "test"; }); 

svg.append("g") 
    .attr("class", "x grid") 
    .attr("transform", "translate(0," + height + ")") 
    .call(make_x_axis() 
     .tickSize(-height, 0, 0) 
     .tickFormat("")); 

svg.append("g") 
    .attr("class", "y grid") 
    .call(make_y_axis() 
    .tickSize(-width, 0, 0) 
    .tickFormat("")); 

var clip = svg.append("svg:clipPath") 
    .attr("id", "clip") 
    .append("svg:rect") 
    .attr("x", 0) 
    .attr("y", 0) 
    .attr("width", width) 
    .attr("height", height); 

var chartBody = svg.append("g") 
    .attr("clip-path", "url(#clip)"); 

chartBody.append("svg:path") 
    .datum(data) 
    .attr("class", "line") 
    .attr("d", line); 

function zoomed() { 
    console.log(d3.event.translate); 
    console.log(d3.event.scale); 
    svg.select(".x.axis").call(xAxis); 
    svg.select(".y.axis").call(yAxis); 
    svg.select(".x.grid") 
     .call(make_x_axis() 
     .tickSize(-height, 0, 0) 
     .tickFormat("")); 
    svg.select(".y.grid") 
     .call(make_y_axis() 
     .tickSize(-width, 0, 0) 
     .tickFormat("")); 
    svg.select(".line") 
     .attr("class", "line") 
     .attr("d", line); 
} 

我已經能夠靜態行添加到在本例中我的D3地塊,我試圖做到的,是使標記線與文本「測試」一起隨着圖形移動。

我試過的是將d3.svg.line()與行生成器一起使用,但最終沒有得到對d的引用。我試過的另一個版本是創建一個如下函數,但沒有得到d的引用,並將該行繪製爲零。在這裏,我試圖畫出該行,當且僅當標記標記出現在數據中時。默認情況下填充數據時,我確保它有Number.NaN當我不需要繪製標記。

var marker = svg.append("line") 
    .attr("x1",function(d) { if(d.marker!=Number.NaN) return x(d.date); }) 
    .attr("y1", 0)  
    .attr("x2",function(d) { if(d.marker!=Number.NaN) return x(d.date); }) 
    .attr("y2", height) 
    .attr("class", "marker") 
+0

裏面'函數()'你需要改變'x1'&'的屬性x2''marker' – ksav

回答

1

根據我對您的問題的回覆,我做了一些小的更改。在您的縮放處理器zoomed()內部,您需要更改和markerText屬性x1 & x2的屬性。

此函數在每個縮放事件上觸發,以根據變焦距和軸移動物體或重繪物體。

raw = {"l2":[-58,-44,-31,-21,-17,-16,-16,-15,-15,-14,-13,-12,-11,-10,-9,-7,-5,-3,-1,2,4,8,11,14,17,20,24,28,32,37,41,46,51,56,60,64,69,73,77,82,84,87,87,87,87,85,82,77,73,66,60,53,46,39,33,26,20,13,8,4,-1,-6,-10,-14,-16,-19,-22,-25,-26,-27,-28,-29,-30,-31,-31,-32,-32,-32,-32,-31,-31,-31,-31,-31,-30,-31,-30,-30,-30,-30,-29,-28,-27,-27,-27,-27,-27,-26,-26,-26,-26,-26,-26,-26,-26,-25,-25,-25,-25,-25,-25,-25,-25,-25,-24,-24,-24,-25,-25,-24,-23,-23,-23,-23,-23,-23,-23,-23,-23,-22,-22,-22,-22,-22,-22,-21,-21,-21,-21,-20,-20,-20,-20,-19,-18,-16,-13,-10,-6,-2,1,4,7,9,12,14,16,16,16,15,13,9,6,2,-1,-4,-7,-10,-11,-12,-14,-15,-16,-17,-18,-19,-19,-20,-20,-20,-20,-20,-20,-20,-24,-32,-45,-54,-50,-25,25,97,182,252,270,220,126,35,-25,-53,-65,-71,-70,-60,-46,-32,-22,-18,-16,-16,-15,-14,-13,-13,-12,-11,-10,-8,-7,-5,-3,-1,1,4,7,10,14,17,21,24,28,32,36,40,45,50,55,59,64,69,72,77,81,84,87,88,88,87,84,82,77,73,67,61,54,47,39,33,26,20,14,9,4,-1,-6,-9,-13,-16,-19,-22,-24,-26,-28,-29,-29,-30,-30,-31,-32,-32,-32,-31,-31,-32,-31,-31,-31,-31,-30,-30,-29,-29,-29,-29,-28,-28,-27,-27,-28,-28,-26,-26,-26,-26,-26,-26,-26,-26,-25,-25,-25,-25,-25,-25,-26,-26,-25,-24,-24,-24,-24,-24,-24,-24,-23,-23,-23,-23,-23,-23,-23,-24,-22,-22,-22,-22,-22,-22,-22,-21,-22,-20,-20,-20,-20,-20,-19,-18,-16,-13,-10,-8,-3,0,4,7,9,11,13,15,16,16,16,14,11,6,2,-2,-4,-7,-9,-11,-12,-14,-16,-17,-18,-19,-19,-19,-19,-20,-20,-20,-20,-20,-20,-23,-30,-43,-54,-53,-30,17,88,172,245,271,230,138,45,-19,-50,-63,-70,-70,-61,-48,-34,-23,-18,-17,-16,-16,-15,-14,-13,-13,-11,-10,-8,-7,-5,-3,-1,1,4,7,9,13,16,20,23,27,31,36,40,44,49,54,59,63,68,73,76,81,83,86,88,87,87,85,82,78,73,68,62,55,48,40,33,27,20,14,9,4,0,-5,-9,-13,-16,-19,-22,-24,-26,-28,-29,-29,-29,-30,-31,-31,-32,-31,-32,-32,-32,-32], "startts":1357714800000,"marker1":[50,100]}; 

var data =[]; 
for(var i=0;i<raw.l2.length;i++) 
{ 
    var marker = Number.NaN; 

    for(var j=0;j<raw.marker1.length;j++) 
    { 
     if(i==raw.marker1[j]) 
     { 
      marker=i; 
      break; 
     } 
    } 
    var obj = {"date":raw.startts+(1/244.140625*1000)*i, "value":raw.l2[i]/75,"marker":marker} 
    data.push(obj) 
} 

margin = { 
    top: 20, 
    right: 20, 
    bottom: 20, 
    left: 45 
}; 

width = 1800 - margin.left - margin.right; 
height = 600 - margin.top - margin.bottom; 

var x = d3.time.scale() 
    .domain(d3.extent(data, function (d) { 
    return d.date; 
})) 
    .range([0, width]); 

var y = d3.scale.linear() 
    .domain(d3.extent(data, function (d) { 
    return d.value; 
})) 
    .range([height, 0]); 

var line = d3.svg.line() 
    .x(function (d) { 
    return x(d.date); 
}) 
    .y(function (d) { 
    return y(d.value); 
}); 



var zoom = d3.behavior.zoom() 
    .x(x) 
    .y(y) 
    .on("zoom", zoomed); 

svg = d3.select('#chart') 
    .append("svg:svg") 
    .attr('width', width + margin.left + margin.right) 
    .attr('height', height + margin.top + margin.bottom) 
    .append("svg:g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 
    .call(zoom); 

svg.append("svg:rect") 
    .attr("width", width) 
    .attr("height", height) 
    .attr("class", "plot"); 

var make_x_axis = function() { 
    return d3.svg.axis() 
     .scale(x) 
     .orient("bottom") 
     .ticks(5); 
}; 

var make_y_axis = function() { 
    return d3.svg.axis() 
     .scale(y) 
     .orient("left") 
     .ticks(5); 
}; 

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

svg.append("svg:g") 
    .attr("class", "x axis") 
    .attr("transform", "translate(0, " + height + ")") 
    .call(xAxis); 

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

svg.append("g") 
    .attr("class", "y axis") 
    .call(yAxis); 




svg.append("g") 
    .attr("class", "x grid") 
    .attr("transform", "translate(0," + height + ")") 
    .call(make_x_axis() 
     .tickSize(-height, 0, 0) 
     .tickFormat("")); 

svg.append("g") 
    .attr("class", "y grid") 
    .call(make_y_axis() 
    .tickSize(-width, 0, 0) 
    .tickFormat("")); 

// Moved this after you append your grids 
var marker = svg.append("line") 
    .attr("x1",100) 
    .attr("y1", 0)  
    .attr("x2",100) 
    .attr("y2", height) 
    .attr("class", "marker") 

// Moved this after you append your grids & saved it to a var for later use 
var markerText = svg.append("text") 
    .attr("x", 100) 
    .attr("y", 0) 
    .attr("dy", ".35em") 
    .attr("dx", 5) 
    .attr("class", "marker-text") 
    .text(function(d) { return "test"; }); 

var clip = svg.append("svg:clipPath") 
    .attr("id", "clip") 
    .append("svg:rect") 
    .attr("x", 0) 
    .attr("y", 0) 
    .attr("width", width) 
    .attr("height", height); 

var chartBody = svg.append("g") 
    .attr("clip-path", "url(#clip)"); 

chartBody.append("svg:path") 
    .datum(data) 
    .attr("class", "line") 
    .attr("d", line); 

function zoomed() { 
    console.log(d3.event.translate); 
    console.log(d3.event.scale); 
    svg.select(".x.axis").call(xAxis); 
    svg.select(".y.axis").call(yAxis); 
    svg.select(".x.grid") 
     .call(make_x_axis() 
     .tickSize(-height, 0, 0) 
     .tickFormat("")); 
    svg.select(".y.grid") 
     .call(make_y_axis() 
     .tickSize(-width, 0, 0) 
     .tickFormat("")); 
    svg.select(".line") 
     .attr("class", "line") 
     .attr("d", line); 

     // Position at the start time according to your x scale. x(val) 
     // It's not clear from your question where you want to position it 
     var markerPos = x(raw.startts); 

     // Move marker to position 
     marker.attr("x1", markerPos).attr("x2", markerPos); 

     // Move marker text to position 
     markerText.attr("x", markerPos); 

} 

小提琴:https://jsfiddle.net/kqnLfkvw/1/

+0

三江源ksav這是有幫助的,我設法解決它以類似的方式。 – sandeepzgk

+0

太好了。如果它向你展示方式,請隨時將答案標記爲已接受。 – ksav

0

這可以通過使用D3軸來解決。工作示例,請放大https://jsfiddle.net/3gww76s0/

var make_x_marker = function (scale=1, transform=[0,0]) { 

    console.log(transform) 
    var markers =[]; 
    var markerLabels={}; 
    for (i=0; i<raw.marker1.length; i++) 
    { 
    var value=transform[0]+scale*(1/244.140625*1000)*raw.marker1[i]; 
    markers.push(value) 
    markerLabels[value]="A"+Math.floor(Math.random()*26); 
    } 

    return d3.svg.axis() 
     .orient("top") 
     .tickValues(markers) 
     .tickSize(height-15) 
     .tickFormat(function(d){return markerLabels[d]}) 


};