Mobile - approx 350-500px
I've built a mask that has a circle cut out of it, it grows, shrinks and has a label. But I am having issues trying to get it to scale correctly.
I have tried rescaling features with the viewbox - but it doesn't work and resizing causes an opacity mask bug which I've not been able to fix.
Using ViewBox to resize svg depending on the window size
//latest js fiddle http://jsfiddle.net/NYEaX/1563/
$(document).ready(function() {
function maskMaker(el) {
var backcolor = $(el).data("color");
var backopacity = $(el).data("opacity");
var height = $(el).data("height");
var width = $(el).data("width");
var width = 1120;
var height = 500;
var labelName = $(el).data("label-name");
var bubbleValue = $(el).data("bubble-value");
var displaceLeft = $(el).data("displace-left");
var displaceTop = $(el).data("displace-top");
var data = [{
"label": labelName,
"x": displaceLeft,
"y": displaceTop,
"value": bubbleValue
}];
console.log("MASK data", data);
// Set the main elements for the series chart
var svgroot = d3.select($(el)[0])
.append("svg")
.attr("viewBox", "0 0 " + width + " " + height)
/*
.attr("width", "100%")
.attr("height", "100%")*/
.attr("width", width)
.attr("height", height)
.attr("preserveAspectRatio", "xMidYMid meet");
// filters go in defs element
var defs = svgroot.append("defs");
var mask = defs.append("mask")
.attr("id", "myMask");
mask.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", "100%")
.attr("height", "100%")
.style("fill", "white")
.style("opacity", backopacity);
var invisiblebubble = mask.append("circle")
.data(data);
//create a fixed bubble first
invisiblebubble
.attr("cx", "50%")
.attr("cy", "50%")
.attr("r", function(d) {
return d.value - 20;
});
//now mask the fixed circle
var masker = defs.append(function() {
return mask.node().cloneNode(true)
})
.attr("id", "myMaskForPointer")
.select("rect")
.style("opacity", 0.8);
invisiblebubble
.attr("r", 10);
//animate this circle
invisiblebubble
.attr("cx", "50%")
.attr("cy", "50%")
.transition()
.duration(1800)
.attr("r", 10)
.transition()
.duration(900)
.attr("r", function(d) {
return d.value;
});
//apply the rest of the chart elements
var svg = svgroot
.attr("class", "series")
.append("g")
.attr("transform", "translate(0,0)")
var rect = svg
.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", "100%")
.attr("height", "100%")
.attr("mask", "url(#myMask)")
.style("fill", backcolor);
/*
//__labels
var centrallabel = svgroot.append("g")
.attr("class", "centrallabel")
.data(data);
centrallabel
.append("text")
.attr("text-anchor", "middle")
.attr("x", 550)
.attr("y", 250 + 10)
.text(function(d) {
return "200";
})
*/
function addLabel() {
//__labels
var labels = svgroot.append("g")
.attr("class", "labels")
//__ enter
var labels = labels.selectAll("text")
.data(data);
labels.enter()
.append("text")
.attr("text-anchor", "middle")
//__ update
//labels
.attr("x", function(d) {
return d.x;
})
.attr("y", function(d) {
return d.y - 10;
})
.text(function(d) {
return d.label;
})
.each(function(d) {
var bbox = this.getBBox();
d.sx = d.x - bbox.width / 2 - 2;
d.ox = d.x + bbox.width / 2 + 2;
d.sy = d.oy = d.y + 5;
d.cx = 550;
d.cy = 250;
})
.transition()
.duration(300)
labels
.transition()
.duration(300)
//__ exit
labels.exit().remove();
//__labels
}
function addPointer() {
//__pointers
var pointers = svgroot.append("g")
.attr("class", "pointers");
var dots = defs.append("marker")
.attr("id", "circ")
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("refX", 3)
.attr("refY", 3);
var pointers = pointers.selectAll("path.pointer")
.data(data);
//__ enter
pointers.enter()
.append("path")
.attr("class", "pointer")
.style("fill", "none")
.attr("marker-end", "url(#circ)")
.attr("mask", "url(#myMaskForPointer)")
//__ update
//pointers
.attr("d", function(d) {
if (d.cx > d.ox) {
return "M" + d.sx + "," + d.sy + "L" + d.ox + "," + d.oy + " " + d.cx + "," + d.cy;
} else {
return "M" + d.ox + "," + d.oy + "L" + d.sx + "," + d.sy + " " + d.cx + "," + d.cy;
}
})
.transition()
.duration(300)
pointers
.transition()
.duration(300)
//__ exit
pointers.exit().remove();
//__pointers
}
//delay for the mask
setTimeout(function() {
addLabel();
addPointer();
}, 1000);
}
function resizeHandling(el){
function maskResizer(width, height) {
$(el).find('.series').attr("width", width);
$(el).find('.series').attr("height", height);
$(el).find('.series').attr("viewBox", "0 0 " + width + " " + height);
}
$(window).resize(function() {
var paneWidth = $(el).width();
var paneHeight = $(el).height();
console.log("paneHeight", paneHeight);
console.log("paneWidth", paneWidth);
maskResizer(paneWidth, paneHeight);
});
}
//var el = $(".mask"); //selector
$('[data-role="maskmaker"]').each(function(index) {
console.log("test")
maskMaker(this);
resizeHandling(this);
});
});