【问题标题】:D3 - Add space between internal barsD3 - 在内部条之间添加空间
【发布时间】:2019-11-06 17:15:21
【问题描述】:

我有一个演示 here

这是一个简单的 d3 图表。

条之间没有空间。我知道我可以添加这个

const x = d3.scaleBand() .range([0, width]) //.padding(0.1)

这会在每个条形的两侧增加空间。

如何从第一个和最后一个柱中删除空间,以便第一个和最后一个柱位于图表边缘

【问题讨论】:

    标签: d3.js


    【解决方案1】:

    使用.paddingInner([0.1]); 仅设置内部填充,如文档https://github.com/d3/d3-scale#band_paddingInner 中所述

    这是可行的解决方案:

    var originalData = [
    	{
    		date: "Jan",
    		value: 1507
      },
    	{
    		date: "Feb",
    		value: 1600
    	},
    	{
    		date: "Mar",
    		value: 1281
    	},
    	{
    		date: "Apr",
    		value: 1898
    	},
    	{
    		date: "May",
    		value: 1749
    	},
    	{
    		date: "June",
    		value: 1270
    	},
    	{
    		date: "July",
    		value: 1712
    	},
    	{
    		date: "Aug",
    		value: 1270
    	},
    	{
    		date: "Sept",
    		value: 1257
    	},
    	{
    		date: "Oct",
    		value: 1257
    	},
    	{
    		date: "Nov",
    		value: 1277
    	},
    	{
    		date: "Dec",
    		value: 1057
    	}
    ]
    
    ///////////////////////////// Update function
    
    const randomizeData = (data) =>  {
        const rand = Math.floor(Math.random() * data.length) + 2
        const newData = data.slice(0, rand)
        update(newData)
    }
    
    ///////////////////////////// Create SVG
    
    const w = 400
    const h = 250
    
    const margin = {
        top: 20,
        bottom: 40,
        left: 40,
        right: 20
    }
    
    const width = w - margin.left - margin.right
    const height = h - margin.top - margin.bottom
    
    const svg = d3.select(".chart-container").append("svg")
        .attr("id", "svg")
        .attr("width", w)
        .attr("height", h)
    
    const chart = svg.append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
    
    const x = d3.scaleBand()
        .range([0, width])
        .paddingInner([0.1]);
      
    const y = d3.scaleLinear()
        .rangeRound([height, 0])
    
    const xAxis = chart.append("g").attr("class", "axis axis-x")
    const yAxis = chart.append("g").attr("class", "axis axis-y")              
    
    ///////////////////////////////// Update function
    
    //Recalc Domains
    //Redraw Axis
    //Enter
    //Update
    //Exit
    
    const update = (graphData) => {
    
        // Recalc domains based on new data
        // x is scaleBand
        x.domain(graphData.map( (d) => d.date) );
    
        y.domain([0, d3.max( graphData, (d) => d.value) ]);
    
        const u = chart.selectAll(".bar")
            .data(graphData)
    
        // Enter
        u.enter()
            .append("rect")
              .classed('bar', true)
              .attr('x', (d) => x(d.date) )
              .attr("y", (d) => y(d.value) )
              .attr("width", x.bandwidth() )
              .attr("height", (d) => height - y(d.value) )
    
        // Update
        u.attr('x', (d) => x(d.date) )
            .attr("width", x.bandwidth() )
            .attr("y", (d) => y(d.value) )
            .attr("height", (d) => height - y(d.value) )
    
        // Exit
        u.exit()
            .remove()
    
         // Redraw axes based on new data
        xAxis.call(d3.axisBottom(x))
            .attr("transform", "translate(0," + height + ")");
        yAxis.call(d3.axisLeft(y))    
    }    
    
    randomizeData(originalData);
    
    var button = document.getElementById('btn');
    button.addEventListener('click', () => randomizeData(originalData) );
    h1, h2 {
      font-family: Lato;
    }
    
    #svg{
      background-color: lightgrey;
    }
    
    .bar{
      shape-rendering: crispEdges;
      fill: mediumvioletred;
    }
    
    .bar-label{
      fill: white;
    }
    
    .bar-label{
      text-anchor: end;
    }
    
    .grid line{
      stroke: #bbb;
    }
    
    .grid .tick:nth-child(4) line{
      stroke-width: 3;
      stroke: #999;
    }
    
    .divide{
      fill: lightgrey;
    }
    
    .update-btn{
      display: block;
      margin-top: 30px;
    }
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width">
      <title>JS Bin</title>
    </head>
    <body>
      <div class="chart-container"></div>
    
    
    <button class="update-btn" id="btn">Update</button>
    
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.3/d3.min.js"></script>
    
    </body>
    </html>

    【讨论】: