ОБНОВЛЕНИЕ:
Максимальное значение yAxis меньше, чем фактическое максимальное значение данных nest
, поэтому оно усекается.
Вам необходимо использовать данные nest
внутриy Масштаб вычислений вместо использования исходных данных dataset
.
Шаги для достижения этой цели:
- определить
nest
сначала - получить значение
totalMax
flatting nest
дважды - используйте
totalMax
для вычисления yScale
значения
var totalMax = Object
.entries(nest)
.reduce(function(totalMax, [key, regionValue]){
const regionMax = Object
.entries(regionValue.values)
.reduce(function(regionMax, [key,yearValue]){
return parseInt(yearValue.value,10) > regionMax ? parseInt(yearValue.value, 10) : regionMax;
}, 0)
return parseInt(regionMax, 10) > totalMax ? parseInt(regionMax, 10) : totalMax;
}, 0)
var yScale = d3.scaleLinear().domain([0, totalMax]).range([h - padding, padding])
Я пишу демонстрационную базу для вашего кода:
var parseTime = d3.timeParse("%Y");
var margin = {
top: 20,
right: 20,
bottom: 30,
left: 50
},
w = 960 - margin.left - margin.right,
h = 500 - margin.top - margin.bottom;
var padding = 20;
/////////////////get the data//////////////////
const csv = `state,region,year,count
Alabama,South,2010,1
Alabama,South,2011,1
Alabama,South,2012,0
Alabama,South,2013,0
Alabama,South,2014,2
Alabama,South,2015,6
Alaska,West,2010,2245
Alaska,West,2011,1409
Alaska,West,2012,1166
Alaska,West,2013,1329
Alaska,West,2014,1296
Alaska,West,2015,1575
Connecticut,Northeast,2010,0
Connecticut,Northeast,2011,0
Connecticut,Northeast,2012,0
Connecticut,Northeast,2013,0
Connecticut,Northeast,2014,0
Connecticut,Northeast,2015,1
Missouri,Midwest,2010,2
Missouri,Midwest,2011,3
Missouri,Midwest,2012,2
Missouri,Midwest,2013,0
Missouri,Midwest,2014,1
Missouri,Midwest,2015,5
California,West,2010,546
California,West,2012,243
California,West,2013,240
Wyoming,West,2015,198
California,West,2011,195
California,West,2014,191`;
const dataset = d3.csvParse(csv);
dataset.forEach(function(d) {
d.date = parseTime(d.year);
d.region = d['region'];
d.state = d['state'];
d.count = d['count'];
});
var nest = d3.nest()
.key(function(d) {
return d.region;
})
.key(function(d) {
return d.date;
})
.rollup(function(leaves) {
return d3.sum(leaves, function(d) {
return parseInt(d.count, 10);
});
})
.entries(dataset)
/////////////////scales the data//////////////////
var xScale = d3.scaleTime()
.domain([d3.min(dataset, function(d) {
return d.date
}), d3.max(dataset, function(d) {
return d.date
})]).range([padding, w - padding * 2])
var totalMax = Object
.entries(nest)
.reduce(function(totalMax, [key, regionValue]){
const regionMax = Object
.entries(regionValue.values)
.reduce(function(regionMax, [key,yearValue]){
return parseInt(yearValue.value,10) > regionMax ? parseInt(yearValue.value, 10) : regionMax;
}, 0)
return parseInt(regionMax, 10) > totalMax ? parseInt(regionMax, 10) : totalMax;
}, 0)
var yScale = d3.scaleLinear()
.domain([0, totalMax]).range([h - padding, padding])
// var yScale = d3.scaleLinear()
// .domain([0, 3500])
// .range([h - padding, padding]) //not supposed to hard code the scale but it is not working otherwise...commented out above
var xAxis = d3.axisBottom().scale(xScale);
var yAxis = d3.axisLeft().scale(yScale);
/////////////////charts start here//////////////////
var svg = d3.select("body").append("svg")
.attr("width", w + margin.left + margin.right)
.attr("height", h + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
var svg1 = d3.select("body").append("svg")
.attr("width", w + margin.left + margin.right)
.attr("height", h + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
//Define the line
var valueLine = d3.line()
.x(function(d) {
return xScale(new Date(d.key));
})
.y(function(d) {
return yScale(d.value);
})
// Set the color scheme
var colors = d3.scaleOrdinal()
.domain(["South", "West", "Northeast","Midwest"])
.range(["#EF5285", "#88F284" , "#5965A3","#900C3F"]);
var regYear = svg.selectAll(".regYear")
.data(nest)
.enter()
.append("g")
.attr("stroke", function(d){ return colors(d.key)}); // Adding color!
var paths = regYear.selectAll(".line")
.data(function(d) {
return [d.values]
})
.enter()
.append("path");
// Draw the line
paths
.attr("d", function(d) {
return valueLine(d)
})
.attr("class", "line")
.style("fill", "none");
svg.selectAll(".dot")
.data(dataset)
.enter().append("circle") // Uses the enter().append() method
.attr("class", "dot") // Assign a class for styling
.attr("cx", function(d, i) { return xScale(i) })
.attr("cy", function(d) { return yScale(d.count) })//this is not working
.attr("r", 5);
svg.append("g").attr("class", "axis").attr("transform", "translate(0," + (h - padding) + ")").call(xAxis);
//draw Y axis
svg.append("g").attr("class", "axis").attr("transform", "translate(" + padding + ",0)").call(yAxis);
// add label
svg.append("text").attr("x", (w / 2)).attr("y", h + 30).attr("text-anchor", "middle").text("Year");
svg.append("text").attr("x", padding).attr("y", padding - 20).attr("text-anchor", "middle").text("# of Events");
//add title
svg.append("text").attr("x", (w / 2)).attr("y", padding).attr("text-anchor", "middle").text("Events per Year by Category");
// add legend
var legend = svg.append("g")
.attr("class", "legend")
.attr("x", w - 65)
.attr("y", 25)
.attr("height", 100)
.attr("width", 100);
////////////////////////////////////END///////////////////////////
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Nested Chart</title>
<script src="https://d3js.org/d3.v5.min.js"></script>
<style type="text/css">
.pagebreak {
page-break-before: always;
}
.axis path,
.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
}
.point {
fill: none;
size: 2px
}
.dot {
fill: #ffab00;
stroke: #fff;
}
</style>
</head>
<div style="width:800px; margin:0 auto;" class='body'></div>
<div class="pagebreak"> </div>
<body>
</body>
</html>
Я заметил, что тип данных вашего d.count
равен string
, поэтому максимальное значение не будет правильным.
console.log(d3.max(['6','2245'])) // it's 6!
Попробуйте преобразовать значение в number
перед его возвратом:
var yScale = d3.scaleLinear()
.domain([0, d3.max(dataset, function(d) {
return parseInt(d.count,10);
})])
.range([h - padding, padding])