如何在D3条形图中限制最大宽度

留田

我是d3条形图的新手,下面是我想在项目中使用的条形图代码。

我只是想知道如何限制条形图的最大宽度,因为当我只有一条记录时,条形图的宽度会变得非常大,实际上,该条形图占据了整个宽度,然后图形看起来就不好了。d3中有什么方法可以限制每个条的最大宽度。

<!DOCTYPE html>
<meta charset="utf-8">
<style> /* set the CSS */
body { font: 12px Arial;}
path {
    stroke: steelblue;
    stroke-width: 2;
    fill: none;
}
.axis path,
.axis line {
    fill: none;
    stroke: grey;
    stroke-width: 1;
    shape-rendering: crispEdges;
}
.legend {
    font-size: 16px;
    font-weight: bold;
    text-anchor: middle;
}
</style>
<body>
<div id="d3id" ></div>
<!-- load the d3.js library -->
<script src="https://d3js.org/d3.v4.min.js"></script>

<script>
    var models = [
        {
            "model_name":"http://www.test.com",
            "field1":19,
            "field2":83
        },
        {
            "model_name":"http://www.test2.com",
            "field1":67,
            "field2":93
        },
        {
            "model_name":"http://www.test3.com",
            "field1":10,
            "field2":56
        },
        {
            "model_name":"http://www.test4.com",
            "field1":98,
            "field2":43
        },

        {
            "model_name":"http://www.test.com",
            "field1":19,
            "field2":83
        },
        {
            "model_name":"f7",
            "field1":67,
            "field2":93
        },
        {
            "model_name":"f8",
            "field1":10,
            "field2":56
        },
        {
            "model_name":"f9",
            "field1":98,
            "field2":43
        }
    ];
    models = models.map(i => {
        i.model_name = i.model_name;
        return i;
    });

    var container = d3.select('#d3id'),
        width = 500,
        height = 300,
        margin = {top: 30, right: 20, bottom: 30, left: 50},
        barPadding = .3,
        axisTicks = {qty: 5, outerSize: 0, dateFormat: '%m-%d'};

    var svg = container
        .append("svg")
        .attr("width", width)
        .attr("height", height)
        .append("g")
        .attr("transform", `translate(${margin.left},${margin.top})`);

    var xScale0 = d3.scaleBand().range([0, width - margin.left - margin.right]).padding(barPadding);
    var xScale1 = d3.scaleBand();
    var yScale = d3.scaleLinear().range([height - margin.top - margin.bottom, 0]);

    var xAxis = d3.axisBottom(xScale0).tickSizeOuter(axisTicks.outerSize);
    var yAxis = d3.axisLeft(yScale).ticks(axisTicks.qty).tickSizeOuter(axisTicks.outerSize);

    xScale0.domain(models.map(d => d.model_name));
    xScale1.domain(['field1', 'field2']).range([0, xScale0.bandwidth()]);
    yScale.domain([0, d3.max(models, d => d.field1 > d.field2 ? d.field1 : d.field2)]);

    var model_name = svg.selectAll(".model_name")
        .data(models)
        .enter().append("g")
        .attr("class", "model_name")
        .attr("transform", d => `translate(${xScale0(d.model_name)},0)`);

    /* Add field1 bars */
    model_name.selectAll(".bar.field1")
        .data(d => [d])
        .enter()
        .append("rect")
        .attr("class", "bar field1")
        .style("fill","#4267b2")
        .attr("x", d => xScale1('field1'))
        .attr("y", d => yScale(d.field1))
        .attr("width", xScale1.bandwidth())
        .attr("height", d => {
            return height - margin.top - margin.bottom - yScale(d.field1)
        });

    /* Add field2 bars */
    model_name.selectAll(".bar.field2")
        .data(d => [d])
        .enter()
        .append("rect")
        .attr("class", "bar field2")
        .style("fill","#69b3a2")
        .attr("x", d => xScale1('field2'))
        .attr("y", d => yScale(d.field2))
        .attr("width", xScale1.bandwidth())
        .attr("height", d => {
            return height - margin.top - margin.bottom - yScale(d.field2)
        });

    // Add the X Axis
    svg.append("g")
        .attr("class", "x axis")
        .attr("transform", `translate(0,${height - margin.top - margin.bottom})`)
        .call(xAxis);

    // Add the Y Axis
    svg.append("g")
        .attr("class", "y axis")
        .call(yAxis);

</script>
</body>

另外,如何调整标签以使其合适?请帮我。

王子

