D3 v4更新窗口大小上的对象位置

时间:2017-05-27 11:57:17

标签: d3.js

我正在使用d3 v4并努力创建一个简单的图表,作为进一步开发的参考,它使用d3.zoom()函数,图表调整大小以适应浏览器窗口。每当我得到其中一个工作时,其他的休息。 Typescript代码在Angular 4组件中,但不应产生影响。

首先我初始化一些属性:

    // Create a variable to hold the DOM Element which the chart will be attached to.
    this.element = this.chartContainer.nativeElement;

    // Set the width and height
    this.width = this.svgWidth - this.margin.left - this.margin.right;
    this.height = this.svgHeight - this.margin.top - this.margin.bottom;

    // create scale objects
    this.xScale = d3.scaleLinear()
        .domain([0, 100])
        .range([0, this.width]);

    this.yScale = d3.scaleLinear()
        .domain([-10, -20])
        .range([this.height, 0]);

    // create axis objects
    this.xAxis = d3.axisBottom(this.xScale);
    this.yAxis = d3.axisLeft(this.yScale);

然后我定义了我的zoomFunction()

    this.zoomFunction = () => {

        if (d3.event.transform != null) {
            //console.log(d3.event.transform);

            if (this.xScale != null) {

                // create new scale ojects based on event
                let new_xScale = d3.event.transform.rescaleX(this.xScale);
                let new_yScale = d3.event.transform.rescaleY(this.yScale);

                // update axes
                this.xChartAxis.call(this.xAxis.scale(new_xScale));
                this.yChartAxis.call(this.yAxis.scale(new_yScale));

                // update circle
                this.circles.attr("transform", d3.event.transform)
            };
        };
    };

定义我的zoom()函数:

    this.zoom = d3.zoom().on("zoom", this.zoomFunction);

定义我的windowResize()函数:

        this.onWindowResize =() => {

        // Set the width and height.
        // The element.offsetWidth is the total width of the DOM element including scrollbars, borders etc.
        this.svgWidth = this.element.offsetWidth;
        this.svgHeight = this.element.offsetHeight;

        // Update the width and height which the chart fits into.
        this.width = this.element.offsetWidth - this.margin.left - this.margin.right;
        this.height = this.element.offsetHeight - this.margin.top - this.margin.bottom;

        // Update the width of the svgViewport.
        this.svgViewport.attr("width", this.svgWidth);
        this.svgViewport.attr("height", this.svgHeight);

        // Update the size of the zoomView
        this.zoomView
            .attr("width", this.width)
            .attr("height", this.height);

        // Update the Range of the x scale.
        this.xScale.range([0, this.width]);
        this.yScale.range([0, this.height]);

        // Update the axis.
        this.innerSpace.select(".axisY")
            .call(this.yAxis);
        this.innerSpace.select(".axisX")
            .attr("transform", "translate(0," + this.height + ")")
            .call(this.xAxis);
    };

添加EventListener:

window.addEventListener("resize", this.onWindowResize);

最后创建我的图表:

    createChart() {

    // Create a circle
    this.originalCircle = {
        "cx": 50,
        "cy": -15,
        "r": 20
    };

    // Append an svg object to the chart element and save in the variable 'svgViewport'.
    this.svgViewport = d3.select(this.element).append('svg')
        .attr("class", "chart")
        .attr("width", this.svgWidth)
        .attr("height", this.svgHeight);

    // Inner Drawing Space
    this.innerSpace = this.svgViewport.append("g")
        .attr("class", "inner-space")
        .attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")")
        .call(this.zoom);

    // Add the circle.
    this.circles = this.innerSpace.append('circle')
        .attr("id", "circles")
        .attr("cx", this.xScale(this.originalCircle.cx))
        .attr("cy", this.yScale(this.originalCircle.cy))
        .attr('r', this.originalCircle.r);

    // Draw Axis
    this.xChartAxis = this.innerSpace.append("g")
        .attr("class", "axisX")
        .attr("transform", "translate(0," + this.height + ")")
        .call(this.xAxis);

    this.yChartAxis = this.innerSpace.append("g")
        .attr("class", "axisY")
        .call(this.yAxis);

    // append zoom area
    this.zoomView = this.innerSpace.append("rect")
        .attr("class", "zoom")
        .attr("width", this.width)
        .attr("height", this.height)
        .call(this.zoom);
};

奇怪的是,如果我刷新浏览器并调整窗口大小,轴会移动并按预期调整大小,但圆圈不会移动。当我平移/缩放时,圆圈会正确移动和缩放,并且轴可以正确移动。平移/缩放然后调整窗口大小后,轴不再移动,圆圈保持静止。

我认为我很接近,但我看不到下一步。任何建议都非常欢迎。

0 个答案:

没有答案