【发布时间】:2018-11-05 12:01:43
【问题描述】:
我使用 D3 实现了一个折线图,它应该显示 5 年内每个国家/地区的员工人数。我在下面附上了 JSFiddle。在图表的 X 轴上,我需要将年份作为标签。 (年份来自数据集)但问题是 X 轴有一些附加值作为标签,我无法弄清楚为什么会发生这种情况。我对使用 D3 也很陌生。谁能告诉我这里出了什么问题?
小提琴:https://jsfiddle.net/yasirunilan/e01L3uvt/1/
var data = [
{
name: "USA",
values: [
{date: "2000", price: "100"},
{date: "2001", price: "110"},
{date: "2002", price: "145"},
{date: "2003", price: "241"},
{date: "2004", price: "101"}
]
},
{
name: "UK",
values: [
{date: "2000", price: "200"},
{date: "2001", price: "120"},
{date: "2002", price: "33"},
{date: "2003", price: "21"},
{date: "2004", price: "51"}
]
},
{
name: "UAE",
values: [
{date: "2000", price: "50"},
{date: "2001", price: "10"},
{date: "2002", price: "5"},
{date: "2003", price: "71"},
{date: "2004", price: "20"}
]
},
{
name: "Australia",
values: [
{date: "2000", price: "20"},
{date: "2001", price: "40"},
{date: "2002", price: "25"},
{date: "2003", price: "75"},
{date: "2004", price: "19"}
]
},
{
name: "India",
values: [
{date: "2000", price: "200"},
{date: "2001", price: "150"},
{date: "2002", price: "170"},
{date: "2003", price: "150"},
{date: "2004", price: "130"}
]
},
{
name: "Orange Department F",
values: [
{date: "2000", price: "75"},
{date: "2001", price: "100"},
{date: "2002", price: "120"},
{date: "2003", price: "140"},
{date: "2004", price: "190"}
]
}
];
const margin = 80;
const width = 1000 - 2 * margin;
const height = 550 - 2 * margin;
var duration = 250;
var lineOpacity = "0.25";
var lineOpacityHover = "0.85";
var otherLinesOpacityHover = "0.1";
var lineStroke = "1.5px";
var lineStrokeHover = "2.5px";
var circleOpacity = '0.85';
var circleOpacityOnLineHover = "0.25"
var circleRadius = 3;
var circleRadiusHover = 6;
/* Format Data */
var parseDate = d3.time.format("%Y");
data.forEach(function(d) {
d.values.forEach(function(d) {
d.date = parseDate.parse(d.date);
d.price = +d.price;
});
});
/* Scale */
var xScale = d3.time.scale()
.domain(d3.extent(data[0].values, d => d.date))
.range([0, width-margin]);
var yScale = d3.scale.linear()
.domain([0, d3.max(data[0].values, d => d.price)])
.range([height-margin, 0]);
// var color = d3.scale.ordinal(d3.schemeCategory10);
var color = d3.scale.category10();
/* Add SVG */
var svg = d3.select("svg")
.attr("width", (width+margin)+"px")
.attr("height", (height+margin)+"px")
.append('g')
.attr("transform", `translate(${margin}, ${margin})`);
/* Add line into SVG */
var line = d3.svg.line()
.x(d => xScale(d.date))
.y(d => yScale(d.price));
let lines = svg.append('g')
.attr('class', 'lines');
lines.selectAll('.line-group')
.data(data).enter()
.append('g')
.attr('class', 'line-group')
.on("mouseover", function(d, i) {
svg.append("text")
.attr("class", "title-text")
.style("fill", color(i))
.text(d.name)
.attr("text-anchor", "middle")
.attr("x", (width-margin)/2)
.attr("y", 5);
})
.on("mouseout", function(d) {
svg.select(".title-text").remove();
})
.append('path')
.attr('class', 'line')
.attr('d', d => line(d.values))
.style('stroke', (d, i) => color(i))
.style('opacity', lineOpacity)
.on("mouseover", function(d) {
d3.selectAll('.line')
.style('opacity', otherLinesOpacityHover);
d3.selectAll('.circle')
.style('opacity', circleOpacityOnLineHover);
d3.select(this)
.style('opacity', lineOpacityHover)
.style("stroke-width", lineStrokeHover)
.style("cursor", "pointer");
})
.on("mouseout", function(d) {
d3.selectAll(".line")
.style('opacity', lineOpacity);
d3.selectAll('.circle')
.style('opacity', circleOpacity);
d3.select(this)
.style("stroke-width", lineStroke)
.style("cursor", "none");
});
/* Add circles in the line */
lines.selectAll("circle-group")
.data(data).enter()
.append("g")
.style("fill", (d, i) => color(i))
.selectAll("circle")
.data(d => d.values).enter()
.append("g")
.attr("class", "circle")
.on("mouseover", function(d) {
d3.select(this)
.style("cursor", "pointer")
.append("text")
.attr("class", "text")
.text(`${d.price}`)
.attr("x", d => xScale(d.date) + 5)
.attr("y", d => yScale(d.price) - 10);
})
.on("mouseout", function(d) {
d3.select(this)
.style("cursor", "none")
.transition()
.duration(duration)
.selectAll(".text").remove();
})
.append("circle")
.attr("cx", d => xScale(d.date))
.attr("cy", d => yScale(d.price))
.attr("r", circleRadius)
.style('opacity', circleOpacity)
.on("mouseover", function(d) {
d3.select(this)
.transition()
.duration(duration)
.attr("r", circleRadiusHover);
})
.on("mouseout", function(d) {
d3.select(this)
.transition()
.duration(duration)
.attr("r", circleRadius);
});
/* Add Axis into SVG */
var xAxis = d3.svg.axis().scale(xScale)
.orient("bottom").tickSize(1);
var yAxis = d3.svg.axis().scale(yScale)
.orient("left").tickSize(1);
svg.append("g")
.attr("class", "x axis")
.attr("transform", `translate(0, ${height-margin})`)
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append('text')
.attr("y", 15)
.attr("transform", "rotate(-90)")
.attr("fill", "#000")
.attr('text-anchor', 'middle')
.text("No. of Employees");
【问题讨论】:
-
为什么在学习 d3 时使用 d3v3,我们目前在 d3v5。使用 d3v5,您可以指定只需要年标记处的刻度。为什么不结合鼠标事件处理程序?
-
我正在实施图表的系统已经使用 d3 V3。因为最好使用相同的库版本,所以我使用 D3v3 实现了这个。我们不能在 v3 中做到这一点。您究竟要求组合鼠标事件处理程序是为了什么?
-
然后实现一个自定义刻度格式化程序,如github.com/d3/d3-time-format
标签: javascript d3.js charts axis