ZF - svg line

by PhilQ

HTML

<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<script type="text/x-template" id="graph-line-template">
	<svg :width="w" :height="h" xmlns="http://www.w3.org/2000/svg">
		<defs>
			<filter id="dropshadow" x="-50%" y="-50%" width="200%" height="200%">
			  <feGaussianBlur in="SourceAlpha" stdDeviation="3"/> 
			  <feOffset dx="0" dy="2" result="offsetblur"/>
			  <feComponentTransfer>
				<feFuncA type="linear" slope="0.3"/>
			  </feComponentTransfer>
			  <feMerge> 
				<feMergeNode/>
				<feMergeNode in="SourceGraphic"/> 
			  </feMerge>
			</filter>

			<filter id="textglow" x="-50%" y="-50%" width="200%" height="200%">
				<feOffset result="offOut" in="SourceGraphic" dx="0" dy="0" />
				<feFlood result="maskColor" flood-color="#ffffff" flood-opacity="1" />
				<feComposite result="maskOut" operator="in" in="maskColor" in2="offOut"/>
				
				<feMorphology result="morphOut" in="maskOut" operator="dilate" radius="1" />

				<feGaussianBlur result="blurOut" in="morphOut" stdDeviation="1" />

				<feBlend result="blendOut" in="morphOut" in2="blurOut" mode="screen" />

				<feComponentTransfer result="blendOpacityOut" in="blendOut">
					<feFuncA type="linear" slope="1"/>
				</feComponentTransfer>

				<feBlend result="almostthereOut" in="SourceGraphic" in2="blendOpacityOut" mode="normal" />

				<feBlend in="SourceGraphic" in2="almostthereOut" mode="multiply" />
			</filter>
		</defs>
		<g class="graph-line" :font-size="font_base + 'px'">

			<g v-if="is_large_enough">

				<!-- Y-axes scale -->
				<line
					v-for="(l, lI) in y_lines"
					:x1="chartdata.rotate ? graph_x + Math.round((l/max)*graph_w) : graph_x - 5"
					:x2="chartdata.rotate ? graph_x + Math.round((l/max)*graph_w) : graph_x + graph_w"
					:y1="chartdata.rotate ? chartdata.margin.around : h - graph_y - Math.round((l/max)*graph_h)"
					:y2="chartdata.rotate ? h - graph_y + 5 : h - graph_y - Math.round((l/max)*graph_h)"
					stroke-width="1" stroke="#dfdfdf"
					/>
				<text...

SCSS

svg {
	//background: rgba(255,0,0, 0.5);
}

.graph-line {
	.graph-line-group.over, use {
		display: none;
	}
	.graph-line-group, use.over {
		display: inline;
	}
	
	circle.off {
		display: inline;
	}
	circle.on {
		display: none;
		r: 8;
	}

	.graph-line-group:hover {
		circle.off {
			display: none;
		}
		circle.on {
			display: inline;
		}
	}
}

JavaScript

// The raw data to observe
var chartdata = {
    w: 8,
    h: 4,
	blocksize: 0,
	rotate: false,
	margin: {
		around: 15,
		outer: 20,
    },
	markers: true,
	area: false,
	curved: true,
	connected: true,
	percentage: false,
	axes: {
		x: {
			label: 'Per maand',
			subs: ['Jan','Feb','Mrt'],
			label_size: 25,
			scale_size: 20,
		},
		y: {
			label: 'Patiënten',
			min_value: '0',
			max_value: '100',
			calculate_max: true,
			label_size: 25,
			scale_size: 20,
		},
	},
	values: [
		{
			label: 'Hartpoli',
			color: '#ff0000',
			values: [10,5,8],
		},
		{
			label: 'Longpoli',
			color: '#0000ff',
			values: [4,11,3],
		},
	],
};


// A resusable polygon graph component
Vue.component('graph-line', {
    props: ['chartdata','size'],
    template: '#graph-line-template',
    methods: {
        in_front: function (id, event) {
        	$('.graph-line-group-hover' + id + ', #graph-line-group' + id).addClass('over');
            //$( event.target.parentNode ).addClass('over');
            //event.target.parentNode.appendChild( event.target );
        },
        off_front: function (id, event) {
        	$('.graph-line-group-hover' + id + ', #graph-line-group' + id).removeClass('over');
            //$( event.target.parentNode ).removeClass('over');
        },
    },
    computed: {
		w: function () {
			return Math.max(0, Math.round(this.size * this.chartdata.w));
		},
    	h: function () {
			return Math.max(0, Math.round(this.size * this.chartdata.h));
		},

		font_base: function () {
			return Math.round(this.size*0.05);
		},

		graph_w: function () {
			var w = this.w - (2*this.chartdata.margin.around);
			w -= ((this.chartdata.rotate) ? (this.chartdata.axes.x.label_size + this.chartdata.axes.x.scale_size) : (this.chartdata.axes.y.label_size + this.chartdata.axes.y.scale_size));
			return Math.max(0, w);
		},
		graph_h: function () {
			var h = this.h - (2*this.chartdata.margin.around);
			h -= ((this.chartdata.rotate) ? (this.chartdata.axes.y.label_size +...