I'm trying to display a Chart.js graph inside a <canvas>, and this canvas is wrapped inside a <div>.
I want the graph to be responsive, have a fixed height of 700px and a width of 80% of the page's width. On top of all, I want this graph to be centered inside the page ! My code is below
HTML
<div class='chartContainer'>
<canvas id="canvas"></canvas>
</div>
CSS
.chartContainer{
text-align: center;
}
canvas{
width: 80% !important;
height: 700px !important;
margin: 0;
}
JAVASCRIPT
new Chart(canvasContext, {
type: 'line',
data: {
labels: hourLabels,
datasets: dataToRender
},
options: {
responsive: true,
maintainAspectRatio: false
});
My problem is : I can't center it, the <div> takes the whole page but the <canvas> seems to have a margin applied to it even though it doesn't appear inside the DOM console...
Screenshot of the apparent margin
Can anyone point my problem ? Thank you very much :-)
Put this in your CSS
canvas{
margin: 0 auto;
}
Related
I'm trying to create a map of button elements that overlay a full-screen image, positioned over all the 'buttons' depicted on the image. When the image resizes, the button elements should resize as well.
I initially used an SVG image map for this, but it had a positioning bug (the link below) that didn't allow for the video player inside the foreignObject to show.
SVG foreignObject and absolute positioning
I figured using absolute positioning, and JS to measure the width of the background image was the best way to go. However, I'm having trouble making it work.
Below is the project, with the white box needing to be positioned over the background image (the entire box, with chocolates, and the screen).
The image is within a div as a background, like so:
export const BackgroundLightsOn = styled.div`
position: absolute;
background: url(${BgLightsOn});
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
height: 100%;
width: 100%;
border: 1px solid red;
`
Unfortunately, getting the dimensions of this DOM element gets the dimensions of the div, not the image (which is sometimes larger than the viewport). Below is the 'resizing' code, but this connects to backgroundRef (which is the div element the image is the background, not the image itself).
import React, { useEffect, useRef } from 'react';
import {
TruffleTinContainer,
TruffleTinOutside,
} from '../truffle-tin/styledTruffleTin';
export default function TruffleTin({ backgroundRef }) {
const truffleTinRef = useRef();
const initialPos = { x: 150, y: 150 };
const padding = 25;
let truffleBoxWidth = 0;
let truffleBoxHeight = 0;
useEffect(() => {
truffleBoxWidth = truffleTinRef.current.offsetWidth;
truffleBoxHeight = truffleTinRef.current.offsetHeight;
resize();
}, []);
function resize() {
let backgroundDivRect = backgroundRef.current.getBoundingClientRect();
truffleTinRef.current.style.left =
(initialPos.x / truffleBoxWidth) * backgroundDivRect.width -
padding +
'px';
truffleTinRef.current.style.top =
(initialPos.y / truffleBoxHeight) * backgroundDivRect.height -
padding +
'px';
}
useEffect(() => {
window.addEventListener('resize', resize);
return () => window.removeEventListener('resize', resize);
});
return (
<TruffleTinContainer ref={truffleTinRef}>
I'm the truffle tin
</TruffleTinContainer>
);
}
See the GIF below for the issue:
What's the best way to get this div to proportionally match the width of the background image?
(Edit: I changed the 'div with image background' to an img tag, but even then, the getBoundingClientRect shows not the width of the image, but the width of the viewport:
(in other words, even though the image is much wider than the viewport, I'm still getting the viewports dimensions, when what I want is the image's dimensions))
You don't need JS for that. This is achieved with plain CSS, all you need is the button center positions relative to left-top corner of the block. Sample HTML/CSS:
<div class='wrapper'> <!-- Will need this later -->
<div class='container'>
<a class='button' style='--left: 25%; --top: 20%'>1</a>
<a class='button' style='--left: 35%; --top: 80%'>2</a>
</div>
</div>
.container{
position: relative;
background: url('/path/to/image');
background-size: 100% auto;
}
.button{
position: absolute;
left: var(--left);
top: var(--top);
transform: translate(-50%, -50%); /* Move button a bit so its center matches the actual position */
/* These are just for visualization */
width: 50px;
height: 50px;
border-radius: 100%;
background: pink;
display: flex; align-items: center; justify-content: center;
}
The next step is to make .container have a constant width, or at least a constant width/height ratio if you care about vertical resizing. The constant width is achieved with a simple min-width. To avoid horizontal scroll we will add a .wrapper to hide the cut-off sides:
.wrapper{
display: flex;
align-items: center;
max-width: 100%;
overflow: hidden;
}
/* A-and a min-width for .container */
.container{
min-width: 1200px; /* Or whatever */
}
If you need a fixed ratio:
.container::before{
content: '';
display: block;
padding-top: 56.25%; /* 56.25% of the parent width this is, ratio 16x9 */
}
min-width can still be applied if needed. There's an aspect-ratio CSS property that can be used instead of that pseudo-element hack, but it is supported only in relatively fresh browser versions; still might be used if you don't plan supporting a little outdated browsers.
I'm using Highcharts to render charts on webpage. Now I found an issue if I use min-width and max-width CSS option on container div:
<div id="container" style="min-width: 310px; max-width: 960px; height:400px;"></div>
I added a background image with this method:
Highcharts.theme = {
chart: {
backgroundColor: '#FFFFFF',
plotBackgroundImage: '/path/to/mybackgroundimage.png'
}
};
This image has 960px width and 400px height and it shows well on desktops, but if I check it on mobile devices the image's apect ratio has gone and the image become distorted.
Is there a backgroundSize:'cover' or something like this to fix the image position and size on different screen widths?
You can disable the plotBackgroundImage parameter and set the backgroundColor as transparent. Then apply the background img in CSS (for the container).
CSS
#container {
background:url(https://www.highcharts.com/samples/graphics/skies.jpg) 0% 0%;
background-size:cover;
}
chart:
chart: {
backgroundColor: 'rgba(0,0,0,0)',
type: 'line'
}
Example
- http://jsfiddle.net/4q7atyt9/
I think you can use rem instead of px.
rem is called "root em" can change the size depend on the screen size.
<div id="container" style="min-width: 20rem; max-width: 60rem; height:15rem;"></div>
Note:
10px = 0.625rem;
16px = 1rem;
in your css
#media screen and (min-width: 480px) and (max-width:980px) {
#container {
min-width: 20rem; //change the size
max-width: 60rem;
height: 15rem;
}
}
I am creating a UI control. It is a bar which shows colored areas in relative proportion to each other based on the input. A few of the requirements are that there be a 1px gutter between the colors and that every color must be shown at a minimum of 1px no matter how small the relative width.
The bar looks like this:
The gutters are being placed using a technique described by the pocketgrid documentation:
.threshold-container {
height: 8px;
$threshold-horiz-gutter: 1px;
&.block-group {
margin-left: -$threshold-horiz-gutter;
}
.threshold {
height: 100%;
min-width: 2px;
&.block {
padding-left: $threshold-horiz-gutter;
}
.colored-area {
height: 100%;
width: 100%;
}
}
}
There is a codepen here which provides a working example: http://codepen.io/ghoti143/pen/eZNXVW
The problem I face is that when the relative proportion of any one color is sufficiently small, the last color area wraps to the next line and looks like this:
To replicate this issue, visit the codepen project and enter this as the Threshold Array value:
[{"value":0,"color":"LightGreen"},
{"value":50,"color":"PaleGoldenrod"},
{"value":5000,"color":"LightSalmon"},
{"value":10000,"color":"Salmon"}]
In this case, the width style of the LightGreen area is 0.33333%. This equates to 0.495px at a bar width of 150px. However, because of the requirement to always show at least 1px of width for each color, the LightGreen area is consuming 2px of width (1px content + 1px padding).
Thanks for any insights you may have!
You can use the css calc function to subtract out the 1px margins from the width calculations for each section. [For example]http://codepen.io/anon/pen/ZWGNVY
coloredAreas.push({
color: thresholds[i].color,
width: 'calc(' + width + '% - 1px)'
});
I'm using flot as a plotting javascript utility.
Here is the sample I'm using which allows toggle...
https://github.com/flot/flot/blob/master/examples/series-toggle/index.html
What I want to achieve is to move the legend to the right side of the plot as having several curves causes the legend to grow big and block the view.
I tried the "aboveData" option as the api suggested:
$.plot("#placeholder", data, {
yaxis: {
min: 0
},
xaxis: {
tickDecimals: 0
},grid: {show:true, aboveData:false},
});
It did not do anything.
Then I tried changing the css to add a "left" property to the table:
.legend table {
border-spacing: 5px;
left:800px;
}
which does move the legend table to right but there is an opaque white div container left behind.
Any idea how to remove it?
You method kinda works if you use the parent legend div instead of the table:
.legend {
position: absolute;
left:800px;
}
This is probably not the best way to achieve your goals though. flot provides the ability to relocate the legend to a container (div) of your choice. So to put the legend right of the plot, I'd do:
<div id="flotGraph" style="width: 400px; height: 400px; float: left"></div>
<div id="legendContainer" style="float: left"></div>
And then use the legend container property:
$.plot("#placeholder", data, {
yaxis: {
min: 0
},
xaxis: {
tickDecimals: 0
},
legend: {
container: $('#legendContainer')
}
});
Here's an example.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
vertical alignment of image inside a div
OK, this what I'm trying to do :
I'm having an empty div (a box), with almost no height.
I'm making an AJAX request to load some content into it.
Before loading the content, I want to display in a typical "ajax loading" rotating gif.
I've managed to :
Center the img horizontally (by putting it inside another div with text-align:center;)
What is left :
Be able to give some height to that empty div. (easy)
Vertically align the image, so that it appears on the very center of the box. (I've got absolutely no idea how to do this. I'm currently setting an upper margin, which works for one particular box, but which wouldn't work if the box already has some different height...)
How would you go about it?? (Any possible idea is acceptable. CSS/Javascript whatever...)
http://jsfiddle.net/teresko/5mG2y/
The basic idea is the use display: table-cell; and then vertical-align: middle;
the HTML
<div class="container">
<div class="holder">
<img class="stuff" src="path/to/image.png">
</div>
</div>
the CSS:
.container{
/* the container in which image is placed */
height: 300px;
margin: 0 auto;
width: 200px;
}
.holder{
display: table-cell;
width: 100%;
vertical-align: middle;
height: inherit;
}
.stuff{
display: block;
}
This way the placement of image will not depend on dimensions of container. It also can be adjusted to be in horizontal center too. All you have to do is to add .stuff{ margin: 0 auto;}.
Don't forget that table-cell is not the correct usage. You don't want images to be trated as table cells, since table cells should only contain table data.
Just raising a caution flag. Stick to the semantics.
it's better to use the answer from that other thread.
This:
#container { position: relative; }
#container img {
position: absolute;
left: 50%;
top: 50%;
margin-top: /* -1/2 the height of the image */
margin-left: /* -1/2 the width of the image */
}
Good luck!
With jQuery
//HTML
<div><img src="loader.gif" class="loader" alt="Loader" /></div>
//JS
$.fn.centeringIn = function(){
var pere = this.parent();
(pere.css("position") == 'static') ? pere.css("position","relative"):pere.css("position");
this.css({
'position' : 'absolute',
'top' : ( pere.height() - this.height() )/2+'px',
'left' : ( pere.width() - this.width() )/2+'px'
});
}
$(document).ready( function() {
$('.loader').centeringIn();
});
Add some margin-top to the image style so that it is aligned in the middle of the div. Say your div is 50px height and your image has a height of 5px. Then make your margin-top 20px to put it in the middle.