如何向 ColorScale 图例添加标签 - D3 热图

问题描述 投票:0回答:0

我目前正在学习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-->
javascript d3.js heatmap
© www.soinside.com 2019 - 2024. All rights reserved.