I am making a clock using Raphael with my own. I created a big circle which is for clock, and i need to create the other three bullets for 12,3,6,9 hrs. now how can i create the circle, which is child of the big one. (how can i append the small circles to big one)?
i wrote this function to made that, but no use. it makes the small circles as absolute. how can i create the small circles as relative to parent?
my function :
window.onload = function(){
var paper = new Raphael ('clock',500,500);
var circle = paper.circle(250,250,200);
circle.node.id="clock";
circle.attr({
stroke:"#f00"
})
var num = new Raphael(document.getElementById('clock'),400,400);
var graydot = num.circle(10,100,5);
graydot.attr({fill:"#000"});
}
any one can help me? or let me know about parent child relation ship of svg... pls!
I don't think that Raphael caters for hierarchies of objects in the manner you speak of. The best you can do is group objects together into sets if you want to treat the objects as one.
As for creating the other three nodes, you can clone your first dot and rotate 90 degrees around the centre of your clock. Do that three times and you'll have your clockface.
Here's a fiddle that illustrates the idea.
First of all, you don't have to declare multiple different Raphael instances. Just use one on top of which you build your clock.
Moreover, there is no "parent child relation ship of svg" your two shapes are siblings( only if you insert them into the same Raphael instance).
The only thing that they have in common is that they are attached to the same svg - take a look at the resulting sgv :
<svg height="500" version="1.1" width="500" xmlns="http://www.w3.org/2000/svg" style="overflow-x: hidden; overflow-y: hidden; position: relative; ">
<desc>Created with Raphaël 2.0.0</desc>
<defs></defs>
<circle cx="250" cy="250" r="200" fill="none" stroke="#ff0000" id="clock" style=""></circle>
<circle cx="10" cy="100" r="5" fill="#000000" stroke="#000" style=""></circle>
</svg>
What I'm trying to say is that it's normal for the circle to be positioned "absolute".
If you want to position the 4 circles relative to the big one, you should calculate their centers manually :
var paper = new Raphael('clock', 500, 500);
var circle = paper.circle(250, 250, 200);
var graydot = paper.circle(circle.attrs.cx - circle.attrs.r + 10, circle.attrs.cy, 10 );
Here's a live example : http://jsfiddle.net/gion_13/4p7Np/
Related
https://developers.google.com/chart/interactive/docs/gallery/ganttchart
Is it possible to add labels on the Gantt chart durations, like the below screenshot?
As WhiteHat said, there is no built-in option.
For my specific case (I always have the same structure in my Gantt graph) I did the following (to place some DIVs on top of the bars - with these DIVs you can do whatever you want):
// callback after draw (afterDraw() function is called after chart is drawn)
google.visualization.events.addListener(chart, 'ready', afterDraw);
function afterDraw(){
// the container element to append our generated DIVs (with the labels)
// it has to be outside the SVG element, but inside the chart container
var toContainer = $('#chart_div > div > div');
// in order to create DIVs to place them on top of the bars, we first need to get bars SVG/RECTs positions and sizes
// in my case, the RECT elements with the necessary top/left/width/height are in the 6th G element
$( "#chart_div g:eq(5) rect" ).each(function() {
toContainer.append("<div style='top:"+$(this).attr('y')+"px; left: "+$(this).attr('x')+"px; width: "+$(this).attr('width')+"px; height: "+$(this).attr('height')+"px;text-align: center;position:absolute;line-height:2' >Some text</div>");
});
}
Famo.us Surfaces have a single way to set the size of a surface. They have a "size" property that takes an array of 2 numbers which correspond directly to pixel values. This is not overly useful when dealing with mobile devices given the large number of different screen sizes. This will require the user to do math on the size of the parent container rather than Famo.us doing the math behind the scenes.
If one of the values is not given, it will use 100% available of that dimension, but there is no way that I can see to specify 50% or 33%.
var firstSurface = new Surface({
size: [100, 400],
content: 'hello world',
properties: {
color: 'white',
textAlign: 'center',
backgroundColor: '#FA5C4F',
width: "200px"
}
});
The "width" property doesn't do anything whether or not the 0th array element is removed, even though it's claimed that you can use CSS properties in camelCase. I assumed this would be the proper way to use %'s, but it is not.
No, this is not possible. You need to calculate, but this is not hard:
var sizeModifier = new Modifier();
sizeModifier.sizeFrom(function(){
var size = mainContext.getSize();
return [0.5 * size[0],0.5 * size[1]];
});
The engine emits a resize event from the main context where you can hook up your modifier.
Using the sizeFrom function, you can dynamically set the size.
You need to use a Modifier because setting the size on a Surface does not affect the DOM, only the size used for internal calculations. (This can be used for spacing, see the layout guide)
Assuming you want a percentage of the viewport, I used the mainContext, which is [100%,100%]. Of course, you can call getSize on any parent surface.
As of famo.us v0.3, proportional sizing has been added. You can now use this kind of notation:
new Modifier({
size: [undefined, undefined],
proportions: [0.5, 1/3] // width 50%, height 33%
});
You can also use for instance SizeConstraint to do size-scaling:
var sizeCS = new SizeConstraint({
scale: [0.5, 1.3]
});
sizeCS.add(new Surface({..}));
https://github.com/IjzerenHein/famous-sizeconstraint
I used famo.us to make Breezi, Thinglist, and Lumosity capptivate.co examples (neaumusic.github.io)
Surface:
size:[undefined, undefined],
// this is default; size key can be ommited; fills Modifier size
Modifier:
size: [window.innerWidth * 0.5, window.innerHeight * 0.5],
Later, you can use .setTransform() on your Modifier with Transform.scale() or Transform.rotateY() and since your Surface is directly overlapping the Modifier, nothing funky will happen. This is not to say you can't have a 1 pixel by 1 pixel Modifier to position a Surface from the Surface's top left corner, and this leads me to another topic of confusion with positioning...
Positioning With Origin
If you have an origin [0.3, 0.3], the location 30% of the way across the inner box will align to 30% of the way across the outer box.
In other words, using CSS aligning the left edge of inner to left edge of outer:
position: absolute,
left: 30%
Is not equivalent to origin: [0.3, Y] because your inner object will be too far left by 30% of it's width
But is equivalent to shifting:
origin: [0, Y],
transform: Transform.translate(window.innerWidth * 0.3, 0, 0)
I was recommended to use only 9 positions for the origin
The corners, the middle of the edges, and the center (0.5, 0.5) of a box
Famo.us does manage the size of the surface, but you have the ability to set min and max widths and heights on your surfaces to be responsive.
var firstSurface = new Surface({
size: [100, 400],
content: 'hello world',
properties: {
color: 'red',
textAlign: 'center',
backgroundColor: '#FA5C4F',
minWidth: '90%',
maxHeight: '60%'
}
});
I'm trying to draw machinery from the bird's eye perspective.
Therefore, I draw rectangles. Theese rectangles may have angles (e.g. 90°, 270°). So i apply rotation transformation onto them. This way i can draw the whole plant.
Now if I apply scaling transformation onto the set, the elements are scaling. But the rotation transformations I previously applied, is running backwards.
Copy this to raphael's playground to see what i mean.
var rect1 = paper.rect(50,50,200,100).attr({fill: "green"});
var rect2 = paper.rect(250,50,200,100).attr({fill: "green"});
var rect3 = paper.rect(550,50,200,100).attr({fill: "green"});
rect3.transform("r90,550,50");
var set = paper.set();
set.push(rect1,rect2,rect3);
set.animate({'transform':"S0.5,0.5,50,50"}, 2000);
What I want now, is to prevent reversing the rotation and that the third elements alignment to second one stays as it is after rotation (some kind of "L").
Thanks in advance!
Allright, got it myself. Using "..." solved my problem.
var rect1 = paper.rect(50,50,200,100).attr({fill: "green"});
var rect2 = paper.rect(250,50,200,100).attr({fill: "green"});
var rect3 = paper.rect(550,50,200,100).attr({fill: "green"});
rect3.transform("r90,550,50...");
var set = paper.set();
set.push(rect1,rect2,rect3);
set.animate({'transform':"...S0.5,0.5,50,50"}, 2000);
Tried it this way yesterday, but somehow it didnt work. Today, its working just fine =)
I have a line chart that I've created with gRaphael. It has axes and tick marks, but I'd like to have grid lines. Is there built-in way to achieve this or an add on library that can help me?
gRaphael does not have a built-in way to add grid lines, but it is pretty easy to draw them, either by editing the source code or manipulating your graph object after you create it.
I had found an extension called RaphAlytics and used its drawGrid() function in cases where I needed a bounding box with a grid.
You can adapt this function for any gRaphael graph as needed to draw gridlines. On a line chart, I needed to draw horizontal gridlines that were aligned with the left axis marks on a line chart, so I used the function as an example like this:
// Draw horizontal gridlines
for (var i = 0; i < g.axis[1].text.items.length; i++) {
r.path(['M', x, g.axis[1].text.items[i].attrs.y, 'H', w + x]).attr({
stroke : '#EEE'
}).toBack();
}
Here's a working fiddle to illustrate that example: http://jsfiddle.net/KM3BB/1/
I tried doing this yesterday. Short answer: gRaphaël can't do this for you with any linechart options nor axis options, you have to do-it-yourself with Raphaël.
Something like:
var r = Raphael("holder"), txtattr = { font: "12px sans-serif" };
r.path('M 15 200.5 L 310 200.5 M 15 180.5 L 310 200.5');
r.linechart(10, 10, 300, 220, x, [y, y2, y3]);
This means under my linechart draw a path which starts from 15,200.5 and draws a straight line to 310,200.5 moves to 15,180.5 and draws a line to 310,180.5. Don't ask me why but the .5 is important for getting the stroke to actually be 1px wide and solid black. Otherwise it seems to get aliased to 2px wide at 50% opacity. You have to calculate the exact placement in regards to your linechart yourself.
You can also play with the path function in the playground by changing r to paper.
You might also consider looking at Google Chart Tools if your looking for things like defining the exact range of the axis (as opposed to just the min and max of the input).
I am using the setViewBox() function in Raphael 2. The width and height is multiplied by a value like (1.2, 1.3 ...). This changes the magnification/ zooming properly but the x and y which I have given as 0,0 makes the paper display its contents after some offset. If i modify the x and y to some positive value after the rendering( using firebug!!) then the top left of the paper moves back and above to its right position. I want to know how will the value be calculated. I have no idea about how the x,y affect the viewbox. If anybody can give me any pointers for this it will be a real help.
I have tried giving the difference between the width/ height divided by 2. Also I must mention that I am not rendering an image but various raphael shapes e.g. rects, paths text etc. in my paper.
Looking forward to some help!
Kavita
this is an example showing how to calculate the setViewBox values, I included jquery (to get my SVG cocntainer X and Y : $("#"+map_name).offset().left and $("#"+map_name).offset().top) and after that I calculated how much zoom I need :
var original_width = 777;
var original_height = 667;
var zoom_width = map_width*100/original_width/100;
var zoom_height = map_height*100/original_height/100;
if(zoom_width<=zoom_height)
zoom = zoom_width;
else
zoom = zoom_height;
rsr.setViewBox($("#"+map_name).offset().left, $("#"+map_name).offset().top, (map_width/zoom), (map_height/zoom));
did you put the center of your scaling to 0,0 like:
element.scale(1.2,1.2,0,0);
this can scale your element without moving the coordinates of the top left corner.