将定位更改为绝对以包含词云D3 文本数据词云

问题描述 投票:0回答:1

我在D3中写了如下代码生成词云:

HTML

<html>

<head>
    <title>D3 Word Cloud for Textual Data</title>

    <link rel="stylesheet" href="style-sheet.css">
</head>

<body>
    <script src="https://d3js.org/d3.v7.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3-cloud/1.2.5/d3.layout.cloud.js"></script>

    <svg width="500" height="300"></svg>

    <script src="data-script.js"></script>
</body>

</html>

CSS

.word {
    font-size: 2em;
    fill: steelblue;
}

JS

var data = ["hello", "world", "d3", "word", "cloud", "visualization"];

var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height"),
    margin = { top: 20, right: 20, bottom: 30, left: 40 },
    g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var layout = d3.layout
    .cloud()
    .size([width - margin.left - margin.right, height - margin.top - margin.bottom])
    .words(data.map(function (d) { return { text: d, size: 10 + Math.random() * 20 }; }))
    .padding(5)
    .rotate(function () { return ~~(Math.random() * 2) * 90; })
    .fontSize(function (d) { return d.size; })
    .on("end", draw);

layout.start();

function draw(words) {
    g.selectAll(".word")
        .data(words)
        .join("text")
        .attr("class", "word")
        .style("font-size", function (d) { return d.size + "px"; })
        .style("fill", function (d, i) { return "steelblue"; })
        .attr("text-anchor", "middle")
        .attr("transform", function (d) {
            return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
        })
        .text(function (d) { return d.text; });
}

但后来我注意到这些词有时会被切断并溢出到 SVG 元素之外。我无法弄清楚如何修复它(除了玩字体大小和填充并不总是有效)所以我寻求建议并被告知:Change the absolute positioning!

所以,我修改了我的CSS代码如下:

.word {
    font-size: 2em;
    fill: steelblue;
    position: absolute;
}

但这也没有用...

我该如何解决这个问题?

javascript d3.js word-cloud
1个回答
0
投票

你所做的一切都是完美的,但分组元素 g 的翻译值错误。

使用宽度和高度的一半使 g 元素居中。然后每一个字都会变成svg里面。

var data = ["hello", "world", "d3", "word", "cloud", "visualization"];

var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height"),
    margin = { top: 20, right: 20, bottom: 30, left: 40 },
    g = svg.append("g").attr("transform", "translate(" + width/2 + "," + height/2 + ")");//center the g element by taking half of height and width

var layout = d3.layout
    .cloud()
    .size([width - margin.left - margin.right, height - margin.top - margin.bottom])
    .words(data.map(function (d) { return { text: d, size: 10 + Math.random() * 20 }; }))
    .padding(5)
    .rotate(function () { return ~~(Math.random() * 2) * 90; })
    .fontSize(function (d) { return d.size; })
    .on("end", draw);

layout.start();

function draw(words) {
    g.selectAll(".word")
        .data(words)
        .join("text")
        .attr("class", "word")
        .style("font-size", function (d) { return d.size + "px"; })
        .style("fill", function (d, i) { return "steelblue"; })
        .attr("text-anchor", "middle")
        .attr("transform", function (d) {
            return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
        })
        .text(function (d) { return d.text; });
}
.word {
    font-size: 1em;
    fill: steelblue;
}
<script src="https://d3js.org/d3.v7.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3-cloud/1.2.5/d3.layout.cloud.js"></script>

    <svg width="500" height="300"></svg>

© www.soinside.com 2019 - 2024. All rights reserved.