【问题标题】:D3: The data on the axis not mappingD3:轴上的数据没有映射
【发布时间】:2016-11-10 11:35:21
【问题描述】:

我尝试在 D3 中实现条形图,但我的坐标轴上的映射出现问题。我有一个包含 x 和 y 的数据集,但我的值似乎没有正确映射。

这是代码:

var data = [
                                            {x: 2, y:  4},
                                            {x: 5, y:  8},
                                            {x: 8, y: 10},
                                            {x: 2, y:  4},
                                            {x: 5, y:  8},
                                            {x: 8, y: 19},
                                            {x: 2, y:  4},
                                            {x: 5, y:  8},
                                            {x: 8, y: 10},
                                            {x: 2, y:  4},
                                            {x: 5, y:  8},
                                            {x: 8, y: 10},
                                            {x: 2, y:  4},
                                            {x: 5, y:  8},
                                            {x: 8, y: 10},
                                            {x: 2, y:  4},
                                            {x: 3, y:  8},
                                            {x: 8, y: 10},
                                            {x: 24, y:  4},
                                            {x: 15, y:  8},
                                            {x: 18, y: 10}
                                        ];


                                        var margin = {top: 20, right: 30, bottom: 30, left: 40},
                                            w = 1000 - margin.left - margin.right,
                                            h = 500 - margin.top - margin.bottom;

                                        var x = d3.scale.linear()
                                            .range([0, w]);

                                        var y = d3.scale.linear()
                                            .range([h, 0]);

                                        var xAxis = d3.svg.axis()
                                            .scale(x)
                                            .orient("bottom");
                                            //.tickFormat(d3.format("%Y/%m"));

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

                                        var zoom = d3.behavior.zoom()
                                            .scaleExtent([1, 1])
                                            .x(x)
                                            .on("zoom", zoomed);

                                        var chart = d3.select("#testChart").append("svg")
                                            .attr("width", w + margin.left + margin.right)
                                            .attr("height", h + margin.top + margin.bottom)
                                            .append("g")
                                            .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
                                            .call(zoom);

                                        var rect = chart.append("rect")
                                            .attr("width", w)
                                            .attr("height", h)
                                            .style("fill", "none")
                                            .style("pointer-events", "all");

                                        chart.append("g")
                                            .attr("class", "x axis")
                                            .attr("transform", "translate(0," + h + ")")
                                            .call(xAxis)



                                        chart.append("g")
                                            .attr("class", "y axis")
                                            .call(yAxis);

                                        //data.forEach(function (d) {
                                              //d.date = new Date("20" + d.yy + "/" + d.mm);
                                              // coerce to number
                                                //d.ppm_value = +d.ppm_value;
                                               // d.date = format.parse(d.date);
                                                //console.log(d.ppm_value);
                                               // console.log(d.date);
                                            //});

                                        x.domain(data.map(function (d) {
                                            console.log("HEelllppp!!!!",d.date);
                                            return d.x;
                                        }));
                                        y.domain([0, d3.max(data, function (d) {
                                            return d.y;
                                        })]);

                                        var bars = chart.append("g")
                                            .attr("class", "chartobjects");

                                        bars.selectAll(".rect")
                                            .data(data)
                                            .enter().append("rect")
                                            .attr("class", "rectBar")
                                            .on("click", hello)
                                            .attr('x', function (d) {
                                             console.log("Blaaannaaaaa!!!!!!",d.x);
                                                return x(d.x);
                                            })
                                            .attr("y", function (d) {
                                                return y(d.y);
                                            })
                                            .attr("height", function(d) { return h - y(d.y); })
                                            .attr("width", 45)
                                            .attr("fill", function(d){
                                                 return d.y > 6 ? "blue" : "red"});

                                       function hello(){
                                           alert("Hello world!!")
                                       }

                                        function zoomed() {
                                            var tx = Math.max(0, d3.event.translate[0]);
                                                //ty = Math.min(0, d3.event.translate[1]);
                                            zoom.translate([tx]);
                                            bars.attr("transform", "translate(" + [tx] + ")scale(" + d3.event.scale + ")");
                                            chart.select(".x.axis")
                                                .call(xAxis);
                                            //chart.select(".y.axis")
                                            //  .call(yAxis);
                                        }

也许你有一些想法为什么。我也发个图:

