Как я могу преобразовать эту горизонтальную гистограмму в вертикальную гистограмму - PullRequest
0 голосов
/ 20 октября 2019

Я относительно новичок в d3.js. Я работаю над проектом, в котором мне нужно отобразить графики в моем веб-приложении. Я нашел код, который частично делал то, что мне было нужно, но график - это горизонтальная гистограмма, а мне нужна вертикальная (столбчатая диаграмма).

Я попытался переключить ось, поскольку это имело логический смысл, но я думаю, что где-то запутался ... Может кто-нибудь помочь мне с преобразованием этой гистограммы в столбчатую диаграмму?

HTML-код:

      <div class="container">
        <div class="row">
            <div class="col-md-4">
                <div class="panel panel-default">
                    <div class="panel-body">
                        <form role="form" class="categories">
                        </form>
                    </div>
                </div>
            </div>
            <div class="col-md-8">
                <div class="graph"></div>
            </div>
        </div>
    </div>

Графический код:

           var data = [{
                year: '1990',
                stats: [454.2894, 2420.8398, 5122.7559]
            },
            {
                year: '1995',
                stats: [569.3625, 2387.0628, 5041.4598]
            },
            {
                year: '2000',
                stats: [ 783.59, 2337.01, 4877.29]
            },
            {
                year: '2005',
                stats: [ 807.86, 2555.67, 4634.35]
            },
            {
                year: '2010',
                stats: [ 1060.82, 2687.81, 4249.26]
            },
            {
                year: '2015',
                stats: [ 1215.32, 2757.62, 4024.94]
            }
        ];

        var ids = ['mangroves', 'water', 'others'];
        var statistics = ['Mangroves', 'Water', 'Others'];

        // Let's populate the categoeries checkboxes
        d3.select('.categories').selectAll('.checkbox')
            .data(ids)
            .enter()
            .append('div')
            .attr('class', 'checkbox')
            .append('label').html(function(id, index) {
                var checkbox = '<input id="' + id + '" type="checkbox" class="category">';
                return checkbox + statistics[index];
            });

        // some variables declarations
        var margin = {
                top: 20,
                right: 20,
                bottom: 30,
                left: 40
            },
            width = 800 - margin.left - margin.right,
            height = 400 - margin.top - margin.bottom;

        // the scale for the year statistic value
        var x = d3.scale.linear().range([0, width]);

        // the scale for each year
        var y0 = d3.scale.ordinal().rangeBands([0, height], .1);
        // the scale for each year statistic
        var y1 = d3.scale.ordinal();

        // just a simple scale of colors
        var color = d3.scale.ordinal()
            .range(["#00ff00", "#0000ff", "#cccccc"]);

        //
        var xAxis = d3.svg.axis()
            .scale(x)
            .orient("bottom")
            .tickFormat(d3.format(".2s"));

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

        var svg = d3.select(".graph").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 + ")");

        d3.select('.categories').selectAll('.category').on('change', function() {
            var x = d3.select('.categories').selectAll('.category:checked');
            var ids = x[0].map(function(category) {
                return category.id;
            });
            updateGraph(ids);
        });
        renderGraph();

        function renderGraph() {
            x.domain([0, 0]);
            // y0 domain is all the year names
            y0.domain(data.map(function(d) {
                return d.year;
            }));
            // y1 domain is all the statistic names, we limit the range to from 0 to a y0 band
            y1.domain(statistics).rangeRoundBands([0, y0.rangeBand()]);

            svg.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(0," + height + ")")
                .call(xAxis);

            svg.append("g")
                .attr("class", "y axis")
                .call(yAxis)
        }

        function updateGraph(selectedIds) {

            var statesData = data.map(function(stateData) {
                return {
                    year: stateData.year,
                    datas: selectedIds.map(function(selectedId) {
                        var index = ids.findIndex(function(id) {
                            return selectedId === id;
                        });
                        return {
                            id: ids[index],
                            name: statistics[index],
                            value: stateData.stats[index]
                        };
                    })
                }
            });


            // x domain is between 0 and the maximun value in any datas.value
            x.domain([0, d3.max(statesData, function(d) {
                return d3.max(d.datas, function(d) {
                    return d.value
                });
            })]);
            // y0 domain is all the year names
            y0.domain(statesData.map(function(d) {
                return d.year;
            }));
            // y1 domain is all the statistic names, we limit the range to from 0 to a y0 band
            y1.domain(ids).rangeRoundBands([0, y0.rangeBand()]);

            svg.selectAll('.axis.x').call(xAxis);
            svg.selectAll('.axis.y').call(yAxis);

            var year = svg.selectAll(".year")
                .data(statesData);

            year.enter().append("g")
                .attr("class", "year")
                .attr("transform", function(d) {
                    return "translate(0, " + y0(d.year) + ")";
                });

            var statistic = year.selectAll("rect")
                .data(function(d) {
                    return d.datas;
                });

            // we append a new rect every time we have an extra data vs dom element
            statistic.enter().append("rect")
                .attr('width', 0);

            // this updates will happend neither inserting new elements or updating them
            statistic
                .attr("x", 0)
                .attr("y", function(d, index) {
                    return y1(ids[index]);
                })
                .attr("id", function(d) {
                    return d.id;
                })
                .style("fill", function(d) {
                    return color(d.name);
                })
                .text(function(d) {
                    return d.name
                })
                .transition()
                .attr("width", function(d) {
                    return x(d.value);
                })
                .attr("height", y1.rangeBand());

            statistic.exit().transition().attr("width", 0).remove();

            var legend = svg.selectAll(".legend")
                .data(statesData[0].datas.map(function(statistic) {
                    return statistic.name;
                }));

            legend.enter().append("g");
            legend
                .attr("class", "legend")
                .attr("transform", function(d, i) {
                    return "translate(0," + (200 + i * 20) + ")";
                });

            var legendColor = legend.selectAll('.legend-color').data(function(d) {
                return [d];
            });
            legendColor.enter().append("rect");
            legendColor
                .attr('class', 'legend-color')
                .attr("x", width - 18)
                .attr("width", 18)
                .attr("height", 18)
                .style("fill", color);

            var legendText = legend.selectAll('.legend-text').data(function(d) {
                return [d];
            });;

            legendText.enter().append("text");
            legendText
                .attr('class', 'legend-text')
                .attr("x", width - 24)
                .attr("y", 9)
                .attr("dy", ".35em")
                .style("text-anchor", "end")
                .text(function(d) {
                    return d;
                });

            legend.exit().remove();
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...