I want to change the size of Highcharts legend (especially its width). Here is some of the code I tried to use based on research I did:
$(window).resize(changeSummaryLayout);
function changeSummaryLayout() {
var w = window.innerWidth;
if (w < 1370 && w > 992) {
for (i = 0; i < charts.length; i++) {
charts[i].highcharts().setTitle({ x: -5 });
charts[i].highcharts().legend.options.y = 150;
charts[i].highcharts().margin[3] = 0;
charts[i].highcharts().legend.options.width = 200;
charts[i].highcharts().legend.itemStyle.width = 200;
for (var index in charts[i].highcharts().series) {
charts[i].highcharts().legend.destroyItem(charts[i].highcharts().series[index]);
}
charts[i].highcharts().legend.render();
//charts[i].highcharts().legend.update({ itemStyle150 });
//charts[i].highcharts().isDirtyLegend = true;
//charts[i].highcharts().redraw();
//charts[i].highcharts().isDirtyBox = true;
}
$('#chartContainer').css('height', '400px');
$('.pieChartTotal').css('height', '390px');
$('.pieChartCanvasSum').css('height', '330px !important');
$('.highcharts-container').children().css('height', '330px');
$('.highcharts-background').attr('height', '330px');
}
None of those solutions is worknig to change the width and, what is strange, the width gets updated only after I hover my mouse over legend. Can anyone explain to me why does this happen?
Is there any solution that will work here?
I think you can try like:
var chart = new Highcharts.Chart({
......
});
function resizeWindow(){
chart.legend.options.width = widthyouwanttoadd;
chart.legend.itemStyle.width = widthyouwanttoadd;
for(var index in this.chart.series) {
chart.legend.destroyItem(chart.series[index]);
}
chart.legend.render()
}
Related
I have the classical Progress bar in Javascript. I Would like to simply place the vertical bar without seeing it moving on the screen.
function progressbar() {
var vertical_bar2 = document.querySelector("#P5 .vl5");
var element = document.getElementById("myprogressBar");
var ValueSet = 25
var width = 0;
document.getElementById("vl5").style.display='';
document.getElementById("value2").style.display='';
document.getElementById("value1").style.display='';
var identity = setInterval(scene, 10);
function scene() {
if (width >= ValueSet) {
clearInterval(identity);
} else {
width++;
vertical_bar2.style.left = `${width}%`;
document.getElementById("value2").innerHTML = ValueSet
}
}
}
I am trying the following script but it is not working
function progressbar() {
var vertical_bar2 = document.querySelector("#P5 .vl5");
var element = document.getElementById("progressBar");
var CE = 25
var width = 0;
document.getElementById("vl5").style.display='';
document.getElementById("Value2").style.display='';
document.getElementById("Value1").style.display='';
vertical_bar2.style.left = 25;
document.getElementById("Value").innerHTML = CE
}
Based on the code your provided, it looks like you just need to set a unit for the left property of your bar. Currently you are only setting a value (25), but without a unit (%, px, em, etc.) it will not apply anything.
vertical_bar2.style.left = "25%";
or
vertical_bar2.style.left = `${CE}%`;
I am working on a project where I have a slideshow with images as follows:
img {
width:100vw;
height:100vh;
object-fit:cover;
}
This makes the images fullscreen and behave like background-size:cover, so they fill out the whole viewport on any screen size without distortion.
I would like to tag certain points with text tooltips on these images. For this purpose I have found Tim Severien's Taggd, which works great on responsive images, but in my case the object-fit:cover; property makes the tagged positions inaccurate.
I have tried everything from CSS hacks to improving Tim's code, but I am out of ideas. If you have any solution or workaround in mind please share.
Thank you!
well i actually wanted to do the same thing.
here is what i've done.
maybe it will help someone in the future.
it would be great if this feature could be integrated in taggd.
function buildTags()
{
// be aware that image.clientWidth and image.clientHeight are available when image is loaded
var croppedWidth = false;
var expectedWidth = 0;
var croppedWidthHalf = 0;
var imageWidth = 0;
var croppedHeight = false;
var expectedHeight = 0;
var croppedHeightHalf = 0;
var imageHeight = 0;
var naturalRatio = image.naturalWidth/image.naturalHeight;
var coverRatio = image.clientWidth/image.clientHeight;
if(Math.abs(naturalRatio - coverRatio) < 0.01)
{
// the image is not cropped, nothing to do
}
else
{
if(naturalRatio > coverRatio)
{
// width is cropped
croppedWidth = true;
expectedWidth = image.clientHeight * naturalRatio;
croppedWidthHalf = (expectedWidth - image.clientWidth)/2;
imageWidth = image.clientWidth;
}
else
{
// height is cropped
croppedHeight = true;
expectedHeight = image.clientWidth / naturalRatio;
croppedHeightHalf = (expectedHeight - image.clientHeight)/2;
imageHeight = image.clientHeight;
}
}
function calcy(y)
{
if(croppedHeight)
{
var positiony = y * expectedHeight;
if(positiony > croppedHeightHalf)
return (positiony - croppedHeightHalf)/imageHeight;
else // tag is outside the picture because cropped
return 0; // TODO : handle that case nicely
}
else
return y;
}
function calcx(x)
{
if(croppedWidth)
{
var positionx = x * expectedWidth;
if(positionx > croppedWidthHalf)
return (positionx - croppedWidthHalf)/imageWidth;
else // tag is outside the picture because cropped
return 0; // TODO : handle that case nicely
}
else
return x;
}
var tags = [
Taggd.Tag.createFromObject({
position: { x: calcx(0.74), y: calcy(0.56) },
text: 'some tag',
}),
Taggd.Tag.createFromObject({
position: { x: calcx(0.9), y: calcy(0.29) },
text: 'some other tag',
}),
....
];
var taggd = new Taggd(image, options, tags);
}
$(window).bind("load", function() {buildTags();});
Is not possible. Think if the user has a tablet with 1024x768 resolution, when the user change view from horizontal to vertical the image can fill the space but you will loose part of the image, loose img quality, etc.
The best way for cross devices is to use big pictures and add in css
img {
height: auto;
width: 100%;
display: block;
}
And fill image background with a color;
In my actual Javascript, i preload some images and display them on the body of my index.html. I need a way to resize them in order to fot the width and height of the window. Here is my actual code:
function($) {
$.preLoadImages = function() {
var args_len = arguments.length;
for (var i = args_len; i--; ) {
var cacheImage = document.createElement('img');
cacheImage.src = arguments[i];
arrayimg.push(cacheImage);
}
arrayimg.reverse();
}
})(jQuery)
function resizing(img) {
var $image = img;
var image_width = $image.width;
var image_height = $image.height;
var body_width = $("#corps").width();
var body_height = $("#corps").height();
$image.width = body_width;
$image.height = body_height;
}
$.preLoadImages("./images/01.jpg", "./images/02.jpg", "./images/03.jpg", "./images/p1.jpg", "./images/p2.jpg", "./images/p3.jpg");
for ( j = 0; j < arrayimg.length; j++) {
resizing(arrayimg[j]);
}
This code actually works pretty well. The main problem is that the resize is not keeping the aspect of the actual picture. I need some code that respect the aspect ratio of the initial picture.
You can calculate the ratio like this:
var ratio = Math.min(body_width/image_width, body_height/image_height);
Then just multiply:
$image.width = ratio*body_width;
$image.height = ratio*body_height;
I assumed you want to "fit" the image inside the body. If you want to clip, replace Math.min with Math.max (and add overflow:hidden etc...)
I'm using Raphael.js. Everytime i load the page i get an error that reads:
con is undefined
x = con.x
I looked up con in the Raphael documentation, and this is what i found:
var con = R._getContainer.apply(0, arguments),
container = con && con.container,
x = con.x,
y = con.y,
width = con.width,
height = con.height;
//...
con is clearly defined here. Here is the code I am trying to load:
var paper = new Raphael(ele('canvas_container'), 500, 500);
window.onload = function() {
var circle = paper.circle(100,100,100);
for (i = 0; i < 5; i++) {
var multiplier = i * 5;
paper.circle(250 + (2 * multiplier), 100 + multiplier, 50 - multiplier);
}
}
Has anyone else gotten this error? Is this a bug in the version of Raphael that I have or is there some other problem?
Try moving the paper instantiation inside your window's load function:
window.onload = function() {
var paper = new Raphael(ele('canvas_container'), 500, 500);
var circle = paper.circle(100,100,100);
for (i = 0; i < 5; i++) {
var multiplier = i * 5;
paper.circle(250 + (2 * multiplier), 100 + multiplier, 50 - multiplier);
}
}
If you try to get an element by its id before the DOM is ready, getElementById won't return anything. As you can see here, trying your code on an empty document shows the same result.
Raphael.js expects there to be a hard coded HTML element on the page with the name of the Raphael canvas (ie: "canvas_container"). If the HTML element is created during run time (dynamically in your JavaScript code), it will throw this error.
R._engine.create = function () {
var con = R._getContainer.apply(0, arguments),
container = con && con.container,
x = con.x,
y = con.y,
width = con.width,
height = con.height;
if (!container) {
throw new Error("SVG container not found.");
}
var cnvs = $("svg"),
css = "overflow:hidden;",
isFloating;
x = x || 0;
y = y || 0;
width = width || 512;
height = height || 342;
$(cnvs, {
height: height,
version: 1.1,
width: width,
xmlns: "http://www.w3.org/2000/svg"
});
if (container == 1) {
cnvs.style.cssText = css + "position:absolute;left:" + x + "px;top:" + y + "px";
R._g.doc.body.appendChild(cnvs);
isFloating = 1;
} else {
cnvs.style.cssText = css + "position:relative";
if (container.firstChild) {
container.insertBefore(cnvs, container.firstChild);
} else {
container.appendChild(cnvs);
}
}
container = new R._Paper;
container.width = width;
container.height = height;
container.canvas = cnvs;
container.clear();
container._left = container._top = 0;
isFloating && (container.renderfix = function () {});
container.renderfix();
return container;
};
see the news scroller on the top of this site
http://track.dc.gov/Agency/DH0
Any idea what library/functions this site uses to implment such a smooth scroller?
They have a very nicely formatted block of code you can study. Open your favorite JS debugger when you visit the site, wait for everything to get moving, and then press "Break All" or the equivalent in your debugger. You'll see something like the following:
Dashboard.UI.EndlessLine = function() {
var me = this;
me.jq = $(me);
me.classNames = { CONTAINER: "uiEndless", VIEW: "uiEndlessView", CANVAS: "uiEndlessCanvas", TILE: "uiEndlessTile" };
var canvas = null;
var view = null;
var tiles = null;
var x = 0;
var xx = 0;
var canvasWidth = 0;
var step = 1;
var delay = 40;
me.initialize = function(container, data, handler) {
required(container, "container");
required(data, "data");
required(handler, "handler");
container.addClass(me.classNames.CONTAINER);
view = newDiv(me.classNames.VIEW);
canvas = newDiv(me.classNames.CANVAS);
view.append(canvas);
container.append(view);
x = 0;
xx = 0;
canvasWidth = 0;
tiles = me.populateTiles(data, handler);
container.click(function() {
if (me.started()) me.stop(); else me.start();
});
};
me._resize = function(size) {
};
var moveId = 0;
me.start = function() {
me.stop();
me.tick();
}
me.stop = function() {
if (moveId > 0) clearTimeout(moveId);
moveId = 0;
}
me.started = function() {
return moveId > 0;
};
me.tick = function() {
var tile = tiles.current();
var width = tile.calculatedWidth;
if (x < width - step) {
x += step;
} else {
x = 0;
tile.css("left", canvasWidth + "px");
if (tiles.advance()) {
xx = 0;
canvasWidth = 0;
do {
current = tiles.current();
width = current.calculatedWidth;
current[0].style.left = canvasWidth + "px";
canvasWidth += width;
} while (!tiles.advance());
} else {
canvasWidth += width;
}
}
canvas[0].style.left = -(xx) + "px";
xx += step;
moveId = setTimeout(me.tick, delay);
}
me.populateTiles = function(data, handler) {
var tiles = new Dashboard.Core.List();
var viewWidth = view.contentWidth();
var maxHeight = 0;
each(data, function() {
var tile = newDiv(me.classNames.TILE);
handler.call(this, tile);
tile.css({ left: canvasWidth + "px", top: 0 });
canvas.append(tile);
var width = tile.outerWidth();
var height = tile.outerHeight();
if (maxHeight < height) maxHeight = height;
tile.calculatedWidth = width;
canvasWidth += width; // getting width may only be done after the element is attached to DOM
tiles.append(tile);
view.height(height);
});
return tiles.createCycle();
}
}
I'm impressed -- everything looks professional and nicely namespaced.
Update: If you want an explanation of how it works, focus on the tick method defined above. Glossing over all the details (cause I haven't really studied it myself), it calculates a step size, moves the message element to the left by the some amount, and schedules the next tick call for 40 milliseconds in the future.
jQuery enthusiast, Remy Sharp, has his own Marquee Plugin that you can implement pretty easily. You can gather deeper details of it on his blog or by visiting the demo page.
For Mootools users, there's Mooquee.
You can also view the actual code for this example online at http://track.dc.gov/Resource/Script/ - do a search for "uiEndless" to find the target-scripting.