[英]How to add text-based legend to D3.js chart
我只是想知道如何在D3.js图表中添加一个带有文本的框。 它将充当我的图例,并在x轴上描述每个变量。 它应该看起来像这样 。
我想将此json数组中的每个“ wuc”标签与“ nomenclature”标签进行匹配:
data = [{
"Wuc": "23A",
"Nomenclature": "Engine, Basic (F117-PW)",
"Hours": 155899.90
},
{
"Wuc": "23V",
"Nomenclature": "Fan Thrust Reverser",
"Hours": 56576
}
]
底部代码用于我的D3.js图表。 谢谢您的帮助!
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<style>
.bars:hover {
fill: blue;
}
.legend:hover {
fill: blue;
}
/* tooltip for bar chart */
div.tooltip {
position: absolute;
text-align: center;
width: 50px;
height: 60px;
padding: 2px;
font: 12px sans-serif;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
</style>
<div id="bar_chart">
</div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
// d3.json("data.json", function(error, data) {
// if (error) throw error;
// var parseTime = d3.timeParse("%M:%S");
// var timeformat = d3.timeFormat("%M:%S")
data = [{
"Wuc": "23A",
"Nomenclature": "Engine, Basic (F117-PW)",
"Hours": 155899.90
},
{
"Wuc": "23V",
"Nomenclature": "Fan Thrust Reverser",
"Hours": 56576
}
]
data.forEach(function(d) {
// d.atime = parseTime(d.atime);
d.Hours = +d.Hours;
});
var margin = {
top: 70,
right: 50,
bottom: 100,
left: 80
},
width = 600 - margin.left - margin.right,
height = 600 - margin.top - margin.bottom;
//Define the div for the tooltip
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var x = d3.scaleBand()
.domain(data.map(function(d) {
return d.Wuc
}))
.range([0, width])
.padding([0.8]); //sets decimal of the space between bar centres
var y = d3.scaleLinear()
.domain([0, d3.max(data, function(d) {
return d.Hours
})])
.range([height, 0]);
var svg = d3.select("#bar_chart")
.data(data)
.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 + ")");
// Add the X Axis
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// text label for the x axis
svg.append("text")
.attr("x", width / 2)
.attr("y", margin.top + height)
.style("text-anchor", "middle")
.style("font-weight", "bold")
.text("x-Axis Title");
// Add the Y Axis
svg.append("g")
.attr("class", "axis")
.call(d3.axisLeft(y)
.ticks(5));
// text label for the y axis
svg.append("text")
.attr("class", "blah")
.attr("transform", "rotate(-90)")
.attr("x", 0 - height / 2)
.attr("y", -50)
.style("text-anchor", "middle")
.style("font-weight", "bold")
.text("y-Axis Title");
// graph main title
svg.append("text")
.attr("x", width / 2)
.attr("y", -20)
.style("text-anchor", "middle")
.style("font-weight", "bold")
.style("font-size", "20px")
.text("Main Title");
//********* Bar Chart ****************
var rects = svg.selectAll('rect')
.data(data)
.enter();
rects.append('rect')
.on("mouseover", function(d, i, node) { //this is repeated should be in a function
div.transition()
.duration(200)
.style("opacity", .85);
div.html("<strong> Name:</strong> " + d.Wuc + "</br><strong> Value:</strong> " + d.Hours)
.style("left", (d3.event.pageX + 5) + "px")
.style("top", (d3.event.pageY - 28) + "px");
d3.select(this)
.style("fill", "blue");
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
d3.select(this)
.style("fill", "lightblue");
})
.attr("class", "bars") //should fill blue on mouseover, not working???
.attr('x', function(d, i) {
return x(d.Wuc);
})
.attr('y', function(d, i) {
return y(d.Hours);
})
.attr('height', function(d, i) {
return height - y(d.Hours)
})
.attr('width', x.bandwidth())
.attr("transform", "translate(0,0)")
.style('fill', 'lightblue')
.style('stroke', 'lightgray');
// }); //closes function d3.json("data.json", function(error, data) {.....
</script>
您可以简单地在svg后面加上“ rect”,也可以在文本后面加上数据。
<!DOCTYPE html> <meta charset="utf-8"> <body> <style> .bars:hover { fill: blue; } .legend:hover { fill: lightblue; } /* tooltip for bar chart */ div.tooltip { position: absolute; text-align: center; width: 50px; height: 60px; padding: 2px; font: 12px sans-serif; background: lightsteelblue; border: 0px; border-radius: 8px; pointer-events: none; } </style> <div id="bar_chart"> </div> <script src="https://d3js.org/d3.v4.min.js"></script> <script> // d3.json("data.json", function(error, data) { // if (error) throw error; // var parseTime = d3.timeParse("%M:%S"); // var timeformat = d3.timeFormat("%M:%S") data = [{ "Wuc": "23A", "Nomenclature": "Engine, Basic (F117-PW)", "Hours": 155899.90 }, { "Wuc": "23V", "Nomenclature": "Fan Thrust Reverser", "Hours": 56576 } ] data.forEach(function(d) { // d.atime = parseTime(d.atime); d.Hours = +d.Hours; }); var margin = { top: 70, right: 50, bottom: 100, left: 80 }, width = 600 - margin.left - margin.right, height = 600 - margin.top - margin.bottom; //Define the div for the tooltip var div = d3.select("body").append("div") .attr("class", "tooltip") .style("opacity", 0); var x = d3.scaleBand() .domain(data.map(function(d) { return d.Wuc })) .range([0, width]) .padding([0.8]); //sets decimal of the space between bar centres var y = d3.scaleLinear() .domain([0, d3.max(data, function(d) { return d.Hours })]) .range([height, 0]); var svg = d3.select("#bar_chart") .data(data) .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 + ")"); // Add the X Axis svg.append("g") .attr("class", "axis") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x)); // text label for the x axis svg.append("text") .attr("x", width / 2) .attr("y", margin.top + height) .style("text-anchor", "middle") .style("font-weight", "bold") .text("x-Axis Title"); // Add the Y Axis svg.append("g") .attr("class", "axis") .call(d3.axisLeft(y) .ticks(5)); // text label for the y axis svg.append("text") .attr("class", "blah") .attr("transform", "rotate(-90)") .attr("x", 0 - height / 2) .attr("y", -50) .style("text-anchor", "middle") .style("font-weight", "bold") .text("y-Axis Title"); // graph main title svg.append("text") .attr("x", width / 2) .attr("y", -20) .style("text-anchor", "middle") .style("font-weight", "bold") .style("font-size", "20px") .text("Main Title"); //************* Legend *************** // add legend rect gray svg.append("rect") .attr("class", "legend") .attr("x", 280) .attr("y", 30) .attr("rx", "5px") .attr("width", 230) .attr("height", 80) .attr("stroke", "darkgray") .attr("fill", "white"); var legend_text = svg.selectAll("legend_text") .data(data) .enter(); legend_text.append("text") .attr("class", "legend_text") .attr("x", 290) .attr("y", function(d, i) { return (i * 20) + 40; }) .attr("dy", "0.32em") .style("font-weight", "bold") .text(function(d) { return d.Wuc + " " + d.Nomenclature; }); //********* Bar Chart **************** var rects = svg.selectAll(".bars") .data(data) .enter(); rects.append('rect') .attr("class", "bars") .on("mouseover", function(d, i, node) { //this is repeated should be in a function div.transition() .duration(200) .style("opacity", .85); div.html("<strong> Name:</strong> " + d.Wuc + "</br><strong> Value:</strong> " + d.Hours) .style("left", (d3.event.pageX + 5) + "px") .style("top", (d3.event.pageY - 28) + "px"); d3.select(this) .style("fill", "blue"); }) .on("mouseout", function(d) { div.transition() .duration(500) .style("opacity", 0); d3.select(this) .style("fill", "lightblue"); }) .attr("class", "bars") //should fill blue on mouseover, not working??? .attr('x', function(d, i) { return x(d.Wuc); }) .attr('y', function(d, i) { return y(d.Hours); }) .attr('height', function(d, i) { return height - y(d.Hours) }) .attr('width', x.bandwidth()) .attr("transform", "translate(0,0)") .style('fill', 'lightblue') .style('stroke', 'lightgray'); // }); //closes function d3.json("data.json", function(error, data) {..... </script>
您可能还想使rect的高度动态化以适合不同数量的数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.