html - d3 v4 内部填充设置为 .001 实际上不会导致范围之间的小填充

标签 html css d3.js

有没有办法最小化分组水平条形图中范围之间的填充?

我正在为 AngularJS 构建一个水平条形图指令,目前我已经很接近了,但我对间距不太满意。如果有更好的方法来构建垂直范围,我将非常感谢任何提示。到目前为止,这是我的结果:

angular.module('MissionControlApp').directive('d3GroupedHorizontalBarChart2', ['d3', '$timeout', function(d3, $timeout) {
    return {
        restrict: 'E',
        scope: {
            data: '=',
            onClick: '&d3OnClick'
        },
        link: function(scope, ele) {
            var refreshScope = function() {
                scope.$apply();
            };

            var svg = d3.select(ele[0])
                .append("svg")
                .attr("width", "100%");

            // on window resize, re-render d3 canvas
            window.onresize = function() {
                return scope.$apply();
            };
            scope.$watch(function(){
                    return angular.element(window)[0].innerWidth;
                }, function(){
                    return scope.render(scope.data);
                }
            );

            // watch for data changes and re-render
            scope.$watch("data", function(newVals) {
                if(!newVals) return;
                return scope.render(newVals);
            }, true);

            // define render function for grouped bar charts
            scope.render = function(data){
                if(!data) return;

                // remove all previous items before render
                svg.selectAll("*").remove();

                // setup variables
                var margin = {top: 25, right: 40, bottom: 70, left: 150};
                var width = d3.select(ele[0])._groups[0][0].offsetWidth - margin.left - margin.right;
                var height = (scope.data.length * 60);

                svg.attr('height', height + margin.top + margin.bottom);

                var y0 = d3.scaleBand()
                    .rangeRound([0, height])
                    .paddingInner(0.01);

                var y1 = d3.scaleBand()
                    .padding(0.01);

                var x = d3.scaleLinear()
                    .rangeRound([0, width]);

                var color = d3.scaleLinear()
                    .domain([0, 25, 50, 75, 100])
                    .range(["#51b75d", "#90eb9d","#ffff8c","#f5c93f","#c45c44"])
                    .interpolate(d3.interpolateHcl);

                var xAxis = d3.axisBottom(x)
                    .tickSizeInner(-(height-5))
                    .tickPadding(8);

                var keys = d3.keys(data[0]).filter(function(key) { return key !== "user"; });
                y0.domain(data.map(function(d) { return d.user; }));
                y1.domain(keys).rangeRound([0, y0.bandwidth()]);
                x.domain([0, 100]);

                // Define bars
                var bar = svg.selectAll(".bar")
                    .data(data)
                    .enter().append("g")
                    .attr("transform", function(d) { return "translate(" + margin.left + "," + (y0(d.user) + (y0.bandwidth()/2) + margin.top - y1.bandwidth()) + ")"; });

                var barEnter = bar.selectAll("rect")
                    .data(function(d) { return d.values; })
                    .enter();

                barEnter.append("rect")
                    .attr("height", y1.bandwidth())
                    .attr("y", function(d) {return y1(d.name); })
                    .attr("x", 0)
                    .attr("value", function(d){return d.name;})
                    .attr("width", 0)
                    .attr("fill", function(d) { return color(d.value); })
                    .on("mouseover", function() { d3.select(this).style("cursor", "pointer");})
                    .on("mouseout", function() { d3.select(this).style("cursor", "default");})
                    .on("click", function(d){
                        scope.onClick({item: d});
                        d3.select(".selectedBlueFill").classed("selectedBlueFill", false);
                        d3.select(this).classed("selectedBlueFill", true);
                        $timeout(refreshScope, 0, false); // flush the digest cycle
                    })
                    .transition()
                    .duration(1000)
                    .attr("width", function(d) { return x(d.value); });

                barEnter.append("text")
                    .attr("fill", "#000")
                    .attr("y", function(d){return y1(d.name) + (y1.bandwidth() / 2);})
                    .attr("x", function(d){return x(d.value);})
                    .attr("dx", 5)
                    .attr("dy", ".35em")
                    .text(function(d){return parseFloat(d.value).toFixed(0) + "%";})
                    .attr("fill-opacity", 0)
                    .transition()
                    .duration(1500)
                    .attr("fill-opacity", 1);

                // Set up x axis
                svg.append("g")
                    .attr("class", "axisHorizontal")
                    .attr("transform", "translate(" + margin.left + "," + (height + margin.top) + ")")
                    .call(xAxis);

                // Set up y axis
                svg.append("g")
                    .attr("class", "y axis")
                    .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
                    .call(d3.axisLeft(y0));

                // Draw the legend
                // Create the gradient for the legend
                svg.append("defs")
                    .append("linearGradient")
                    .attr("id", "legend-traffic")
                    .attr("x1", "0%").attr("y1", "0%")
                    .attr("x2", "100%").attr("y2", "0%")
                    .selectAll("stop")
                    .data(color.range())
                    .enter().append("stop")
                    .attr("offset", function(d,i) { return i/(color.range().length-1); })
                    .attr("stop-color", function(d) { return d; });

                // Legend variables
                var legendWidth = width * 0.6;
                var legendHeight = 10;

                // Legend container
                var legendSvg = svg.append('g')
                    .attr("class", "legendWrapper")
                    .attr("transform", "translate(" + ((width + margin.left + margin.right)/2) + "," + (height + margin.top + margin.bottom) + ")");

                // Draw the rectangle
                legendSvg.append("rect")
                    .attr("class", "legendRect")
                    .attr("x", -legendWidth/2)
                    .attr("y", -30)
                    .attr("width", legendWidth)
                    .attr("height", legendHeight)
                    .attr("fill", "url(#legend-traffic)");

                // Append title
                legendSvg.append("text")
                    .attr("class", "legendTitle")
                    .attr("x", 0)
                    .attr("y", -35)
                    .attr("text-anchor", "middle")
                    .text("Worksets Opened %");

                // Set scale for x-axis
                var xScale = d3.scaleLinear()
                    .range([0, legendWidth])
                    .domain([0,100]);

                // Define x-axis
                var legendAxis = d3.axisBottom(xScale).ticks(5);

                // Set up x-axis
                legendSvg.append("g")
                    .attr("class", "axisLegend")
                    .attr("transform", "translate(" + (-legendWidth/2) + "," + (legendHeight-30) + ")")
                    .call(legendAxis);
            };
        }
    };
}]);

