d3.js에서 창 크기를 조정할 때 svg 크기 조정
d3.js로 산점도를 그리고 있어요이 질문의 도움을 받아:
화면 크기, 현재 웹 페이지 및 브라우저 창 가져오기
저는 다음과 같은 답을 사용하고 있습니다.
var w = window,
d = document,
e = d.documentElement,
g = d.getElementsByTagName('body')[0],
x = w.innerWidth || e.clientWidth || g.clientWidth,
y = w.innerHeight|| e.clientHeight|| g.clientHeight;
이렇게 사용자 창에 플롯을 맞출 수 있습니다.
var svg = d3.select("body").append("svg")
.attr("width", x)
.attr("height", y)
.append("g");
이제 사용자가 창의 크기를 조정할 때 플롯의 크기를 조정해 주었으면 합니다.
PS: 제 코드에 jQuery를 사용하지 않습니다.
'응답형 SVG'를 찾으십시오. SVG를 응답형 SVG로 만드는 것은 매우 간단하며, 더 이상 크기에 대해 걱정할 필요가 없습니다.
방법은 다음과 같습니다.
d3.select("div#chartId")
.append("div")
// Container class to make it responsive.
.classed("svg-container", true)
.append("svg")
// Responsive SVG needs these 2 attributes and no width and height attr.
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", "0 0 600 400")
// Class to make it responsive.
.classed("svg-content-responsive", true)
// Fill with a rectangle for visualization.
.append("rect")
.classed("rect", true)
.attr("width", 600)
.attr("height", 400);
.svg-container {
display: inline-block;
position: relative;
width: 100%;
padding-bottom: 100%; /* aspect ratio */
vertical-align: top;
overflow: hidden;
}
.svg-content-responsive {
display: inline-block;
position: absolute;
top: 10px;
left: 0;
}
svg .rect {
fill: gold;
stroke: steelblue;
stroke-width: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="chartId"></div>
주의: SVG 이미지의 모든 것은 창 너비에 따라 확대됩니다.여기에는 스트로크 폭과 글꼴 크기(CSS로 설정된 크기도 포함)가 포함됩니다.이것이 바람직하지 않은 경우는, 이하와 같은 대체 솔루션이 있습니다.
상세정보/자습서:
http://thenewcode.com/744/Make-SVG-Responsive
http://soqr.fr/testsvg/embed-svg-liquid-layout-responsive-web-design.php
window.onresize 사용:
function updateWindow(){
x = w.innerWidth || e.clientWidth || g.clientWidth;
y = w.innerHeight|| e.clientHeight|| g.clientHeight;
svg.attr("width", x).attr("height", y);
}
d3.select(window).on('resize.updatesvg', updateWindow);
UPDATE는 @cminatti에서 새로운 방법을 사용합니다.
역사적 목적을 위한 오래된 대답
IMO는 select()와 on()을 사용하는 것이 좋습니다.이렇게 하면 여러 개의 이벤트핸들러를 사이즈 변경할 수 있기 때문입니다.너무 흥분하지 마
d3.select(window).on('resize', resize);
function resize() {
// update width
width = parseInt(d3.select('#chart').style('width'), 10);
width = width - margin.left - margin.right;
// resize the chart
x.range([0, width]);
d3.select(chart.node().parentNode)
.style('height', (y.rangeExtent()[1] + margin.top + margin.bottom) + 'px')
.style('width', (width + margin.left + margin.right) + 'px');
chart.selectAll('rect.background')
.attr('width', width);
chart.selectAll('rect.percent')
.attr('width', function(d) { return x(d.percent); });
// update median ticks
var median = d3.median(chart.selectAll('.bar').data(),
function(d) { return d.percent; });
chart.selectAll('line.median')
.attr('x1', x(median))
.attr('x2', x(median));
// update axes
chart.select('.x.axis.top').call(xAxis.orient('top'));
chart.select('.x.axis.bottom').call(xAxis.orient('bottom'));
}
http://eyeseast.github.io/visible-data/2013/08/28/responsive-charts-with-d3/
크기 조정 코드가 그래프를 만드는 코드와 거의 같다면 좀 못생겼죠.따라서 기존 차트의 모든 요소의 크기를 조정하는 대신 단순히 다시 로드하는 것이 어떻습니까?저는 다음과 같이 작업을 진행했습니다.
function data_display(data){
e = document.getElementById('data-div');
var w = e.clientWidth;
// remove old svg if any -- otherwise resizing adds a second one
d3.select('svg').remove();
// create canvas
var svg = d3.select('#data-div').append('svg')
.attr('height', 100)
.attr('width', w);
// now add lots of beautiful elements to your graph
// ...
}
data_display(my_data); // call on page load
window.addEventListener('resize', function(event){
data_display(my_data); // just call it again...
}
중요한 것은d3.select('svg').remove();
그렇지 않으면 크기를 조정할 때마다 이전 SVG 요소 아래에 다른 SVG 요소가 추가됩니다.
레이아웃에서는 단순히 '높이' 및 '너비' 속성을 설정하여 플롯을 svg 컨테이너로 다시 중심화/이동할 수 없습니다.그러나 Force Layouts에 적합한 매우 간단한 답이 여기에 있습니다.요약:
원하는 대로 같은 것을 사용하세요.
window.on('resize', resize);
다음으로 svg 및 force 변수가 있다고 가정합니다.
var svg = /* D3 Code */;
var force = /* D3 Code */;
function resize(e){
// get width/height with container selector (body also works)
// or use other method of calculating desired values
var width = $('#myselector').width();
var height = $('#myselector').height();
// set attrs and 'resume' force
svg.attr('width', width);
svg.attr('height', height);
force.size([width, height]).resume();
}
이 방법으로 그래프를 완전히 다시 렌더링하지 않고 속성을 설정하고 필요에 따라 d3를 다시 계산합니다.이것은 적어도 중력점을 사용할 때는 효과가 있습니다.그것이 이 해결책의 전제 조건인지 잘 모르겠습니다.확인 또는 부인할 수 있는 사람?
건배, g
커스텀 로직을 바인드하여 이벤트의 크기를 조정하고 싶다면, 현재는 SVGElement의 경계 상자에 ResizeObserver 브라우저 API를 사용할 수 있습니다.
이것은 또한 근처의 요소 크기 변경으로 인해 컨테이너 크기가 조정되는 경우를 처리합니다.
광범위한 브라우저 지원을 위한 폴리필이 있습니다.
UI 컴포넌트에서는 다음과 같이 동작합니다.
function redrawGraph(container, { width, height }) {
d3
.select(container)
.select('svg')
.attr('height', height)
.attr('width', width)
.select('rect')
.attr('height', height)
.attr('width', width);
}
// Setup observer in constructor
const resizeObserver = new ResizeObserver((entries, observer) => {
for (const entry of entries) {
// on resize logic specific to this component
redrawGraph(entry.target, entry.contentRect);
}
})
// Observe the container
const container = document.querySelector('.graph-container');
resizeObserver.observe(container)
.graph-container {
height: 75vh;
width: 75vw;
}
.graph-container svg rect {
fill: gold;
stroke: steelblue;
stroke-width: 3px;
}
<script src="https://unpkg.com/resize-observer-polyfill@1.5.1/dist/ResizeObserver.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<figure class="graph-container">
<svg width="100" height="100">
<rect x="0" y="0" width="100" height="100" />
</svg>
</figure>
// unobserve in component destroy method
this.resizeObserver.disconnect()
directed 하는 사용자는 D3 v4/v5를 합니다.size
메서드는 더 이상 존재하지 않습니다.다음과 같은 것이 나에게 효과가 있었다(이 github 문제에 근거한다).
simulation
.force("center", d3.forceCenter(width / 2, height / 2))
.force("x", d3.forceX(width / 2))
.force("y", d3.forceY(height / 2))
.alpha(0.1).restart();
언급URL : https://stackoverflow.com/questions/16265123/resize-svg-when-window-is-resized-in-d3-js
'programing' 카테고리의 다른 글
Docker-compose mysql: Import .sql (0) | 2022.12.10 |
---|---|
MySQL - SELECT 쿼리에 기반한 업데이트 쿼리 (0) | 2022.12.10 |
Thread.sleep과타임 유닛sleep (0) | 2022.12.10 |
QTCreator에서 사용하기 위해 설치된 mariadb10과 RPI3(Stretch)를 교차 컴파일하려면 어떻게 해야 합니까? (0) | 2022.12.10 |
MySQL에서 "Every derived table must airas"라는 오류는 무엇입니까? (0) | 2022.12.10 |