ZF - svg web
by PhilQ
HTML
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<script type="text/x-template" id="graph-web-template">
<svg :width="w" :height="h" xmlns="http://www.w3.org/2000/svg">
<defs xmlns="http://www.w3.org/2000/svg">
<filter id="insetglow" x="-50%" y="-50%" width="200%" height="200%">
<feComponentTransfer in=SourceAlpha>
<feFuncA type="table" tableValues="0.1 0" />
</feComponentTransfer>
<feGaussianBlur stdDeviation="0"/>
<feOffset dx="1" dy="1" result="offsetblur"/>
<feFlood flood-color="rgb(255, 255, 255)" result="color"/>
<feComposite in2="offsetblur" operator="in"/>
<feComposite in2="SourceAlpha" operator="in" />
<feMerge>
<feMergeNode in="SourceGraphic" />
<feMergeNode />
</feMerge>
</filter>
<filter id="insetshadow" x="-50%" y="-50%" width="200%" height="200%">
<feComponentTransfer in=SourceAlpha>
<feFuncA type="table" tableValues="0.3 0" />
</feComponentTransfer>
<feGaussianBlur stdDeviation="0"/>
<feOffset dx="-1" dy="-1" result="offsetblur"/>
<feFlood flood-color="rgb(0, 0, 0)" result="color"/>
<feComposite in2="offsetblur" operator="in"/>
<feComposite in2="SourceAlpha" operator="in" />
<feMerge>
<feMergeNode in="SourceGraphic" />
<feMergeNode />
</feMerge>
</filter>
<filter id="dropshadow" 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"...
SCSS
*, *:before, *:after { box-sizing: border-box; margin: 0; padding: 0; }
.graph-web-parent {
.graph-web-poly {
.on {
display: none;
}
&:hover .on {
display: inline;
}
}
&.over {
path:not(.y) {
stroke-opacity: 0.2;
//fill-opacity: 0.2;
}
.graph-web-poly:hover {
path {
stroke-opacity: 1;
stroke-width: 4;
//fill: #ffffff;
//fill-opacity: 0.8;
}
circle {
stroke: #ffffff;
stroke-width: 2;
&:hover {
r: 10;
}
}
* {
filter: url(#dropshadow);
}
}
}
}
JavaScript
function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;
return {
x: centerX + (radius * Math.cos(angleInRadians)),
y: centerY + (radius * Math.sin(angleInRadians))
};
}
// The raw data to observe
var chartdata = {
w: 12,
h: 8,
blocksize: 0,
margin: 30,
stroke: 2, //width
fill: 0, //opacity
stacked: false,
percentage: false,
axes: [
'A', 'B', 'C', 'D', 'E'
],
values: [
{ label: 'Groep 1', color: '#cc0000', values: [
7,
2,
1,
2,
1,
] },
{ label: 'Groep 2', color: '#00cc00', values: [
2,
1,
2,
1,
2,
] },
{ label: 'Groep 3', color: '#0000cc', values: [
3,
7,
15,
9,
3,
] },
],
};
// A resusable polygon graph component
Vue.component('graph-web', {
props: ['chartdata','blocksize'],
template: '#graph-web-template',
methods: {
polar_to_cartesian: function (centerX, centerY, radius, angleInDegrees) {
var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;
return {
x: centerX + (radius * Math.cos(angleInRadians)),
y: centerY + (radius * Math.sin(angleInRadians))
};
},
in_front: function (event) {
$( event.target.parentNode ).addClass('over');
event.target.parentNode.appendChild( event.target );
},
off_front: function (event) {
$( event.target.parentNode ).removeClass('over');
},
get_path: function (points, translation_x, translation_y) {
return 'M ' + (points.map(function (point, i) {
return Math.round(point.x + translation_x) + ',' + Math.round(point.y + translation_y)
...