【问题讨论】:

    标签: javascript d3.js graph charts bar-chart


    【解决方案1】:

    这里的解释更多地是使用 dataviz 原则而不是 D3 代码。

    条形图不同于直方图,主要区别在于:在条形图中,每个条形代表一个定性变量(或分类变量) .话虽如此,您的 x 轴不应使用线性刻度,而应使用序数刻度:

    var x = d3.scale.ordinal()
        .rangeBands([0, w]);
    

    这是一个带有序数比例的演示:

    var data = [{
        x: 2,
        y: 4
    }, {
        x: 5,
        y: 8
    }, {
        x: 8,
        y: 10
    }, {
        x: 2,
        y: 4
    }, {
        x: 5,
        y: 8
    }, {
        x: 8,
        y: 19
    }, {
        x: 2,
        y: 4
    }, {
        x: 5,
        y: 8
    }, {
        x: 8,
        y: 10
    }, {
        x: 2,
        y: 4
    }, {
        x: 5,
        y: 8
    }, {
        x: 8,
        y: 10
    }, {
        x: 2,
        y: 4
    }, {
        x: 5,
        y: 8
    }, {
        x: 8,
        y: 10
    }, {
        x: 2,
        y: 4
    }, {
        x: 3,
        y: 8
    }, {
        x: 8,
        y: 10
    }, {
        x: 24,
        y: 4
    }, {
        x: 15,
        y: 8
    }, {
        x: 18,
        y: 10
    }];
    
    
    var margin = {
            top: 20,
            right: 30,
            bottom: 30,
            left: 40
        },
        w = 1000 - margin.left - margin.right,
        h = 500 - margin.top - margin.bottom;
    
    var x = d3.scale.ordinal()
        .rangeBands([0, w], 0.6);
    
    var y = d3.scale.linear()
        .range([h, 0]);
    
    var xAxis = d3.svg.axis()
        .scale(x)
        .orient("bottom");
    //.tickFormat(d3.format("%Y/%m"));
    
    var yAxis = d3.svg.axis()
        .scale(y)
        .orient("left");
    
    var chart = d3.select("body").append("svg")
        .attr("width", w + margin.left + margin.right)
        .attr("height", h + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    
    var rect = chart.append("rect")
        .attr("width", w)
        .attr("height", h)
        .style("fill", "none")
        .style("pointer-events", "all");
    
    
    
    //data.forEach(function (d) {
    //d.date = new Date("20" + d.yy + "/" + d.mm);
    // coerce to number
    //d.ppm_value = +d.ppm_value;
    // d.date = format.parse(d.date);
    //console.log(d.ppm_value);
    // console.log(d.date);
    //});
    
    x.domain(data.map(function(d) {
        return d.x;
    }));
    y.domain([0, d3.max(data, function(d) {
        return d.y;
    })]);
    
    chart.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + h + ")")
        .call(xAxis)
    
    chart.append("g")
        .attr("class", "y axis")
        .call(yAxis);
    
    var bars = chart.append("g")
        .attr("class", "chartobjects");
    
    bars.selectAll(".rect")
        .data(data)
        .enter().append("rect")
        .attr("class", "rectBar")
        .on("click", hello)
        .attr('x', function(d) {
            return x(d.x);
        })
        .attr("y", function(d) {
            return y(d.y);
        })
        .attr("height", function(d) {
            return h - y(d.y);
        })
        .attr("width", x.rangeBand())
        .attr("fill", function(d) {
            return d.y > 6 ? "blue" : "red"
        });
    
    function hello() {
        alert("Hello world!!")
    }
    
    function zoomed() {
        var tx = Math.max(0, d3.event.translate[0]);
        //ty = Math.min(0, d3.event.translate[1]);
        zoom.translate([tx]);
        bars.attr("transform", "translate(" + [tx] + ")scale(" + d3.event.scale + ")");
        chart.select(".x.axis")
            .call(xAxis);
        //chart.select(".y.axis")
        //  .call(yAxis);
    }
    .axis path,.axis line {
    			fill: none;
    			stroke: black;
    			shape-rendering: crispEdges;
    		}
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

    但是,如果您想保持线性比例并根据数据集中的 x 值定位条形图,请不要使用 map,它会返回一个包含所有 x 值的数组:只需将域设置为 @ 987654328@,无论这些值是什么。

    【讨论】:

    • 我这样做了,但它仍然没有将我的 x 和 y 值映射到轴上。我有 0.0,0.2 之类的值,而我的数据集中没有这些值。
    • 您没有 0.0 或 0.2。再次查看您的数据数组。除此之外,这只是一个一般性的解释,你的代码 - 和你的数据 - 有一些你必须解决的问题。
    • 我知道。我需要在轴上映射我的数据数组,但它不起作用。我像这样进行映射: x.domain(data.map(function (d) { console.log("HEelllppp!!!!",d.x); return d.x; })); y.domain([0, d3.max(data, function (d) { return d.y; })]);
    • 我实现了一些滚动,但现在它不再起作用了。你知道为什么吗?
    • 因为我把它取下来是为了让 sn-p 更简单。
    猜你喜欢
    • 2018-05-09
    • 2017-09-14
    • 1970-01-01
    • 2013-11-03
    • 1970-01-01
    • 2012-11-01
    • 1970-01-01
    • 2017-05-22
    • 2010-12-17
    相关资源
    最近更新 更多