Autoscaling an svg on window resize - javascript

I have this code:
function myClient() {
if (!(this instanceof arguments.callee)) {
return new arguments.callee(arguments);
}
var self = this;
this.init = function() {
self.viewResized();
self.drawSvg();
};
this.viewResized = function () {
var width = $('body').width(),
windowHeight = $(window).height(),
svgCanvasHeight = width * (369.0 / 567.0);
$('#svg').css({
'margin-top': 10
});
}
this.drawSvg = function() {
// ...
}
var myClient;
jQuery(function() {
myClient = new myClient();
$(window).resize(function() {
console.log("window resized");
myClient.viewResized();
});
});
How do I get the svgCanvasHeight in drawSvg dynamically so that when the window is resized, so does the svg's viewBox and svg?

Answered here: Get the real size of a SVG/G element
With regards to viewBox:
I have had a lot of problems with SVG and jQuery.
While html attributes are case-insensitive the svg ones (like viewBox) aren't. I'd try using the element.setAttribute(name, value) native JS function. This worked for me, and make sure you're using viewBox with the capital B.

Related

How can overwrite this calculation?JQuery

I have this site:
link
I have two pages that contain the same divs... on a page I want to be a calculation (to div) on another page another calculation..,
CODE JS:(NEW)
jQuery(document).ready(function ($) {
var windowsizecontact = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
console.log("ecran contact:",windowsizecontact);
var stanga= jQuery('.contact-stanga').outerWidth();
console.log("latime-stanga:",stanga);
var dreapta= jQuery('.contact-dreapta').outerWidth();
console.log("latime-dreapta:",dreapta);
var contentcontactwh=windowsizecontact-stanga-dreapta;
console.log("rezultat",contentcontactwh);
$('.contact-container #primary').css{('cssText', contentcontactwh'!important')}; //here I want to overide this div
});
This is old code (which must remain and apply only on certain pages)
jQuery(document).ready(function ($) {
var latime= Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var _stanga= jQuery('#secondary').outerWidth();
var selectat= jQuery('.selectat').outerWidth();
var calcul=latime-_stanga-selectat;
$('#primary').css('width', calcul);
});
My problem is that the new code (from above) does not apply to div on the contact page because old code ... and I need to do to be unique. (Old code should remain as )
It can override somehow?
EDIT:
jQuery(document).ready(function ($) {
var windowsizecontact = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
console.log("ecran contact:",windowsizecontact);
var stanga= jQuery('.contact-stanga').outerWidth();
console.log("latime-stanga:",stanga);
var dreapta= jQuery('.contact-dreapta').outerWidth();
console.log("latime-dreapta:",dreapta);
var contentcontactwh=windowsizecontact-stanga-dreapta;
console.log("rezultat",contentcontactwh);
console.log("------------------");
if ($("#primary").hasClass("content-contact")) {
alert("ggg");
$('.content-contact').css("width:",contentcontactwh); //here now is problem
}else
{
var latime= Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var _stanga= jQuery('#secondary').outerWidth();
console.log("latime-stanga:",_stanga);
var selectat= jQuery('.selectat').outerWidth();
console.log("latime-stanga:",_stanga);
var calcul=latime-_stanga-selectat;
$('#primary').css('width', calcul);
}
});
I tried the first option suggested ... but now not only apply div width of my.
I've done wrong syntax?
var app = app || {};
app.readyFunction = function () {
// normal
};
// on website you want to overwrite
app.readyFunction = function () {
// altCode
};
// and in document ready just call
$(function () {
app.readyFunction();
});
If al the rest works and if the problem is only in this line then lets change this line a bit.
this
$('.content-contact').css("width:",contentcontactwh); //try removing the : after width
to
$('.content-contact').css("width",contentcontactwh);
Also please provide the console error message if this does not work.

HighCharts: How to use reflow to allow auto-resize after changing size

In our Angular app we're using highcarts-ng for our HighCharts implementation.
Here is the Chart Maximize and Minimize function, which works:
function expandChartPanel() {
vm.chartMaxed = !vm.chartMaxed;
viewHeader = ScopeFactory.getScope('viewHeader');
highChart = ScopeFactory.getScope('highChart');
var chart = highChart.chartObject;
var highChartContainer = document.getElementById("highchart-container");
var highChartContainerWidth = document.getElementById('highchart-container').clientWidth;
var highChartContainerHeight = document.getElementById('highchart-container').clientHeight;
var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight;
if (vm.chartMaxed) {
vs.savedWidth = highChartContainerWidth;
vs.savedHeight = highChartContainerHeight;
console.log('savedWidth = ', vs.savedWidth);
console.log('savedHeight = ', vs.savedHeight);
root.chartExpanded = true;
viewHeader.vh.chartExpanded = true;
highChart.highChartMax = true;
highChartContainerHeight = document.getElementById('highchart-container').clientHeight;
windowWidth = window.innerWidth;
windowHeight = window.innerHeight;
highChart.chartConfig.size.width = windowWidth;
highChart.chartConfig.size.height = windowHeight - 220;
chart.setSize(windowWidth, windowHeight - 220);
}
else {
root.chartExpanded = false;
viewHeader.vh.chartExpanded = false;
highChart.highChartMax = false;
highChart.chartConfig.size.width = vs.savedWidth;
highChart.chartConfig.size.height = vs.savedHeight;
chart.setSize(vs.savedWidth, vs.savedHeight);
}
highChart.restoreChartSize();
}
Here is the reflow function:
function restoreChartSize() {
console.log('restoreChartSize');
if (!vs.chartObject.reflowNow) {
vs.chartObject.reflowNow = vs.chartObject.reflowNow = function() {
this.containerHeight = this.options.chart.height || window.window.HighchartsAdapter.adapterRun(this.renderTo, 'height');
this.containerWidth = this.options.chart.width || window.window.HighchartsAdapter.adapterRun(this.renderTo, 'width');
this.setSize(this.containerWidth, this.containerHeight, true);
this.hasUserSize = null;
}
}
vs.chartObject.reflowNow();
}
This reflow function above, works perfectly in this jsFiddle, but not in our app.
The full Gist file of our HighChartsDirective file.
After clicking Maximize, the chart will expand to the full size of the browser window, but then after dragging to resize the browser window, I call the restoreChartSize function, which activates the reflow.
However the size of the chart does not go to auto-size 100% 100%, it goes back to the previous size of the chart :(
Before Maximize:
After the Maximize function:
Now after resizing the browser window:
window.onresize = function(event) {
console.log('window resizing...');
highChart = ScopeFactory.getScope('highChart');
highChart.restoreChartSize();
console.log('highChart.chartConfig = ', highChart.chartConfig);
};
^ back to the smaller static sizes, not auto-size 100%
You can do this by adding a new method to chart that will manually trigger the reflow like so:
chart.reflowNow = function(){
this.containerHeight = this.options.chart.height || window.window.HighchartsAdapter.adapterRun(this.renderTo, 'height');
this.containerWidth = this.options.chart.width || window.window.HighchartsAdapter.adapterRun(this.renderTo, 'width');
this.setSize(this.containerWidth, this.containerHeight, false);
this.hasUserSize = null;
}
Then whenever you want to get away from manual resizing using setSize() just call chart.reflow()
Here's an working example: jsFiddle
Reference taken from: github-issue
UPDATE for ng-highcharts users
For doing this when using ng-highcharts library, you can simply pull out the chart object in the controller that has highcharts-ng dependency and add the reflowNow function, like so:
var chart = this.chartConfig.getHighcharts();
chart.reflowreflowNow = function (){ ... }
This is also the recommended way to pull out chart to do custom jobs by author of ng-highcharts as noted here and this fiddle.
I ended up finding an alternative solution to be the only thing I could get working, and it actually was pretty simple and straight forward to do. In case anyone else is looking for a fix for this, here's links to the resources that were useful and solved the issue for me.
You can simply add this to your chart config object, at the same level as the config.series or config.options. The comment references info but the actual solution that worked for me uses $timeout with 0 seconds, here
*For using highcharts-ng obviously
http://plnkr.co/edit/14x7gfQAlHw12XZVhWm0?p=preview
$scope.chartConfigObject = {
// function to trigger reflow in bootstrap containers
// see: http://jsfiddle.net/pgbc988d/ and https://github.com/pablojim/highcharts-ng/issues/211
func: function(chart) {
$timeout(function() {
chart.reflow();
//The below is an event that will trigger all instances of charts to reflow
//$scope.$broadcast('highchartsng.reflow');
}, 0);
}
};

React.JS calculating img width in virtual DOM

I'm trying to find the width of an <img> to center it via JavaScript.
Trying to calculate the width of this react.js DOM node returns 0.
var Player = React.createClass({
componentDidMount:function(){
var imgEl = this.refs.imgSize.getDOMNode();
console.log(imgEl.offsetWidth);
},
render: function () {
return (
<img ref="imgSize" src={this.props.imageURL} />
);
}
});
You could use the image's onLoad event to make sure it's loaded before you try this:
<script src="http://fb.me/react-0.12.2.js"></script>
<script src="http://fb.me/JSXTransformer-0.12.2.js"></script>
<script type="text/jsx;harmony=true">void function() { "use strict";
var Player = React.createClass({
_onLoad(e) {
console.log(e.target.offsetWidth)
},
render() {
return <img src={this.props.imageURL} onLoad={this._onLoad}/>
}
})
React.render(<Player imageURL="http://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg"/>, document.body)
}()</script>
I wrote a React library that exposes a size object (with width and height props) to your components.
You can use it like so for your use case:
var SizeMe = require('react-sizeme');
var Player = React.createClass({
componentDidMount:function(){
var imgEl = this.refs.imgSize.getDOMNode();
console.log(imgEl.offsetWidth);
},
render: function () {
// height and width via props!!
var width = this.props.width;
var height = this.props.height;
return (
<img ref="imgSize" src={this.props.imageURL} />
);
}
});
// Wrap your component with the SizeMe HOC!
module.exports = SizeMe()(Player);
Demo: https://react-sizeme-example-esbefmsitg.now.sh/
Github: https://github.com/ctrlplusb/react-sizeme

Reference to Raphael object

I need to create several Raphael objects in my program. field1 and field2 are div-elements. Each Raphael object (paper1,paper2,...) will have unique canvas and they all need to have exactly the same functionality. Raphael objects need to be created dynamically at later point. In the following examplecode I need to know which of the objects fires the mousedown event. I would also like to know in which div-element (field1/field2 here) is that mousedown event fired. How can I get the information?
var myProgram = (function() {
var paper1 = Raphael("field1", 200, 400, fieldActions);
var paper2 = Raphael("field2", 200, 400, fieldActions);
var planeAttrs = {
fill: "#fff"
};
function fieldActions(){
var that = this;
that.field = that.rect(0, 0, 200, 400, 30);
that.field.attr(planeAttrs);
that.field.mousedown( function(e) {
});
});
}());
that.field.mousedown( function(e) {
console.log(this, this.node, this.paper.canvas, this.paper.canvas.parentNode)
});
this - the rect raphael object
this.node - the rect svg dom element
this.paper.canvas - the svg dom element
this.paper.canvas.parentNode - div with id (field2/field1) which contains the svg that is clicked.
Here you go:
that.field.mousedown( function(e) {
var target = e.target;
var svgElem = target.parentNode;
var div = svgElem.parentNode;
alert(div.id);
});
http://jsfiddle.net/mihaifm/UyPn6/3/

Javascript Extensibility

I've a script, which manipulates with canvas. I call it like this:
namespace.module.do(canvas, paramString);
I'd like to move the call to the canvas itself, so it'll somewhat similar to:
<canvas namespace.module.dobehavior=paramString />
Can I do it with JS and if not how close can I get to it?
The canvas is a DOM object, so you could attach functions to it. In your example:
document.getElementsByTagName("canvas")[0].namespace.module.dobehavior = function(paramString) { ... code ... };
(obviously, document.getElementsByTagName("canvas")[0].namespace and document.getElementsByTagName("canvas")[0].namespace.module would need to be an object, so you might need to do
document.getElementsByTagName("canvas")[0].namespace = { module : { dobehavior : function(paramString) { ... } } };
And then if you had the canvas element somewhere (possibly also through var canvas = document.getElementsByTagName("canvas")[0];) you could do
canvas.namespace.module.dobehavior("someString");
Is that what you mean?
In JQuery
$(function() {
$("canvas[ns.mod.colorBehavior]") {
var color = $(this).attr("ns.mod.colorBehavior");
if (color == "red") {
var context = this.getContext('2d');
context.fillStyle = "#ff0000";
context.fillRect(0,0,width,height);
}
}
}
Where width and heigh are the width and height of your canvas element (or a higher value like 10000).

Categories

Resources