所以这里...... http://codepen.io/dwilbank68/pen/VagOKd?editors=0010
我有相同的精确数据数组,创建正确的点数,但没有足够数量的文本元素。
这不是遮挡名称的边际问题......元素甚至不在DOM中。
我甚至将索引附加到名称,以证明graphData数组具有正确数量的元素。
还有什么可能是错的?
svg.selectAll('.dot') // creates the correct number of dots
.data(graphData)
.enter()
.append('circle')
.attr('class', 'dot')
.attr('r', 5)
.attr('cx', (d)=> xScale(d.secondsBehind) )
.attr('cy', (d)=> yScale(d.place) )
.style('fill', (d)=> colorScale(d.dopingAllegations) );
svg.selectAll('.label') // does not create the last two text elements
.data(graphData)
.enter()
.append('text')
.attr('class', 'label')
.attr('x', (d)=> xScale(d.secondsBehind) + 10)
.attr('y', (d)=> yScale(d.place) + 4)
.text( (d)=> d.name );
var url = "https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/cyclist-data.json";
var m = {t: 20, r: 120, b: 30, l: 40},
width = 800 - m.l - m.r,
height = 700 - m.t - m.b;
var svg = d3.select("body").append("svg")
.attr("width", width + m.l + m.r)
.attr("height", height + m.t + m.b)
.append("g")
.attr("transform", "translate(" + m.l + "," + m.t + ")");
var div = d3.select('body')
.append('div')
.style({
'position':'absolute',
'text-align':'center',
'width':'240px',
'height':'2.5em',
'font':'1.5em sans-serif',
'color':'yellow',
'background':'black',
'border-radius':'8px',
'border':'solid 1px green',
'opacity':0
});
var colorScale = d3.scale.ordinal()
.range(["#FF0000", "#009933"]);
var xScale = d3.scale.linear()
.range([width, 0]);
var yScale = d3.scale.linear()
.range([0, height]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.tickFormat(formatMinSec);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
d3.json(url, callback);
function callback (error, data) {
if (error) throw error;
var bestTime = _.sortBy(data, 'Place')[0].Seconds;
var graphData = _.map(data, (d)=> ({
'secondsBehind': Math.abs(bestTime - d.Seconds),
'year': d.Year,
'nationality': d.Nationality,
'doping': d.Doping,
'dopingAllegations': d.Doping.length > 0 ? "Doping Allegations":"No Doping Allegations",
'name': d.Name,
'place': d.Place,
'time': d.Time
}) )
var timeRange = d3.extent(graphData, (d) => d.secondsBehind );
xScale.domain([timeRange[0]-15, timeRange[1]]);
var rankRange = d3.extent(graphData, (d) => d.place );
yScale.domain([rankRange[0], rankRange[1]+1]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.text("Minutes : Seconds Behind Fastest Time")
.attr({
'class': 'label',
'x': width,
'y': -6
})
.style("text-anchor", "end");
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.text("Ranking")
.attr({
'class': 'label',
"transform": "rotate(-90)",
"y": 6,
"dy": ".71em"
})
.style("text-anchor", "end");
svg.selectAll('.dot')
.data(graphData)
.enter()
.append('circle')
.attr('class', 'dot')
.attr('r', 5)
.attr('cx', (d)=> xScale(d.secondsBehind) )
.attr('cy', (d)=> yScale(d.place) )
.style('fill', (d)=> colorScale(d.dopingAllegations) );
svg.selectAll('.label')
.data(graphData)
.enter()
.append('text')
.attr('class', 'label')
.attr('x', (d)=> xScale(d.secondsBehind) + 10)
.attr('y', (d)=> yScale(d.place) + 4)
.text( (d)=> d.name );
// d3.selectAll('.dot')
// .on('mouseover', mouseover)
// .on('mouseout', mouseout);
var legend = svg.selectAll('.legend')
.data(colorScale.domain())
.enter()
.append('g')
.attr('class', 'legend')
.attr('transform', function(d,i){return 'translate(0,' +i*20+')';});
legend.append('rect')
.attr('x', width)
.attr('y', 100)
.attr('width', 18)
.attr('height', 18)
.style('fill', colorScale);
legend.append('text')
.text((d)=> d)
.attr('x', width - 18)
.attr('y', 108)
.attr('dy', '.35em')
.style('text-anchor', 'end');
};
// function mouseover(d){
// div.html('Sepal Width: ' + d.sepalWidth +
// '<br/>' +
// 'Sepal Length: ' + d.sepalLength)
// .style('left', (d3.event.pageX + 9) +'px')
// .style('top', (d3.event.pageY - 43) +'px')
// .style('opacity', 1);
// }
// function mouseout(){
// div.style('opacity', 1e-6);
// }
function formatMinSec(d){
if( d % 60 > 9){
return Math.floor(d/60) +':'+ d%60
} else {
return Math.floor(d/60) +':0'+ d%60
}
}
&#13;
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.dot {
stroke: #000;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.6.1/lodash.min.js"></script>
&#13;
答案 0 :(得分:1)
而不是:
svg.selectAll('.dot') // creates the correct number of dots
.data(graphData)
.enter()
.append('circle')
.attr('class', 'dot')
.attr('r', 5)
.attr('cx', (d)=> xScale(d.secondsBehind) )
.attr('cy', (d)=> yScale(d.place) )
.style('fill', (d)=> colorScale(d.dopingAllegations) );
svg.selectAll('.label') // does not create the last two text elements
.data(graphData)
.enter()
.append('text')
.attr('class', 'label')
.attr('x', (d)=> xScale(d.secondsBehind) + 10)
.attr('y', (d)=> yScale(d.place) + 4)
.text( (d)=> d.name );
这样做:
var gs = svg.selectAll('.dot')
.data(graphData)
.enter();
gs.append('circle')
.attr('class', 'dot')
.attr('r', 5)
.attr('cx', (d)=> xScale(d.secondsBehind) )
.attr('cy', (d)=> yScale(d.place) )
.style('fill', (d)=> colorScale(d.dopingAllegations) );
gs
.append('text')
.attr('class', 'label')
.attr('x', (d)=> xScale(d.secondsBehind) + 10)
.attr('y', (d)=> yScale(d.place) + 4)
.text( (d)=> { return d.name; } );
工作代码here
其他选项是代替
svg.selectAll('.label') // does not create the last two text elements
.data(graphData)
.enter()
.append('text')
.attr('class', 'label')
.attr('x', (d)=> xScale(d.secondsBehind) + 10)
.attr('y', (d)=> yScale(d.place) + 4)
.text( (d)=> d.name );
这样做:
svg.selectAll('.label')
.data(graphData, function(d) {
if (d) {
return d.place; //unique identifier of the data, otherwise Marco Pantani will come only once.
}
})
.enter()
.append('text')
.attr('class', 'label')
.attr('x', (d) => xScale(d.secondsBehind) + 10)
.attr('y', (d) => yScale(d.place) + 4)
.text((d) => d.name);
工作代码here
答案 1 :(得分:1)
label
svg.selectAll('.label')
搜索整个svg并基于.label
。 选择这两个标签,将它们计算为已经创建的,因此在enter
阶段无关紧要
最简单的解决方法是将您的选择包装在g
元素中,例如
var graph = svg.append("g");
graph.selectAll('.dot')
.data(graphData)
// ...
graph.selectAll('.label')
.data(graphData)
// ...
和演示
var url = "https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/cyclist-data.json";
var m = {t: 20, r: 120, b: 30, l: 40},
width = 800 - m.l - m.r,
height = 700 - m.t - m.b;
var svg = d3.select("body").append("svg")
.attr("width", width + m.l + m.r)
.attr("height", height + m.t + m.b)
.append("g")
.attr("transform", "translate(" + m.l + "," + m.t + ")");
var div = d3.select('body')
.append('div')
.style({
'position':'absolute',
'text-align':'center',
'width':'240px',
'height':'2.5em',
'font':'1.5em sans-serif',
'color':'yellow',
'background':'black',
'border-radius':'8px',
'border':'solid 1px green',
'opacity':0
});
var colorScale = d3.scale.ordinal()
.range(["#FF0000", "#009933"]);
var xScale = d3.scale.linear()
.range([width, 0]);
var yScale = d3.scale.linear()
.range([0, height]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.tickFormat(formatMinSec);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
d3.json(url, callback);
function callback (error, data) {
if (error) throw error;
var bestTime = _.sortBy(data, 'Place')[0].Seconds;
var graphData = _.map(data, (d)=> ({
'secondsBehind': Math.abs(bestTime - d.Seconds),
'year': d.Year,
'nationality': d.Nationality,
'doping': d.Doping,
'dopingAllegations': d.Doping.length > 0 ? "Doping Allegations":"No Doping Allegations",
'name': d.Name,
'place': d.Place,
'time': d.Time
}) )
var timeRange = d3.extent(graphData, (d) => d.secondsBehind );
xScale.domain([timeRange[0]-15, timeRange[1]]);
var rankRange = d3.extent(graphData, (d) => d.place );
yScale.domain([rankRange[0], rankRange[1]+1]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.text("Minutes : Seconds Behind Fastest Time")
.attr({
'class': 'label',
'x': width,
'y': -6
})
.style("text-anchor", "end");
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.text("Ranking")
.attr({
'class': 'label',
"transform": "rotate(-90)",
"y": 6,
"dy": ".71em"
})
.style("text-anchor", "end");
var graph = svg.append("g");
graph.selectAll('.dot')
.data(graphData)
.enter()
.append('circle')
.attr('class', 'dot')
.attr('r', 5)
.attr('cx', (d)=> xScale(d.secondsBehind) )
.attr('cy', (d)=> yScale(d.place) )
.style('fill', (d)=> colorScale(d.dopingAllegations) );
graph.selectAll('.label')
.data(graphData)
.enter()
.append('text')
.attr('class', 'label')
.attr('x', (d)=> xScale(d.secondsBehind) + 10)
.attr('y', (d)=> yScale(d.place) + 4)
.text( (d)=> d.name );
// d3.selectAll('.dot')
// .on('mouseover', mouseover)
// .on('mouseout', mouseout);
var legend = svg.selectAll('.legend')
.data(colorScale.domain())
.enter()
.append('g')
.attr('class', 'legend')
.attr('transform', function(d,i){return 'translate(0,' +i*20+')';});
legend.append('rect')
.attr('x', width)
.attr('y', 100)
.attr('width', 18)
.attr('height', 18)
.style('fill', colorScale);
legend.append('text')
.text((d)=> d)
.attr('x', width - 18)
.attr('y', 108)
.attr('dy', '.35em')
.style('text-anchor', 'end');
};
// function mouseout(){
// div.style('opacity', 1e-6);
// }
function formatMinSec(d){
if( d % 60 > 9){
return Math.floor(d/60) +':'+ d%60
} else {
return Math.floor(d/60) +':0'+ d%60
}
}
&#13;
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.dot {
stroke: #000;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.6.1/lodash.min.js"></script>
&#13;