D3.js 向响应式条形图添加图例

时间:2021-08-01 13:18:59

标签: javascript jquery d3.js

我从这个 Link 中找到了一个简单的响应条形图。所以,我对此做了一些小的修改,并在条形图中添加了图例。图表是响应式的,但不是图例。几天以来我一直在研究这个。我曾尝试将图例附加到 x 轴,但也不起作用。

<!doctype html>
  <html lang="en">
    <head>
      <title>Bootstrap Case</title>
        <meta charset="utf-8">
        <script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    </head>
    <style>
      .axis path,
      .axis line {
        fill: none;
        stroke: #bdbdbd;
      }
      .axis text {
        font-family: 'Open Sans regular', 'Open Sans';
        font-size: 13px;
      }
      .bar {
        fill: #8bc34a;
      }
      .bar:hover {
        fill: #039be4;
      }
    </style>
    <div id ="chartID"></div>
    <script>
        var data = [{
                "letter": "a",
                "frequency": "4.84914547592537",
                "Color": "#D3D3D3"
            },
            {
                "letter": "b",
                "frequency": "4.86872684269123",
                "Color": "#D3D3D3"
            },
            {
                "letter": "c",
                "frequency": "6.63842861065779",
                "Color": "#000000"
            },
            {
                "letter": "d",
                "frequency": "6.53280838923937",
                "Color": "#000000"
            }
        ]
        var data2 = [];

        for (var i = 0; i < 2; i++) {
            data2.push(data[i]);
        }

        var color_hash = {
            0: ["Control", "#D3D3D3"],
            1: ["Case", "#000000"]
        }

        var margin = {
            top: 30,
            right: 100,
            bottom: 20,
            left: 80
        };

        var width = 960 - margin.left - margin.right;

        var height = 500 - margin.top - margin.bottom;

        var xScale = d3.scale.ordinal().rangeRoundBands([0, width], .1)

        var yScale = d3.scale.linear()
            .range([height, 0]);


        var xAxis = d3.svg.axis()
            .scale(xScale)
            .orient("bottom");

        var yAxis = d3.svg.axis()
            .scale(yScale)
            .orient("left");

        var svgContainer = d3.select("#chartID").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 + ")");

        xScale.domain(data.map(function (d) {
            return d.letter;
        }));
        yScale.domain([0, d3.max(data, function (d) {
            return d.frequency;
        })]);


        var xAxis_g = svgContainer.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + (height) + ")")
            .call(xAxis);

        var yAxis_g = svgContainer.append("g")
            .attr("class", "y axis")
            .call(yAxis)
            .append("text")
            .attr("dx", "-10em")
            .attr("transform", "rotate(-90)")
            .attr("y", 6).attr("dy", "-4.0em")
            .style("text-anchor", "end").text("Expression values");

        svgContainer.selectAll(".bar")
            .data(data)
            .enter().append("rect")
            .attr("class", "bar")
            .attr("x", function (d) {
                return xScale(d.letter);
            })
            .attr("width", xScale.rangeBand())
            .attr("y", function (d) {
                return yScale(d.frequency);
            })
            .attr("height", function (d) {
                return height - yScale(d.frequency);
            })
            .style("fill", function (d) {
                return d.Color;
            });

        // Add Legends
        var legend = svgContainer.append("g")
            // .attr("transform", "translate(0," + (10) + ")")
            // .attr("x", width - 100)
            // .attr("y", 250)
            // .attr("height", 100)
            // .attr("width", 100);

        legend.selectAll('g').data(data2)
            .enter()
            .append('g')
            .each(function (d, i) {
                var g = d3.select(this);
                g.append("rect")
                    // .attr("class", "legend")
                    .attr("x", width)
                    .attr("y", i * 25)
                    .attr("width", 10)
                    .attr("height", 10)
                    .style("fill", color_hash[String(i)][1]);

                g.append("text")
                    // .attr("class", "legend")
                    .attr("x", width - 20 * -1)
                    .attr("y", i * 25 + 8)
                    // .attr("height", 30)
                    // .attr("width", 100)
                    // .style("text-anchor", "end")
                    .style("font-size", 16)
                    .text(color_hash[String(i)][0]);
            });

        d3.select(window).on('resize', resize);

        function resize() {
            // console.log('----resize function----');
            // update width

            width = parseInt(d3.select('#chartID').style('width'), 10);
            width = width - margin.left - margin.right;

            height = parseInt(d3.select("#chartID").style("height"));
            height = height - margin.top - margin.bottom;
            // console.log('----resiz width----' + width);
            // console.log('----resiz height----' + height);
            // resize the chart

            if (width < 870) {
                //xScale.range([0, width]);
                xScale.rangeRoundBands([0, width], .1);
                yScale.range([height, 0]);

                yAxis.ticks(Math.max(height / 50, 2));
                xAxis.ticks(Math.max(width / 50, 2));

                d3.select(svgContainer.node().parentNode)
                    .style('width', (width + margin.left + margin.right) + 'px');

                svgContainer.selectAll('.bar')
                    .attr("x", function (d) {
                        return xScale(d.letter);
                    })
                    .attr("width", xScale.rangeBand());

                // svgContainer.selectAll('.legend')
                //     .attr("x", function (d) {
                //         return ;
                //     })
                //     .attr("width", xScale.rangeBand());

                svgContainer.select('.x.axis').call(xAxis.orient('bottom'));
                // svgContainer.select('.legend');
            }
        }

    </script>
  </html>
  

需要一些帮助。

谢谢。

0 个答案:

没有答案