但是我得到的结果是内部间距很大。我将 .paddingInner 属性设置为 0.001,但最终还是会出现大间距......想法?

enter image description here

最佳答案

我们的想法是创建群组,其中每个群组都拥有该群组的独特条形图。

现在,一旦你有了组,你就可以用一些数学来改变间距,如下面的代码片段所示:

var bar = chart
    .selectAll("g")
    .data(zippedData)
    .enter().append("g")
    .attr("transform", function(d, i) {
      //here barHeight is the width of the bars.
      return "translate(" + spaceForLabels + "," 
        + (i * barHeight + gapBetweenGroups * (0.5 + Math.floor(i/data.series.length))) + ")";
    });

通过更改 gapBetweenGroups 的值,您可以调节组的距离。

工作代码 here

关于html - d3 v4 内部填充设置为 .001 实际上不会导致范围之间的小填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48651078/

相关文章:

javascript - 寻找设计资源来练习 HTML/CSS

javascript - 堆叠条形图 24 小时 @ 15 分钟数据,仅显示 2 小时刻度

具有动态更新的 d3.js 可重用饼图

javascript - IFrame 和 Flash 广告 Z-Index 问题

html - 链接不工作 HTML/CSS

javascript - 调整窗口大小时导航栏不会折叠

html - 图像上的文本 block 和图像

javascript - 根据数据中的附加列更改 d3 Sankey 图中的节点颜色

javascript - jQuery 不更新 CSS 属性

html - 在特定浏览器宽度下,渐变填充 div 的末尾出现白线