我正在尝试使用D3.js绘制多线图。图表已正确绘制,但x轴刻度未正确与数据点圆对齐。 在此处找到示例代码:https://jsfiddle.net/gopal31795/qsLd7pc5/9/
我假设创建点的代码中存在一些错误。
// Creating Dots on line
segment.selectAll("dot")
.data(function(d) {
return d.linedata;
})
.enter().append("circle")
.attr("r", 5)
.attr("cx", function(d) {
//return x(parseDate(new Date(d.mins))) + x.rangeBand() / 2;
return x(d.mins);
})
.attr("cy", function(d) {
return y(d.value);
})
.style("stroke", "white")
.style("fill", function(d) {
return color(this.parentNode.__data__.name);
})
.on("mouseenter", function(d) {
d3.select(this).transition().style("opacity", "0.25");
tooltip.html("<span style='color:" + color(this.parentNode.__data__.name) + ";'>" + this.parentNode.__data__.name + "</span>: " + (d.value + "s")).style("visibility", "visible").style("top", (event.pageY + 10) + "px").style("left", (event.pageX) + "px");
})
.on("mouseleave", function(d) {
d3.select(this).transition().style("opacity", "1");
tooltip.style("visibility", "hidden");
});
答案 0 :(得分:1)
您的代码(使用旧版v3)中的问题是您使用的是rangeRoundBands
。例如,如果您有条形图,那将是正确的选择。
但是,由于您正在处理数据点,因此应使用rangePoints
或rangeRoundPoints
,这将:
从指定的连续间隔设置输出范围。数组间隔包含两个元素,分别代表最小值和最大值。该间隔可细分为n个均匀分布的点,其中n是输入域中(唯一)值的数量。
因此,应该是:
var x = d3.scale.ordinal()
.rangeRoundPoints([0, width]);
这是您所做的更改的代码:
var Data = [{
"name": "R",
"linedata": [{
"mins": 0,
"value": 1120
},
{
"mins": 2,
"value": 1040
},
{
"mins": 4,
"value": 1400
},
{
"mins": 6,
"value": 1500
}
]
},
{
"name": "E",
"linedata": [{
"mins": 0,
"value": 1220
},
{
"mins": 2,
"value": 1500
},
{
"mins": 4,
"value": 1610
},
{
"mins": 6,
"value": 1700
}
]
}
];
var margin = {
top: 20,
right: 90,
bottom: 35,
left: 90
},
width = $("#lineChart").width() - margin.left - margin.right,
height = $("#lineChart").width() * 0.3745 - margin.top - margin.bottom;
//var parseDate = d3.time.format("%d-%b");
var x = d3.scale.ordinal()
.rangeRoundPoints([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.category10();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(5);
var xData = Data[0].linedata.map(function(d) {
return d.mins;
});
var line = d3.svg.line()
.interpolate("linear")
.x(function(d) {
return x(d.mins);
})
.y(function(d) {
return y(d.value);
});
function transition(path) {
path.transition()
.duration(4000)
.attrTween("stroke-dasharray", tweenDash);
}
function tweenDash() {
var l = this.getTotalLength(),
i = d3.interpolateString("0," + l, l + "," + l);
return function(t) {
return i(t);
};
}
var svg = d3.select("#lineChart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
color.domain(Data.map(function(d) {
return d.name;
}));
x.domain(xData);
var valueMax = d3.max(Data, function(r) {
return d3.max(r.linedata, function(d) {
return d.value;
})
});
var valueMin = d3.min(Data, function(r) {
return d3.min(r.linedata, function(d) {
return d.value;
})
});
y.domain([valueMin, valueMax]);
//Drawing X Axis
svg.append("g")
.attr("class", "x-axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("class", "xAxisText")
.attr("x", width)
.attr("dy", "-.41em")
.style("text-anchor", "end")
.style("fill", "white")
.text("Time(m)");
svg.append("g")
.attr("class", "y-axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.style("fill", "none")
.style("stroke", "white")
.style("stroke-width", 0.8)
.text("Duration(s)");
// Drawing Lines for each segments
var segment = svg.selectAll(".segment")
.data(Data)
.enter().append("g")
.attr("class", "segment");
segment.append("path")
.attr("class", "line")
.attr("id", function(d) {
return d.name;
})
.attr("visible", 1)
.call(transition)
//.delay(750)
//.duration(1000)
//.ease('linear')
.attr("d", function(d) {
return line(d.linedata);
})
.style("stroke", function(d) {
return color(d.name);
});
// Creating Dots on line
segment.selectAll("dot")
.data(function(d) {
return d.linedata;
})
.enter().append("circle")
.attr("r", 5)
.attr("cx", function(d) {
//return x(parseDate(new Date(d.mins))) + x.rangeBand() / 2;
return x(d.mins);
})
.attr("cy", function(d) {
return y(d.value);
})
.style("stroke", "white")
.style("fill", function(d) {
return color(this.parentNode.__data__.name);
})
.on("mouseenter", function(d) {
d3.select(this).transition().style("opacity", "0.25");
tooltip.html("<span style='color:" + color(this.parentNode.__data__.name) + ";'>" + this.parentNode.__data__.name + "</span>: " + (d.value + "s")).style("visibility", "visible").style("top", (event.pageY + 10) + "px").style("left", (event.pageX) + "px");
})
.on("mouseleave", function(d) {
d3.select(this).transition().style("opacity", "1");
tooltip.style("visibility", "hidden");
});
path {
fill: none;
stroke: black;
}
line {
stroke: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<div class="card-body" id="lineChart">
</div>
最后,提示:不要混合使用D3和jQuery。