您可以通过操作附加矩形的width属性来轻松实现这一点。

在这里,我正在检查矩形的宽度是否大于width / 10(500/10),然后保持50的恒定值,否则使用默认值。您可以使用任何逻辑进行操作。

.attr("width", function(d) {
  return xScale1.bandwidth() > width/10 ? width/10 : xScale1.bandwidth();
})

请在下面找到工作清单:

<!DOCTYPE html>
<meta charset="utf-8">
<style> /* set the CSS */
body { font: 12px Arial;}
path {
    stroke: steelblue;
    stroke-width: 2;
    fill: none;
}
.axis path,
.axis line {
    fill: none;
    stroke: grey;
    stroke-width: 1;
    shape-rendering: crispEdges;
}
.legend {
    font-size: 16px;
    font-weight: bold;
    text-anchor: middle;
}
</style>
<body>
<div id="d3id" ></div>
<!-- load the d3.js library -->
<script src="https://d3js.org/d3.v4.min.js"></script>

<script>
    var models = [
        {
            "model_name":"http://www.test.com",
            "field1":19,
            "field2":83
        },
/*         {
            "model_name":"http://www.test2.com",
            "field1":67,
            "field2":93
        },
        {
            "model_name":"http://www.test3.com",
            "field1":10,
            "field2":56
        },
        {
            "model_name":"http://www.test4.com",
            "field1":98,
            "field2":43
        },
        
        {
            "model_name":"http://www.test.com",
            "field1":19,
            "field2":83
        },
        {
            "model_name":"f7",
            "field1":67,
            "field2":93
        },
        {
            "model_name":"f8",
            "field1":10,
            "field2":56
        },
        {
            "model_name":"f9",
            "field1":98,
            "field2":43
        } */
    ];
    models = models.map(i => {
        i.model_name = i.model_name;
        return i;
    });

    var container = d3.select('#d3id'),
        width = 500,
        height = 300,
        margin = {top: 30, right: 20, bottom: 30, left: 50},
        barPadding = .3,
        axisTicks = {qty: 5, outerSize: 0, dateFormat: '%m-%d'};

    var svg = container
        .append("svg")
        .attr("width", width)
        .attr("height", height)
        .append("g")
        .attr("transform", `translate(${margin.left},${margin.top})`);

    var xScale0 = d3.scaleBand().range([0, width - margin.left - margin.right]).padding(barPadding);
    var xScale1 = d3.scaleBand();
    var yScale = d3.scaleLinear().range([height - margin.top - margin.bottom, 0]);

    var xAxis = d3.axisBottom(xScale0).tickSizeOuter(axisTicks.outerSize);
    var yAxis = d3.axisLeft(yScale).ticks(axisTicks.qty).tickSizeOuter(axisTicks.outerSize);

    xScale0.domain(models.map(d => d.model_name));
    xScale1.domain(['field1', 'field2']).range([0, xScale0.bandwidth()]);
    yScale.domain([0, d3.max(models, d => d.field1 > d.field2 ? d.field1 : d.field2)]);

    var model_name = svg.selectAll(".model_name")
        .data(models)
        .enter().append("g")
        .attr("class", "model_name")
        .attr("transform", d => `translate(${xScale0(d.model_name)},0)`);

    /* Add field1 bars */
    model_name.selectAll(".bar.field1")
        .data(d => [d])
        .enter()
        .append("rect")
        .attr("class", "bar field1")
        .style("fill","#4267b2")
        .attr("x", d => xScale1('field1'))
        .attr("y", d => yScale(d.field1))
        .attr("width", xScale1.bandwidth())
        .attr("height", d => {
            return height - margin.top - margin.bottom - yScale(d.field1)
        });

    /* Add field2 bars */
    model_name.selectAll(".bar.field2")
        .data(d => [d])
        .enter()
        .append("rect")
        .attr("class", "bar field2")
        .style("fill","#69b3a2")
        .attr("x", d => xScale1('field2'))
        .attr("y", d => yScale(d.field2))
        .attr("width", function(d) {
          return xScale1.bandwidth() > width/2 ? width/4 : xScale1.bandwidth();
        })
        .attr("height", d => {
            return height - margin.top - margin.bottom - yScale(d.field2)
        });

    // Add the X Axis
    svg.append("g")
        .attr("class", "x axis")
        .attr("transform", `translate(0,${height - margin.top - margin.bottom})`)
        .call(xAxis);

    // Add the Y Axis
    svg.append("g")
        .attr("class", "y axis")
        .call(yAxis);

</script>
</body>

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章