【问题标题】:Center visualization in viewbow D3viewbow D3 中的中心可视化
【发布时间】:2018-07-03 11:50:48
【问题描述】:

我创建了一个 D3 可视化,但在完全加载后,我的可视化不在中心:

我想要这个结果:

我使用 Angular 5 来执行我的 D3 可视化。我的数据已加载,可以正常工作,但我的可视化位于左侧而不是中心。我想集中我的可视化。我的组件中的代码:

export class BrainPageHomeComponent implements OnInit, AfterViewInit, OnDestroy {

    public name: string;
    public svg;
    public color;
    public simulation;
    public link;
    public node;
    public miserables;
    public tooltip;

    constructor(
        private brainService: BrainService,
    ) {
    }

    ngOnInit() {

    }

    ngAfterViewInit() {
        this.loadBrain();
    }

    //Load Brain
    public loadBrain() {
        d3.select("svg").remove();

        this.brainService.getBrain().subscribe(
            data => {
                this.miserables = data['data'];

                this.svg = d3.select("body")
                    .append("svg")
                    .attr("width", "100%")
                    .attr("height", "100%")
                    .call(d3.zoom().on("zoom", function () {
                        let g = d3.select('svg > g');

                        g.attr("transform", d3.event.transform);
                    }))
                    .append("g");


                let width  = +this.svg.attr("width");
                let height = +this.svg.attr("height");

                this.color = d3.scaleOrdinal(d3.schemeCategory20);

                this.simulation = d3.forceSimulation()
                    .force("link", d3.forceLink().id(function (d) {
                        return d.id;
                    }))
                    .force("charge", d3.forceManyBody())
                    .force("center", d3.forceCenter(width / 2, height / 2));

                this.render(this.miserables);
            },
            error => {
                console.log(error);
            });
    }

    ticked() {
        this.link
            .attr("x1", function (d) {
                return d.source.x;
            })
            .attr("y1", function (d) {
                return d.source.y;
            })
            .attr("x2", function (d) {
                return d.target.x;
            })
            .attr("y2", function (d) {
                return d.target.y;
            });

        this.node
            .attr("cx", function (d) {
                return d.x;
            })
            .attr("cy", function (d) {
                return d.y;
            });
    }

    render(graph) {
        let tooltip = d3.select("body")
            .append("div")
            .attr("class", "tooltip-message")
            .style("position", "absolute")
            .style("z-index", "10")
            .style("visibility", "hidden");

        this.link = this.svg.append("g")
            .attr("class", "links")
            .selectAll("line")
            .data(graph.links)
            .enter().append("line")
            .attr("stroke-width", function (d) {
                return Math.sqrt(d.value);
            });

        this.node = this.svg.append("g")
            .attr("class", "nodes")
            .selectAll("circle")
            .data(graph.nodes)
            .enter().append("circle")
            .attr("r", 5)
            .attr("fill", (d) => {
                return this.color(d.group);
            })
            //npm .on("click", function(d, i) { alert("Hello world"); })
            .on("mouseover", function(node){
                console.log(node);
                tooltip.text(node.title);
                return tooltip.style("visibility", "visible");
            })
            .on("mousemove", function(){return tooltip.style("top",
                (d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10)+"px");})
            .on("mouseout", function(){return tooltip.style("visibility", "hidden");})
            .call(d3.drag()
                .on("start", (d) => {
                    return this.dragstarted(d)
                })
                .on("drag", (d) => {
                    return this.dragged(d)
                })
                .on("end", (d) => {
                    return this.dragended(d)
                }));

        this.node.append("title")
            .text(function (d) {
                return d.id;
            });

        this.simulation
            .nodes(graph.nodes)
            .on("tick", (nodes) => {
                return this.ticked()
            })
            .stop();

        this.simulation.force("link")
            .links(graph.links);

        this.simulation.restart();
    }

    dragstarted(d) {
        if (!d3.event.active) this.simulation.alphaTarget(0.3).restart();
        d.fx = d.x, d.fy = d.y;
    }

    dragged(d) {
        d.fx = d3.event.x, d.fy = d3.event.y;
    }

    dragended(d) {
        if (!d3.event.active) this.simulation.alphaTarget(0);
        d.fx = null, d.fy = null;
    }

    ngOnDestroy() {

    }

}

我尝试了很多东西:

  • 添加 viewBox 属性:

    this.svg = d3.select("body") .append("svg") .attr("宽度", "100%") .attr("身高", "100%") .call(d3.zoom().on("缩放", function () { 让 g = d3.select('svg > g');

                    g.attr("transform", d3.event.transform);
                }))
                .attr("viewBox", "0 0 " + "100%" + " " + "100%" )
                .attr("preserveAspectRatio", "xMidYMid meet");
                .append("g");
    
  • 添加重启模拟:

    this.simulation.restart();

但是我的可视化总是在左边而不是中心。

【问题讨论】:

  • 在设置let width 之前,请告诉我们console.log(this.svg.attr("width")) 的结果是什么,没有一元加号。
  • 结果为“null”
  • 好吧,现在你知道为什么d3.forceCenter 不起作用了...

标签: javascript angular d3.js


【解决方案1】:

我解决了我的问题:

我换了:

let width  = +this.svg.attr("width");
let height = +this.svg.attr("height");

作者:

let width  = d3.select('svg').style("width");
let height = d3.select('svg').style("height");

width = width.substring(0, width.length - 2);
height = height.substring(0, height.length - 2);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-05
    • 2022-01-16
    • 2021-11-24
    • 1970-01-01
    • 2018-11-20
    • 1970-01-01
    • 2015-12-30
    • 2020-11-12
    相关资源
    最近更新 更多