찾다

 >  Q&A  >  본문

d3.js를 확대할 때 산점도 값이 유지되지 않습니다.

d3.js를 처음 사용하니 조금만 기다려주세요. vue.js 파일에 순수 JavaScript로 구현했습니다. 확대/축소 기능을 사용하여 산점도를 만들려고 합니다. 지금까지는 거의 모든 것이 잘 작동했지만 크기를 조정하면 x축의 크기가 올바르게 조정되지 않지만 y축은 제대로 작동하는 것을 알 수 있습니다. 예를 들어 원본 그래프를 보면 x축 기준으로 한 점이 약 625에 있을 수 있지만 확대하면 같은 점이 600보다 작아집니다. 이는 y축에서는 발생하지 않습니다. 점의 크기가 올바르게 조정됩니다. 스케일링 함수의 x축 스케일링에 문제가 있다고 가정하고 있지만 알 수 없습니다. 살펴보시고 제가 어디에서 잘못되고 있는지 알 수 있으면 알려주시기 바랍니다.

편집: 이것이 d3.js 버전 7.4.4

를 사용하고 있다는 점을 언급하고 싶습니다. 으아악

흥미롭게도 축 밖의 점이 표시되지 않도록 클리핑 영역을 설정한 후에는 문제가 저절로 해결되는 것 같았습니다. 클리핑 경로를 만드는 방법은 다음과 같습니다.

으아악

다음과 같이 데이터를 그릴 때 해당 속성을 svg에 추가했습니다.

으아악

그리기 데이터 섹션이 포함된 클리핑 경로가 업데이트되었습니다:

<template>
    <div id="reg_plot"></div>
</template>


<script>
import * as d3 from 'd3';
export default {
    name: 'regCamGraph',
    components: {
        d3
    },
    methods: {
        createSvg() {
            // dimensions
            var margin = {top: 20, right: 20, bottom: 30, left: 40},
                svg_dx = 1400, 
                svg_dy =1000,
                chart_dx = svg_dx - margin.right - margin.left,
                chart_dy = svg_dy - margin.top - margin.bottom;

            // data
            var y = d3.randomNormal(400, 100);
            var x_jitter = d3.randomUniform(-100, 1400);

            var d = d3.range(1000)
                        .map(function() { 
                            return [x_jitter(), y()]; 
                        });

            // fill
            var colorScale = d3.scaleLinear()
                                .domain(d3.extent(d, function(d) { return d[1]; }))
                                .range([0, 1]);


            // y position
            var yScale = d3.scaleLinear()
                            .domain(d3.extent(d, function(d) { return d[1]; }))
                            .range([chart_dy, margin.top]);
            
            // x position
            var xScale = d3.scaleLinear()
                            .domain(d3.extent(d, function(d) { return d[0]; }))
                            .range([margin.right, chart_dx]);
            console.log("chart_dy: " + chart_dy);
            console.log("margin.top: " + margin.top);
            console.log("chart_dx: " + chart_dx);
            console.log("margin.right: " + margin.right);
            // y-axis
            var yAxis = d3.axisLeft(yScale);

            // x-axis
            var xAxis = d3.axisBottom(xScale);

            // zoom
            var svg = d3.select("#reg_plot")
                        .append("svg")
                        .attr("width", svg_dx)
                        .attr("height", svg_dy);
            svg.call(d3.zoom().on("zoom", zoom));      // ref [1]

            // plot data
            var circles = svg.append("g")
                            .attr("id", "circles")
                            .attr("transform", "translate(200, 0)")
                            .selectAll("circle")
                            .data(d)
                            .enter()
                            .append("circle")
                            .attr("r", 4)
                            .attr("cx", function(d) { return xScale(d[0]); })
                            .attr("cy", function(d) { return yScale(d[1]); })
                            .style("fill", function(d) { 
                                var norm_color = colorScale(d[1]);
                                return d3.interpolateInferno(norm_color) 
                            });

            // add y-axis
            var y_axis = svg.append("g")
                            .attr("id", "y_axis")
                            .attr("transform", "translate(75,0)")
                            .call(yAxis).style("font-size", "20px")
                        
            // add x-axis
            var x_axis = svg.append("g")
                            .attr("id", "x_axis")
                            .attr("transform", `translate(${margin.left}, ${svg_dy - margin.bottom})`)
                            .call(xAxis).style("font-size", "20px")

            function zoom(e) {

                // re-scale y axis during zoom
                y_axis.transition()
                        .duration(50)
                        .call(yAxis.scale(e.transform.rescaleY(yScale)));

                // re-scale x axis during zoom
                x_axis.transition()
                        .duration(50)
                        .call(xAxis.scale(e.transform.rescaleX(xScale)));

                // re-draw circles using new y-axis scale
                var new_xScale = e.transform.rescaleX(xScale);
                var new_yScale = e.transform.rescaleY(yScale);

                console.log(d);

                x_axis.call(xAxis.scale(new_xScale));
                y_axis.call(yAxis.scale(new_yScale));
                circles.data(d)
                    .attr('cx', function(d) {return new_xScale(d[0])})
                    .attr('cy', function(d) {return new_yScale(d[1])});
            }

        }
    },
    mounted() {
        this.createSvg();
    }
    
}
</script>

P粉294954447P粉294954447225일 전592

모든 응답(1)나는 대답할 것이다

  • P粉659516906

    P粉6595169062024-04-07 15:47:25

    드디어 문제를 해결했습니다. 나에게 도움이 된 내용을 보여주기 위해 원본 게시물을 업데이트했습니다.

    기본적으로 클리핑 영역을 추가한 후 모든 것이 제대로 작동하기 시작했습니다.

    으아악

    회신하다
    0
  • 취소회신하다