Partial border/stroke using SVG - javascript

I'm using svg/d3 for creating a chart made of 'rect' elements.
What is the best way for adding a partical border/stroke for each rectangle (only on top of the rectangle)?
Thanks

I don't think SVG supports stroking only portions of a rectangle or path - stroke isn't like a CSS border. You're left with a few other options, all of which take some extra work:
Stroke the entire rect and apply a clipPath to remove the other three edges - probably works best if you make the rectangles bigger than necessary.
Apply a linear gradient fill to each rect, using the gradient definition to show a "border" at the top of the shape.
Add a separate line element to act as the border for each rect.
Use the stroke-dasharray property (docs) to set a dash definition where the "dash" only covers the top of the rect. This might be tricky to get right, but I suspect it wouldn't be too hard, as the stroke probably begins at the top left of the shape.

Related

HTML Canvas - glowing outline on stroke path?

I noticed a weird outline on my canvas lines. Below is an example:
http://jsfiddle.net/0Lzd562x/6/
The blue stroked rectangle is drawn after the red one but it looks like they mix together or there is a glow on the lines. I've tried setting the lineWidth to a larger value and it fixes the issue, but I want slim lines. Also tried using ctx.lineTo() to draw the rectangles but with same results. I want the latter (blue) rectangle to be on top overriding the right side of the red one.
What's happening is that you're drawing lines along the splits between pixels, not in the middle of the pixels themselves. This causes the line to be rendered at half opacity on each of the pixels. Because of the opacity, the colors from both squares are being added to 2 pixels, resulting in a thick 2px purple line.
The reason for the splitting of the line is antialiasing. You can find a fantastic talk about it by Steve Wittens
You can't turn antialiasing off, but you can draw the lines in the middle of the pixels by adding .5 to the starting x/ys of the rectangles, as long as the sizes are integers
Here's the resulting fiddle: http://jsfiddle.net/0Lzd562x/11/

Per-cell border colors in a highcharts heat map

I'm using highcharts to create a simple heatmap, but now I want to use custom border colors on the cells to represent another dimension in my data set. I am able to accomplish this with the borderColor config option on the data points, but the border of each cell gets drawn partly on top of the border of the preceding cells, so it looks sort of goofy.
Is there a way to specify a margin for the border so that my border gets drawn completely inside the boundary of the cell, so that there is no overlapping of borders? Or is there a way to custom-draw my own border through some event?
You can see this effect in the fiddle at http://jsfiddle.net/8ft7e923/1/ and in the image below. Note how the orange border is drawn over the green and the red is drawn over the orange. This overlapping is what I am trying to eliminate.
It is possible to add pixel padding for a heatmap series and set borderWidth to double of set padding.
Example: http://jsfiddle.net/jk9hp3y9/2/
Example based on your demo: http://jsfiddle.net/8ft7e923/2/
As Halvor mentioned - it is not yet possible to set border for SVG elements to be placed inside of element.
Another way could be to extend Highcharts (similar as in provided demos) to change size of cells with border set to make them fit in same place as the ones without border. More about extending Highcharts in Docs.

Javascript : gauge image effect

I'm making a 2d game using melonJS.
In my game, i have an arrow which rotate on its axis. This arrow is a png image. When i keep the left mouse button, the arrow needs to fill from yellow to red, from the base to the top. Here's an exemple :
The initial arrow is all light red, like the top of the example image. when i keep the button clicked, the arrow color should change from the bottom with a white line as a current position to the top.
How can i do this with javascript ? Is there any things embbeded in melonJS to handle this kind of trick ?
Since your question is text based rather than code based, I'll do the same.
Here is how to draw your rotated changing-gradient arrow
Clear the canvas with context.clearRect.
Rotation: Translate to your desired center-axis coordinate around which you want to rotate. Then Rotate to your desired angle. Transformations (context.translate & context.rotate) will actually rotate the canvas itself. That way all new drawings will be translated (moved) and rotated. Note: Existing pixels will be unaffected.
Drawing the arrow: Draw your arrow with path commands (beginPath, moveTo, lineTo, ... for each piece of the arrow). Since you have already done your transformations (translate & rotate), you don't need to try to rotate your arrow drawings.
Gradient fill for arrow: Create a linear gradient (context.createLinearGradient) that extends through your arrow drawings. Set color stops (context.addColorstop) to create your desired yellow & red gradient along your arrow. Use the gradient as your context.fillStyle and fill your arrow path with context.fill.
Using gradients for the white indicator line You can also use gradients to display your white indicator bar. To do this, draw your arrow and then overdraw with another gradient that is transparent at all places except your desired indicator percentage where it will be white.
var g=ctx.createLinearGradient(0,170,0,0);
g.addColorStop(pct-0.01,'transparent');
g.addColorStop(pct-0.01,'white');
g.addColorStop(pct+0.01,'white');
g.addColorStop(pct+0.01,'transparent');
ctx.fillStyle=g;
ctx.fill();
Always clean up! Undo your transformations. You can undo transformation by either (1) reissuing your transformation commands in reverse order and with negative arguments or (2) resetting every transformation to defaults by resetting the transformation matrix with context.setTransform(1,0,0,1,0,0).
Put your code into a requestAnimationFrame animation loop and change the angle and/or the gradient to meet your design needs.
You can layer two PNG files, one with the arrow, one with the stripe, and control the position of the white stripe that sits on top of the arrow. Canvas should enable that pretty easily by default, and even more so if you're using a library.

Write curved text within a circle with PaperJS

The title basically outlines all the details of my problem. I'm trying to write text within a circle that curves with the outline of the circle. Something very similar to the image bellow.
You can actually do this with a little hack.
Here is how to proceed:
Get the offset to the x-center of each glyph in the text. This can be done by using the with of a PointText for the substring until the glyph.
Find the point for the offset on the path that you want your text to align to.
Place the single centered glyph at the just found point. Rotate the glyph by the path's tangent angle.
Here is the Paper Sketch: Align Text to Path Sketch
And here is the result of a simple test:
You can use the code with an arbitrary path, not only with circles.

Put Raphael (SVG) canvas behind other divisions to make them clickable?

I am using Raphael to create lines between divisions in an organization chart (or flow chart), but I need to be able to actually click on the divisions and content behind it.
If I could make the canvas be behind the other elements, kind of like a background image, that would be idea. Is this possible?
I found a solution. Raphael makes an SVG canvas that is absolutely positioned in my case. Absolute positions act as layers, and so to be on top of that layer, my content had to be absolutely positioned as well.
If someone else has a better solution, I would be happy to hear it, though this is working fine.
What I do is create a layer of invisible (but clickable) shapes on top of the informational lines being rendered, which will act as the target area for the content below.
If your lower layers being target are being created in Raphael you can easily clone them, set the opacity to 0, and position that layer to the top. (See Sets Reference for a way to easily group the layers together.)
Example:
#el = #parent.paper.rect(x,y,w,h); //your existing lower layer shape definition
#elTrigger = #el.clone(); //clone your existing shape
#elTrigger.attr
fill: '#fff'
opacity: 0
cursor: 'pointer'
#elTrigger.click(someAction); //assign the function
If you're lower layer isn't being rendered by Raphael (just HTML) you could still do something similar, but it would require just creating new (transparent) shapes to sit on top of the approximate coordinate of the targets below.

Categories