我有这些带有堆叠条形图的旧代码示例。最好清理代码并将其从d3版本3升级到4。我认为可以改善图表本身的动画效果-也许是数据结构,如果这是将其引入图表的最佳方法。我认为当条形图向上运动时,文本标签会向下运动-有点奇怪吗?
var initialHeight = 0;
var barholder = d3.select(selector + " .barholder");
//_morph stacks
var stacks = barholder.selectAll(".stack")
.data(data);
// Enter
stacks.enter()
.append("g")
.attr("class", "stack")
.attr("x", function(d) {
return methods.x(d.Label);
})
.attr("transform", function(d) {
return "translate(" + methods.x(d.Label) + ",0)";
});
// Update
stacks
.attr("x", function(d) {
return methods.x(d.Label);
})
.transition()
.duration(500)
.attr("x", function(d) {
return methods.x(d.Label);
})
.attr("transform", function(d) {
return "translate(" + methods.x(d.Label) + ",0)";
});
// Exit
stacks.exit()
.transition()
.duration(250)
.attr("x", function(d) {
return methods.x(d.Label);
})
.remove();
//_morph stacks
//_morph bars
var bar = stacks.selectAll("rect")
.data(function(d) {
return d.blocks;
});
// Enter
bar.enter()
.append("rect")
.attr("class", "bar")
.attr("y", function(d) {
return methods.y(d.y1);
})
.attr("width", methods.x.rangeBand())
.style("fill", function(d) {
return methods.color(d.name);
});
// Update
bar
.attr("y", methods.height)
.attr("height", initialHeight)
.attr("width", methods.x.rangeBand())
.transition()
.duration(500)
.attr("x", function(d) {
return methods.x(d.Label);
})
.attr("width", methods.x.rangeBand())
.attr("y", function(d) {
return methods.y(d.y1);
})
.attr("height", function(d) {
return methods.y(d.y0) - methods.y(d.y1);
})
// Exit
bar.exit()
.transition()
.duration(250)
.attr("y", function(d) {
return methods.y(d.y1);
})
.attr("height", function(d) {
methods.y(d.y0) - methods.y(d.y1);
})
.remove();
//__morph bars
//堆积图1版本3 https://jsfiddle.net/4x6thm08/1/
//堆积图2版本3 https://jsfiddle.net/msh14f5d/2/
所以我试图清理代码库
//堆叠图表-版本4-正在进行中 我从这个jsfiddle开始清理基本结构 https://jsfiddle.net/vdwhkLs8/1/
我正在得到范围限制而不是函数错误。
完整的代码
<!DOCTYPE html>
<html>
<head>
<title>StackedChart I</title>
<!--libs-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
<!--js-->
<script>
$(document).ready(function() {
var $this = $('.stackedchart');
var data = [{
"Pizza": 3,
"Pancakes": 0.001,
"label": "Bombay, India"
},
{
"Pizza": 32,
"Pancakes": 20,
"label": "Dallas, United States"
},
{
"Pizza": 33,
"Pancakes": 330,
"label": "Detroit, United States"
}
];
var width = $this.data('width'),
height = $this.data('height');
var color = d3.scaleOrdinal()
.range(["#eb6383", "#fa9191", "#ffe9c5", "#b4f2e1"]);
data.forEach(function(d) {
d.total = +d.value;
});
var margin = {top: 20, right: 5, bottom: 30, left: 20},
width = width - margin.left - margin.right,
height = height - margin.top - margin.bottom;
var x = d3.scaleBand()
.range([0, width])
.padding(0.1);
var y = d3.scaleLinear()
.range([height, 0]);
x.domain(data.map(function(d) { return d.label; }));
y.domain([0, d3.max(data, function(d) { return d.total; })]);
var svg = d3.select($this[0])
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr('class', 'stackedchart')
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var stacked = svg.append('g').attr('class', 'stacked');
/*
bars.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr('fill', function(d, i) {
return color(i);
})
.attr("x", function(d) { return x(d.label); })
.attr("width", x.bandwidth())
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.total); });
bars.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
bars.append("g")
.call(d3.axisLeft(y));*/
//var data = data.slice(0);
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "label"; }));
data.forEach(function(d) {
var y0 = 0;
d.blocks = color.domain().map(function(name) {
var val = d[name];
if(isNaN(val)){
val = 0;
}
return {name: name, values: val, y0: y0, y1: y0 += +val};
});
d.total = d.blocks[d.blocks.length - 1].y1;
});
//_morph stacks
var stacks = stacked.selectAll(".stack")
.data(data);
// Enter
stacks.enter()
.append("g")
.attr("class", "stack")
.attr("x", function(d) { return x(d.label);})
.attr("transform", function(d) {
return "translate(" + x(d.label) + ",0)";
});
// Update
stacks
.attr("x", function(d) { return x(d.label);})
.transition()
.duration(500)
.attr("x", function(d) { return x(d.label); })
.attr("transform", function(d) {
return "translate(" + x(d.label) + ",0)";
});
// Exit
stacks.exit()
.transition()
.duration(250)
.attr("x", function(d) { return x(d.label);})
.remove();
//_morph stacks
var blockData = data.map(d => d.blocks);
console.log("blockData", blockData)
var initialHeight = 0;
$.each(blockData, function( index, value ) {
var bar = stacked.selectAll(".bar")
.data(value);
// array1.map(x => x * 2)
// Enter
bar.enter()
.append("rect")
.attr("class", "bar")
.attr("y", function(d) {
console.log("y(d['y1'])", y(d['y1']))
return 23//y(d['y1']);
})
.attr("width", x.bandwidth())
.style("fill", function(d) {
console.log("d", d)
return "blue";
//return color(d.name);
});
bar
.attr("y", height)
.attr("height", 40)//.attr("height", initialHeight)
.attr("width", x.bandwidth())
.transition()
.duration(500)
.attr("x", function(d) { return x(d.label); })
.attr("width", x.bandwidth())
.attr("y", function(d) {
return 60;
//return y(d['y1']);
})
//.attr("height", function(d) { return y(d.y0) - y(d.y1); })
/*
// Exit
bar.exit()
.transition()
.duration(250)
.attr("y", function(d) { return methods.y(d.y1); })
//.attr("height", function(d) { methods.y(d.y0) - methods.y(d.y1); })
.remove();
*/
});
/*
// Update
bar
.attr("y", height)
.attr("height", initialHeight)
.attr("width", x.bandwidth())
.transition()
.duration(500)
.attr("x", function(d) { return x(d.label); })
.attr("width", x.bandwidth())
.attr("y", function(d) { return y(d.y1); })
.attr("height", function(d) { return y(d.y0) - y(d.y1); })
// Exit
bar.exit()
.transition()
.duration(250)
.attr("y", function(d) { return y(d.y1); })
.attr("height", function(d) { y(d.y0) - y(d.y1); })
.remove();
*/
});
</script>
<!--js-->
<!--css-->
<style>
body {
background: #ffd;
}
</style>
<!--css-->
</head>
<body>
<h1>StackedChart I</h1>
<!--html-->
<div
class="stackedchart"
data-width="300"
data-height="300"
/>
<!--html-->
</body>
</html>
我获取初始数据-并循环遍历以计算不同的块-在这里我将label属性排除为彩色条。
data.forEach(function(d) {
var y0 = 0;
d.blocks = color.domain().map(function(name) {
var val = d[name];
if(isNaN(val)){
val = 0;
}
return {name: name, values: val, y0: y0, y1: y0 += +val};
});
d.total = d.blocks[d.blocks.length - 1].y1;
});
---虽然会发生故障-在我制作了堆栈g元素并尝试将条形图嵌套在堆栈占位符之后-由于某种原因,域数据无法正常工作?像y(d.y1)变成NAN。
//_morph stacks
var stacks = stacked.selectAll(".stack")
.data(data);
// Enter
stacks.enter()
.append("g")
.attr("class", "stack")
.attr("x", function(d) { return x(d.label);})
.attr("transform", function(d) {
return "translate(" + x(d.label) + ",0)";
});
// Update
stacks
.attr("x", function(d) { return x(d.label);})
.transition()
.duration(500)
.attr("x", function(d) { return x(d.label); })
.attr("transform", function(d) {
return "translate(" + x(d.label) + ",0)";
});
// Exit
stacks.exit()
.transition()
.duration(250)
.attr("x", function(d) { return x(d.label);})
.remove();
//_morph stacks
var blockData = data.map(d => d.blocks);
console.log("blockData", blockData)
var initialHeight = 0;
$.each(blockData, function( index, value ) {
var bar = stacked.selectAll(".bar")
.data(value);
// array1.map(x => x * 2)
// Enter
bar.enter()
.append("rect")
.attr("class", "bar")
.attr("y", function(d) {
console.log("y(d['y1'])", y(d['y1']))
return 23//y(d['y1']);
})
.attr("width", x.bandwidth())
.style("fill", function(d) {
console.log("d", d)
return "blue";
//return color(d.name);
});
bar
.attr("y", height)
.attr("height", 40)//.attr("height", initialHeight)
.attr("width", x.bandwidth())
.transition()
.duration(500)
.attr("x", function(d) { return x(d.label); })
.attr("width", x.bandwidth())
.attr("y", function(d) {
return 60;
//return y(d['y1']);
})
//.attr("height", function(d) { return y(d.y0) - y(d.y1); })
/*
// Exit
bar.exit()
.transition()
.duration(250)
.attr("y", function(d) { return methods.y(d.y1); })
//.attr("height", function(d) { methods.y(d.y0) - methods.y(d.y1); })
.remove();
*/
});