function limitBounds(b, maxWidth, maxHeight) { var w = b[1][0] - b[0][0]; if (w > maxWidth) { var c = (b[1][0] + b[0][0]) / 2; maxWidth /= 2; b[0][0] = c - maxWidth; b[1][0] = c + maxWidth; } var h = b[1][1] - b[0][1]; if (h > maxHeight) { var ch = (b[1][1] + b[0][1]) / 2; maxHeight /= 2; b[0][1] = ch - maxHeight; b[1][1] = ch + maxHeight; } } function groupBounds(path, features, width, height, maxWidth, maxHeight) { var r = features.length ? [[[], []], [[], []]] : [[[0], [0]], [[width], [height]]]; features.forEach(function (feature) { var b = path.bounds(feature); limitBounds(b, maxWidth, maxHeight); r[0][0].push(b[0][0]); r[0][1].push(b[0][1]); r[1][0].push(b[1][0]); r[1][1].push(b[1][1]); }); r[0][0] = Math.min.apply(this, r[0][0]); r[0][1] = Math.min.apply(this, r[0][1]); r[1][0] = Math.max.apply(this, r[1][0]); r[1][1] = Math.max.apply(this, r[1][1]); return r; } function normalize(v, minMax) { return minMax.diff ? (v - minMax.min) / minMax.diff : 0.5; } function getValuesMinMax(values) { var v = []; var s = 0; for (var k in values) { v.push(values[k]); s += values[k]; } var r = { min: Math.min.apply(this, v), max: Math.max.apply(this, v) }; r.diff = r.max - r.min; r.sum = s; return r; } function getScale(size, width, height, scaleMargin, maxScale) { var marginSize = [(size[0] + width * scaleMargin), (size[1] + width * scaleMargin)]; var sizeRatio = marginSize[0] / marginSize[1]; var boxRatio = width / height; var r; if (sizeRatio >= boxRatio) { r = width / marginSize[0]; } else { r = height / marginSize[1]; } if (r < 1) { r = 1; } else if (r > maxScale) { r = maxScale; } return r; } function setContextSyle(ctx, opt) { ctx.fillStyle = opt.fillStyle; ctx.strokeStyle = opt.strokeStyle; ctx.shadowColor= opt.shadowColor; ctx.shadowOffsetY = opt.shadowOffsetY; ctx.shadowBlur = opt.shadowBlur; }