04. Marker SVG element

When you are showing data with a line chart, it is very useful for your readers to have markers to highlight every data.
But it can be useful to add arrows on your axis lines too!

We need first to define the marker path in a marker element. The marker element behaves very similarly to the symbol element.

After defining the shape of your marker, you can apply it to using the three attributes marker-start="url(#dot)" marker-mid="url(#dot)" marker-end="url(#dot)".The markers attributes can be applied to a path, a line, a polyline or a polygon.

Line chart

Quick tip: Notice that the viewbox is not starting from the coordinates [0,0]. The polyline is starting from [0,100] to make it easy to calculate its values from a zero origin.

<svg viewBox="-20 -20 140 140" class="line-graph">
	<marker id="arrow" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="6" markerHeight="6" orient="auto">
		<path d="M 0 0 L 10 5 L 0 10 z" />
	</marker>

	<marker id="dot" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="5" markerHeight="5">
		<circle cx="5" cy="5" r="5" stroke="none" fill="red" />
	</marker>

	<line stroke="black" x1="0" y1="100" x2="100" y2="100" marker-end="url(#arrow)" />
	<line stroke="black" x1="0" y1="100" x2="0" y2="0" marker-end="url(#arrow)" />

	<polyline points="0,100 16.6,70 33.2,85 49.8,50 66.4,60 83,20 100,15" fill="none" stroke="grey" marker-start="url(#dot)" marker-mid="url(#dot)" marker-end="url(#dot)" />
</svg>

Animate line chart using SMIL

Even if SMIL is being less and less used thanks to better support of SVG properties through CSS, there are still some animations we cannot achieve without JavaScript.

To animate a polyline with markers we cannot use the stroke-dashoffset trick that we showed last month because only the stroke will move, but the markers will not move and stay at the positions.

The same way we define keyframes in CSS, we can do it in SMIL with the values attributes. In that attribute we can define every step for the property we are animating. When you animate a property with a single keyframe (fade opacity from 0 to 1 for example) you can use the from/to attributes.

<svg viewBox="-20 -20 140 140" class="line-graph">
	<marker id="arrow" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="6" markerHeight="6" orient="auto">
		<path d="M 0 0 L 10 5 L 0 10 z" />
	</marker>
	<marker id="dot" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="5" markerHeight="5">
		<circle cx="5" cy="5" r="5" stroke="none" fill="red" />
	</marker>

	<line stroke="black" x1="0" y1="100" x2="100" y2="100" marker-end="url(#arrow)">
		<animate attributeName="x2" fill="freeze" dur="1.5s" from="0" to="100" keySplines=".42,.32,.1,1" calcMode="spline" />
	</line>
	<line stroke="black" x1="0" y1="100" x2="0" y2="0" marker-end="url(#arrow)">
		<animate attributeName="y2" fill="freeze" dur="1.5s" from="100" to="0" keySplines=".42,.32,.1,1" calcMode="spline" />
	</line>

	<polyline fill="none" stroke="grey" marker-start="url(#dot)" marker-mid="url(#dot)" marker-end="url(#dot)">
		<animate attributeName="points"
             fill="freeze"
             dur="4s"
             begin="0.5s"
             values="
                    0,100 0,100 0,100 0,100 0,100 0,100 0,100;
                    0,100 16.6,70 16.6,70 16.6,70 16.6,70 16.6,70 16.6,70;
                    0,100 16.6,70 33.2,85 33.2,85 33.2,85 33.2,85 33.2,85;
                    0,100 16.6,70 33.2,85 49.8,50 49.8,50 49.8,50 49.8,50;
                    0,100 16.6,70 33.2,85 49.8,50 66.4,60 66.4,60 66.4,60;
                    0,100 16.6,70 33.2,85 49.8,50 66.4,60 83,20 83,20;
                    0,100 16.6,70 33.2,85 49.8,50 66.4,60 83,20 100,15"
             />
	</polyline>

Click to restart the animation