Reputation: 660
I am trying to build a simple dashboard in D3.js and vanilla JS. It looks like the image below. I have added a border to make it easier to visualize how I have designed it. The problem is that I want the grid to use the whole width. Now there is a big margin space on the left and the right of the container that I want to reduce (the drawing). Is there an easy way to do this?
I couldn't find any information on this on https://www.w3schools.com/css/css_grid_container.asp.
const height = 500;
const width = 800;
const skierIconSvg = 'https://image.flaticon.com/icons/svg/94/94150.svg';
const gate =
'https://docs.google.com/drawings/d/e/2PACX-1vReBMnm0oMHA-DuF_s6ds4irdAl_Y_zSbW3rO3DzG6u2Gmp2_ta2tFXO-poCOm7wXx02Dzd2EsT0c13/pub?w=186&h=290';
const finish =
'https://docs.google.com/drawings/d/e/2PACX-1vTWOmvwPIu2MrEbZAla5m2N5CcPVsPSEKHeKBI0sZsF9wKkMhZosnOmgMo1WHTnnAPA9i5LV0p0LR_r/pub?w=186&h=290';
const [p1, p2, p3] = [
[80, 100],
[750, 230],
[750, 230],
];
const svg = d3
.select('#container')
.append('svg')
.attr('viewBox', `0 0 800 240`);
// Store a reference to the span we're going to update
const skierHeight = d3.select('#skier-height');
const vek = document.querySelector('#vekt');
console.log(vek.value);
const line = svg.append('line').attr('stroke', 'black');
const connection = svg.append('line').attr('stroke', 'green');
const marker = svg
.append('circle')
.attr('r', 5)
.attr('stroke', 'red')
.attr('fill', 'none');
const g = svg
.append('g')
.attr('cursor', 'move')
.attr('pointer-events', 'all')
.attr('stroke', 'transparent')
.attr('stroke-width', 30);
const start = g
.append('image')
.attr('id', 'sdjjjjj')
.datum(p1)
.attr('href', gate)
.attr('width', 100)
.attr('height', 100)
.call(
d3
.drag()
.subject(([x, y]) => ({
x,
y,
}))
.on('drag', dragged)
);
const mal = g
.append('image')
.attr('id', 'sdjj')
.datum(p2)
.attr('href', finish)
.attr('width', 100)
.attr('height', 100)
.attr('transform', 'translate(710, 140)')
.call(
d3
.drag()
.subject(([x, y]) => ({
x,
y,
}))
.on('drag', dragged)
);
const skier = g
.append('image')
.attr('id', 'skier')
.datum(p3)
.attr('href', skierIconSvg)
.attr('width', 100)
.attr('height', 100)
.attr('transform', 'translate(-50, -70)')
.call(
d3
.drag()
.subject(() => ({
// Use where the skier is, not where he's supposed to be
x: Number(skier.attr('x')),
y: Number(skier.attr('y')),
}))
.on('start', () => {
// Interrupt all transitions
skier.interrupt();
connection.interrupt();
marker.interrupt();
})
.on('drag', dragged)
.on('end', dropSkier)
);
update();
function dragged(d) {
d[0] = d3.event.x;
d[1] = d3.event.y;
update();
potensiellEnergi();
}
function update() {
const t = (width + height) / distance(p1, p2);
const l1 = interpolate(p1, p2, t);
const l2 = interpolate(p2, p1, t);
const p = interpolate(p1, p2, project(p1, p2, p3));
connection.attr('x1', p3[0]).attr('y1', p3[1]);
connection.attr('x2', p[0]).attr('y2', p[1]);
marker.attr('cx', p[0]).attr('cy', p[1]);
line.attr('x1', l1[0]).attr('y1', l1[1]);
line.attr('x2', l2[0]).attr('y2', l2[1]);
start.attr('cx', (d) => d[0]).attr('cy', (d) => d[1]);
skier.attr('x', (d) => d[0]).attr('y', (d) => d[1]);
mal.attr('cx', (d) => d[0]).attr('cy', (d) => d[1]);
skierHeight.text(`${getHeight(p, p1, p2).toFixed(2)} meter`);
}
function distance([x1, y1], [x2, y2]) {
return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
}
function interpolate([x1, y1], [x2, y2], t) {
return [x1 + (x2 - x1) * t, y1 + (y2 - y1) * t];
}
function project([x1, y1], [x2, y2], [x3, y3]) {
const x21 = x2 - x1,
y21 = y2 - y1;
const x31 = x3 - x1,
y31 = y3 - y1;
return (x31 * x21 + y31 * y21) / (x21 * x21 + y21 * y21);
}
function getHeight([xp, yp], [x1, y1], [x2, y2]) {
// Note that y is counted from top to bottom, so higher y means
// a point is actually lower.
// First, the total height is 100 metres.
const pxPerMeter = (y2 - y1) / 100;
// Calculate the height diff in pixels
const heightDiffPx = y2 - yp;
// Now transform it to meters
return heightDiffPx / pxPerMeter;
}
function vektVelger() {
const vektVerdi = document.querySelector('#vekt');
const vektDisplay = document.querySelector('#skier-vekt');
vektDisplay.innerHTML = vektVerdi.value;
}
function potensiellEnergi() {
const vektVerdi = parseInt(document.querySelector('#skier-vekt').textContent);
const skierHeight = parseInt(
document.querySelector('#skier-height').textContent
);
const hastighet = document.querySelector('#skier-hastighet');
const potEDisplay = document.querySelector('#skier-potentialenergi');
const potEnergi = `${Math.round(vektVerdi * skierHeight * 9.8)}`;
const hastighetsutregning = `${Math.round(
Math.sqrt(2 * (skierHeight * 9.8))
)}`;
return (hastighet.innerHTML = `${hastighetsutregning}`)(
(potEDisplay.innerHTML = `${potEnergi}`)
);
}
function dropSkier(d) {
const projection = interpolate(p1, p2, project(p1, p2, p3));
skier
.transition()
.duration(500)
// First down to the ground
.attr('x', projection[0])
.attr('y', projection[1])
.on('end', () => {
skier
.transition()
.duration(2500)
.ease(d3.easeQuadIn)
// First down to the ground
.attr('x', p2[0])
.attr('y', p2[1]);
});
// Remove the line together with the skier
connection
.transition()
.duration(500)
// First down to the ground
.attr('x1', projection[0])
.attr('y1', projection[1]);
marker.transition().duration(700).remove();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script src="https://d3js.org/d3.v5.js"></script>
<link
href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@300&display=swap"
rel="stylesheet"
/>
<link
href="https://fonts.googleapis.com/css2?family=Amatic+SC:wght@700&display=swap"
rel="stylesheet"
/>
<link
href="https://fonts.googleapis.com/css2?family=Open+Sans&display=swap"
rel="stylesheet"
/>
<!-- Bootstrap -->
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu"
crossorigin="anonymous"
/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
/>
<style>
body {
background-color: white;
margin: 1px;
font-family: 'Noto Sans JP', sans-serif;
}
.container {
color: black;
height: 100%;
width: 100%;
display: grid;
grid-gap: 2px;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 40px auto auto auto;
grid-template-areas:
'h h h h h h h h h h h h'
'b b b r r r r r r r r r'
'f f f f f f f f f f f f';
}
.container div {
display: flex;
width: 100%;
justify-content: center;
align-items: center;
color: black;
}
.header {
grid-area: h;
}
.bib {
grid-area: b;
background-color: white;
font-size: 1.6em;
border-style: solid;
}
.resultat {
grid-area: r;
font-size: 1em;
}
.resultat {
justify-items: center;
justify-content: center;
}
.footer {
grid-area: f;
border-style: solid;
font-size: 1.2EM;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Forsøk på å lage en tutorial i JavaScript og D3.js</h1>
</div>
<div class="bib">
<p>Denne interaktive visualiseringen regner ut den estimerte hastigheten en
utøver har i mål ved å kjøre rett ned bakken med utgangspunkt i
høydeforskjell mellom utøverens lokasjon og mål og utøverens vekt.
Estimeringen tar ikke hensyn til energi som går med til anvendte krefter,
dvs. luftmotstand eller friksjon. Høydeforskjellen justerer du ved å ved
dra skikjøreren opp og ned bakken, mens vekten bestemmer du i meyen under
figuren.</p>
<br />
</div>
<div class="resultat">
<div id="container"></div>
</div>
<div class="footer"><form class="form-inline">
<div class="form-group">
<label for="exampleInputName2">Velg vekt</label>
<input
type="number"
class="form-control input-lg"
id="vekt"
placeholder="Velg vekt"
/>
</div>
<button
type="button"
class="btn btn-default btn-lg"
value="velg"
onclick="vektVelger()"
>
Velg
</button>
</form><table>
<tr>
<td>Høydeforskjell:</td>
<td><span id="skier-height"></span></td>
</tr>
<tr>
<td>Vekt:</td>
<td><span id="skier-vekt">70</span> kg</td>
</tr>
<tr>
<td>Gravitasjonskraft (fg):</td>
<td><span id="skier-gravitasjon">9.8</span> m/sek/sek</td>
</tr>
<tr>
<td>Tilgjengelig potensiell energi:</td>
<td><span id="skier-potentialenergi">0</span></td>
</tr>
<tr>
<td>Hastighet i mål:</td>
<td><span id="skier-hastighet">0</span> m/sek</td>
</tr>
</table>
</div>
</div>
</div>
<script src="skier.js"></script>
</body>
</html>
Upvotes: 0
Views: 104
Reputation: 2056
Based on my understanding you want to remove the space from the left and right. Space is caused by the max-width
in the bootstrap since it won't allow the container
to go outside a specific range. so if you want to extend you should either remove the max-width
or use container-fluid
instead.
.container {
max-width: unset;
}
If that didn't help let me know.
Upvotes: 2