我目前正在学习D3js。
目前我正在制作热图来学习 D3js 的基础知识。
现在我遇到了一个问题,我无法真正找到解决方案。
我创建了一个 ColorScale 图例,并想用它插入标签。
有人给我提示吗?如果有任何建议,我将非常感激!
请参阅下面的我的代码。
致以诚挚的问候 杰戈尔
<!DOCTYPE html>
<html>
<!-- Code Vorschlage mit STRG+Leertaste aktivieren-->
<head>
<meta charset="utf-8" /> <!-- Welche Sonderzeichen verwendet werden können -->
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <!-- Wie sollte sich die Seite auf einem Handy verhalten -->
<title> 1.Grundgerüst </title> <!-- title als Tag -->
<style>
</style>
</head>
<body>
<div id="heatmap"></div>
<script src="https://d3js.org/d3.v7.js" charset="utf-8"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script>
//Datasource
const data = [
{group:"A",variable:"v1",value:"30"},{group:"A",variable:"v2",value:"95"},
{group:"A",variable:"v3",value:"22"},{group:"A",variable:"v4",value:"14"},
{group:"A",variable:"v5",value:"59"},{group:"A",variable:"v6",value:"52"},
{group:"A",variable:"v7",value:"88"},{group:"A",variable:"v8",value:"20"},
{group:"A",variable:"v9",value:"99"},{group:"A",variable:"v10",value:"66"},
{group:"B",variable:"v1",value:"37"},{group:"B",variable:"v2",value:"50"},
{group:"B",variable:"v3",value:"81"},{group:"B",variable:"v4",value:"79"},
{group:"B",variable:"v5",value:"84"},{group:"B",variable:"v6",value:"91"},
{group:"B",variable:"v7",value:"82"},{group:"B",variable:"v8",value:"89"},
{group:"B",variable:"v9",value:"6"},{group:"B",variable:"v10",value:"67"},
{group:"C",variable:"v1",value:"96"},{group:"C",variable:"v2",value:"13"},
{group:"C",variable:"v3",value:"98"},{group:"C",variable:"v4",value:"10"},
{group:"C",variable:"v5",value:"86"},{group:"C",variable:"v6",value:"23"},
{group:"C",variable:"v7",value:"74"},{group:"C",variable:"v8",value:"47"},
{group:"C",variable:"v9",value:"73"},{group:"C",variable:"v10",value:"40"},
{group:"D",variable:"v1",value:"75"},{group:"D",variable:"v2",value:"18"},
{group:"D",variable:"v3",value:"92"},{group:"D",variable:"v4",value:"43"},
{group:"D",variable:"v5",value:"16"},{group:"D",variable:"v6",value:"27"},
{group:"D",variable:"v7",value:"76"},{group:"D",variable:"v8",value:"24"},
{group:"D",variable:"v9",value:"1"},{group:"D",variable:"v10",value:"87"},
{group:"E",variable:"v1",value:"44"},{group:"E",variable:"v2",value:"29"},
{group:"E",variable:"v3",value:"58"},{group:"E",variable:"v4",value:"55"},
{group:"E",variable:"v5",value:"65"},{group:"E",variable:"v6",value:"56"},
{group:"E",variable:"v7",value:"9"},{group:"E",variable:"v8",value:"78"},
{group:"E",variable:"v9",value:"49"},{group:"E",variable:"v10",value:"36"},
{group:"F",variable:"v1",value:"35"},{group:"F",variable:"v2",value:"80"},
{group:"F",variable:"v3",value:"8"},{group:"F",variable:"v4",value:"46"},
{group:"F",variable:"v5",value:"48"},{group:"F",variable:"v6",value:"100"}
];
// Setze Dimension und Größe
var i_width = 800;
var i_height = 450;
const margin = {top: 40, right: 50, bottom: 40, left: 50};
const width = i_width - margin.left - margin.right;
const height = i_height - margin.top - margin.bottom;
const extent = d3.extent(data, d => d.value);
// Holt mir die Unique Group und Variables von der Datenquelle für die X- und Y-Achse
const myGroups = data.map(function(d){return d.group})
const myVars = data.map(function(d){return d.variable})
//-----------------------------------------------------------------------------------
// Anfügen von svg Elementen zu #heatmap
const svg = d3.select("#heatmap")
.append("svg") //Anfügen von svg an #heatmap
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
const g_area = d3.select("svg")
// Anfügen einer Gruppe an das SVG Element
.append("g") //Anfügen von g (Groups) an svg
.attr("id", "hm_area")
.attr("transform", `translate(${margin.left},${margin.top})`);
//-----------------------------------------------------------------------------------
// Color Skalierung
const myColor = d3.scaleLinear()
.range(["white", "#6e69b3" /*"#69b3a2"*/])
.domain([extent[0],extent[1]])
//-----------------------------------------------------------------------------------
// X-Skalierung
const x = d3.scaleBand()
.range([0, width])
.domain(myGroups)
.padding(0.01);
// X-Achse erstellen
const xAxis = g_area
.append("g")
.attr("id", "hm_x_axis")
xAxis.append("g")
.attr("id", "hm_x_axis_value")
.attr("transform", `translate(0, ${height})`)
.style("color", "rgba(0, 0, 0, 0.65)")
.style("font-size", "16px")
.style("font-family", "arial")
.call(d3.axisBottom(x));
// Einfügen xAxis Label
xAxis.append("text")
.attr("id", "hm_x_axis_label")
.attr("x", width / 2)
.attr("y", height + 40)
.style("fill", "rgba(0, 0, 0, 0.65)")
.style("font-size", "18px")
.style("font-family", "sans-serif")
.attr("text-anchor", "middle")
.text("Label X");
//-----------------------------------------------------------------------------------
// Y-Skalierung
const y = d3.scaleBand()
.range([height, 0])
.domain(myVars)
.padding(0.03);
// Y-Achse erstellen
const yAxis = g_area
.append("g")
.attr("id", "hm_y_axis")
yAxis.append("g")
.attr("id", "hm_y_axis_value")
.style("color", "rgba(0, 0, 0, 0.65)")
.style("font-size", "16px")
.style("font-family", "arial")
.call(d3.axisLeft(y));
// Einfügen yAxis Label
yAxis.append("text")
.attr("id", "hm_y_axis_label")
.attr("y", - 35) //Y ist hierbei die horizontale ausrichtung
.attr("x", - height / 2) //X ist hierbei die vertikale ausrichtung
.attr("transform", "rotate(-90)")
.style("fill", "rgba(0, 0, 0, 0.65)")
.style("font-size", "18px")
.style("font-family", "sans-serif")
.attr("text-anchor", "middle")
.text("Label Y");
//-----------------------------------------------------------------------------------
// Erstellen eines Tooltip
const tooltip = d3.select("#heatmap")
.append("div")
.attr("id", "tooltip")
.style("position", "absolute")
.style("opacity", 0)
.style("background-color", "white")
.style("border", "solid")
.style("border-width", "2px")
.style("border-radius", "5px")
.style("padding", "5px");
const mouseover = function(event,d) {
tooltip
.style("opacity", 1)
d3.select(this).select(".hm_node")
.style("stroke", "black")
.style("stroke-width", "2px")
};
const mousemove = function(event,d) {
tooltip
.html("Wert: " + d.value)
.style("left", (event.x) + 20 + "px")
.style("top", (event.y) - 10 + "px")
};
const mouseleave = function(d) {
tooltip.style("opacity", 0)
d3.select(this).select(".hm_node")
.style("stroke", "none")
};
//-----------------------------------------------------------------------------------
// Erstellen von Rechtecken
// Wird erstellt um den node sowie sein Label in eine gruppe (g) zu packen
const g_nodes = g_area
.append("g")
.attr("id", "hm_nodes")
.selectAll("rect")
.data(data)
.enter()
//FÜr jeden Datensatz ein "g" Element erstellen
.append("g")
.attr("class", "hm_node_grp")
.attr("group", function(d) {return d.group})
.attr("variable",function(d) {return d.variable})
.attr("value", function(d) {return d.value})
.on("mouseover", mouseover)
.on("mousemove", mousemove)
.on("mouseleave", mouseleave)
.on("click", function(d, i){console.log(i)});
const rect_node = g_nodes
.append("rect") //Anfügen von RECT-Elementen
.attr("x", function(d) {return x(d.group)})
.attr("y", function(d) {return y(d.variable)})
.attr("id", "hm_node")
// "Bandwidth" ist über die Methode "BandScale" verfügbar
.attr("width", x.bandwidth())
.attr("height", y.bandwidth())
.style("fill", function(d) {return myColor(d.value)})
// Einfügen der Labels zu den Rechtecken
const rect_label = g_nodes
.append("text")
.attr("class", "hm_label")
.attr("x", (d) => x(d.group))
.attr("y", (d) => y(d.variable))
.attr("dx", x.bandwidth()/2)
.attr("dy", y.bandwidth()/2)
.attr("text-anchor", "middle")
.attr("dominant-baseline", "central")
.style("font-size", "12px")
.style("font-family", "sans-serif")
.text((d) => d.value);
//-----------------------------------------------------------------------------------
// ColorScale Legend
const GradColors = [myColor(extent[1]), myColor(extent[0])];
const g_colorScale = g_area
.append("g")
const g_def = g_colorScale.append("defs")
.append("linearGradient")
.attr("id", "grad")
.attr("x1", "0%")
.attr("x2", "0%")
.attr("y1", "0%")
.attr("y2", "100%");
g_def.selectAll("stop")
.data(GradColors)
.enter()
.append("stop")
.style("stop-color", function(d){ return d; })
.attr("offset", function(d,i){
return 100 * (i / (GradColors.length - 1)) + "%";
})
g_colorScale.append("rect")
.attr("id", "hm_colorScale_legend")
.attr("x", width + 30)
.attr("y", (height / 2) - 150)
.attr("width", 15)
.attr("height", 300)
.attr("rx", "4px")
.attr("text-anchor", "middle")
.style("fill", "url(#grad)");
</script>
</body> <!-- HTML schließender Tag-->
</html> <!-- HTML schließender Tag-->