我想使用这些数据创建一个折线图:
var mydata = [
{
"year": "2019",
"myvalue": "50"
},
{
"year": "2018",
"myvalue": "50"
},
{
"year": "2017",
"myvalue": "NaN"
},
{
"year": "2016",
"myvalue": "NaN"
},
{
"year": "2015",
"myvalue": "10"
},
{
"year": "2014",
"myvalue": "25.6"
},
{
"year": "2013",
"myvalue": "4.2"
},
{
"year": "2012",
"myvalue": "60"
},
{
"year": "2011",
"myvalue": "826"
},
{
"year": "2010",
"myvalue": "32"
},
{
"year": "2009",
"myvalue": "50"
},
{
"year": "2008",
"myvalue": "70"
}
];
整个代码HERE。
我构建的图表有效,但它有一些问题:缺少一些x
轴刻度线,线图(和圆圈)没有被x
轴(如此图所示):
答案 0 :(得分:3)
您的代码需要大量的重构。但是,仅解决问题中陈述的问题,您有3个问题:
您正在将边距应用于<g>
元素,然后再将其应用于轴组。放下translate
:
thisSvg.append('g')
.attr('class', 'y axis')
.attr('transform', 'translate(' + margin.left + ', 0)')
您没有解析日期。在调用您的比例时,year
值为字符串,而不是日期对象。解析日期:
mydata.forEach(function(d) {
d.year = parseTime(d.year)
})
如果不首先设置比例域,则无法调用轴。
总之,这是您的代码,包含这些更改:
var mydata = [{
"year": "2019",
"myvalue": "50"
},
{
"year": "2018",
"myvalue": "50"
},
{
"year": "2017",
"myvalue": "NaN"
},
{
"year": "2016",
"myvalue": "NaN"
},
{
"year": "2015",
"myvalue": "10"
},
{
"year": "2014",
"myvalue": "25.6"
},
{
"year": "2013",
"myvalue": "4.2"
},
{
"year": "2012",
"myvalue": "60"
},
{
"year": "2011",
"myvalue": "826"
},
{
"year": "2010",
"myvalue": "32"
},
{
"year": "2009",
"myvalue": "50"
},
{
"year": "2008",
"myvalue": "70"
}
];
var margin = {
top: 10,
right: 10,
bottom: 50,
left: 40
};
var svg = d3.select('#linechart')
.append('svg')
.attr('width', 600)
.attr('height', 200);
var parseTime = d3.timeParse("%Y");
mydata.forEach(function(d) {
d.year = parseTime(d.year)
})
var values = createAxisLine(svg);
var x = values[0];
var y = values[1];
var width = values[2];
var height = values[3];
var svg2 = values[4];
createChartLine(svg, x, y, width, height, svg2);
function createAxisLine(thisSvg) {
var width = thisSvg.attr('width') - margin.left - margin.right;
var height = thisSvg.attr('height') - margin.top - margin.bottom;
thisSvg = thisSvg.append('g').attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');
var x = d3.scaleTime()
.rangeRound([0, width]);
var y = d3.scaleLinear()
.rangeRound([height, 0]);
x.domain(d3.extent(mydata, function(d) {
return d.year;
}));
y.domain([0, 1000]);
var xAxis = d3.axisBottom(x); //.tickSize(0, 0);
var yAxis = d3.axisLeft(y);
thisSvg.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0, ' + height + ')')
.call(xAxis)
.selectAll('text')
.style('text-anchor', 'end')
.attr('dx', '-.8em')
.attr('dy', '.15em')
.attr('transform', 'rotate(-65)');
thisSvg.append('g')
.attr('class', 'y axis')
.call(yAxis)
.append('text')
.attr('transform', 'rotate(-90)')
.attr('y', 6)
.attr('dy', '.71em')
.style('text-anchor', 'end');
return [x, y, width, height, thisSvg];
}
function createChartLine(thisSvg, x, y, width, height, thisSvg) {
var lines = thisSvg
.attr('transform', function(d) {
return 'translate(' + margin.left + ', ' + margin.top + ')';
});
var line = d3.line()
.x(function(d) {
return x(d.year);
})
.y(function(d) {
return y(d.myvalue);
})
.defined(function(d) { // for missing (0) data
if (isNaN(d.myvalue)) {
d.myvalue = 0;
}
return d.myvalue !== 0;
});
lines.append('path')
.data([mydata])
.attr('class', 'mylines')
.attr('fill', 'none')
.attr('stroke', 'steelblue')
.attr('stroke-width', 1.5)
.attr('d', line);
thisSvg.append('g').attr('class', 'circles')
.selectAll('.dot')
.data(mydata)
.enter()
.append('circle')
.attr('class', 'dot')
.attr('cx', function(d) {
return x(d.year);
})
.attr('cy', function(d) {
return y(d.myvalue);
})
.attr('r', 3);
}
<script src='https://d3js.org/d3.v5.js' charset='utf-8'></script>
<div style='height:50px;'></div>
<div id='linechart'></div>