Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

chartogram

Package Overview
Dependencies
Maintainers
1
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

chartogram - npm Package Compare versions

Comparing version 0.1.8 to 0.1.9

2

bundle/chartogram.js

@@ -1,2 +0,2 @@

!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).chartogram=e()}(this,function(){"use strict";function t(t){return function(t){if(Array.isArray(t)){for(var e=0,n=new Array(t.length);e<t.length;e++)n[e]=t[e];return n}}(t)||function(t){if(Symbol.iterator in Object(t)||"[object Arguments]"===Object.prototype.toString.call(t))return Array.from(t)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}function e(t){for(;t.firstChild;)t.removeChild(t.firstChild)}function n(t,e,n,i,a){for(var o=0;o<i;){var r=document.createElement("div"),s=e+o*(n-e)/(i-1);a&&(s=a(s)),r.appendChild(document.createTextNode(s)),t.appendChild(r),o++}}function i(t,e){var n,i=0,a=function(){n=void 0,i=Date.now(),t()};return function(){var o=Date.now(),r=e-(o-i);r<=0?(n&&(clearTimeout(n),n=void 0),i=o,t()):n||(n=setTimeout(a,r))}}function a(t,e,n){function i(t){n(t.changedTouches[0].clientX,t.changedTouches[0].clientY)}function a(t){n(t.clientX,t.clientY)}function o(){window.removeEventListener("pointermove",a),window.removeEventListener("touchmove",i),window.removeEventListener("pointerup",o),window.removeEventListener("pointercancel",o),window.removeEventListener("touchend",o),window.removeEventListener("touchcancel",o)}function r(t){if(t.touches.length>1)return o();e(t.changedTouches[0].clientX,t.changedTouches[0].clientY),window.addEventListener("touchmove",i),window.addEventListener("touchend",o),window.addEventListener("touchcancel",o)}function s(t){e(t.clientX,t.clientY),window.addEventListener("pointermove",a),window.addEventListener("pointerup",o),window.addEventListener("pointercancel",o)}return t.addEventListener("touchstart",r),t.addEventListener("pointerdown",s),function(){o(),t.removeEventListener(s),t.removeEventListener(r)}}function o(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var n=[],i=!0,a=!1,o=void 0;try{for(var r,s=t[Symbol.iterator]();!(i=(r=s.next()).done)&&(n.push(r.value),!e||n.length!==e);i=!0);}catch(t){a=!0,o=t}finally{try{i||null==s.return||s.return()}finally{if(a)throw o}}return n}(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function r(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function s(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var l=function(){function n(t){var e=this;!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,n),s(this,"onResize",function(t){e.setState({aspectRatio:e.getCanvasAspectRatio()})}),s(this,"onResizeThrottled",i(this.onResize,33)),s(this,"setState",function(t){e.state=function(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{},i=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(i=i.concat(Object.getOwnPropertySymbols(n).filter(function(t){return Object.getOwnPropertyDescriptor(n,t).enumerable}))),i.forEach(function(e){s(t,e,n[e])})}return t}({},e.state,t),e.render()}),s(this,"mapX",function(t){var n=e.props,i=n.canvasWidth,a=n.data,o=a.minX;return(t-o)/(a.maxX-o)*i}),s(this,"mapY",function(t){var n=e.props,i=n.canvasWidth,a=n.minYGlobal;return(t-a)/(n.maxYGlobal-a)*i/e.state.aspectRatio}),s(this,"setUpTimelineWindowHandle",function(t){var n,i,o,r,s="left"===t?e.timelineWindowLeftHandle:e.timelineWindowRightHandle,l=parseFloat(getComputedStyle(e.timelineWindow).borderLeftWidth);return a(s,function(a){n=e.timeline.getBoundingClientRect();var s=e.timelineWindow.getBoundingClientRect();"left"===t?(i=n.left,o=s.left+s.width-2*l,r=a-s.left):(i=s.left+2*l,o=n.left+n.width,r=a-(s.left+s.width))},function(a){a-=r;var s=((a=Math.max(Math.min(a,o),i))-n.left)/n.width;"left"===t?e.updateBounds(s,e.props.toRatio):e.updateBounds(e.props.fromRatio,s)})}),s(this,"setUpTimelineWindow",function(){var t,n,i,o,r;return a(e.timelineWindowDrag,function(a){t=e.timeline.getBoundingClientRect(),n=e.timelineWindow.getBoundingClientRect(),r=a-n.left,i=t.left,o=t.left+(t.width-n.width)},function(a){a-=r;var s=((a=Math.max(Math.min(a,o),i))-t.left)/t.width;e.updateBounds(s,s+n.width/t.width)})}),s(this,"setTimelineWindowLeft",function(t){e.timelineOverlayLeft.style.right="".concat(100*(1-t),"%"),e.timelineWindow.style.left="".concat(100*t,"%")}),s(this,"setTimelineWindowRight",function(t){e.timelineOverlayRight.style.left="".concat(100*t,"%"),e.timelineWindow.style.right="".concat(100*(1-t),"%")}),this.props=t}var l,c,h;return l=n,(c=[{key:"componentDidUpdate",value:function(t){this.props!==t&&(this.props=t,this.state={aspectRatio:this.getCanvasAspectRatio()},this.onChangeBounds(this.props.fromRatio,this.props.toRatio),this.render())}},{key:"componentDidMount",value:function(){var t=this.props.rootNode;this.timeline=t.querySelector(".chartogram__timeline"),this.timelineOverlayLeft=t.querySelector(".chartogram__timeline-overlay-left"),this.timelineWindowLeftHandle=t.querySelector(".chartogram__timeline-window__left-handle"),this.timelineWindow=t.querySelector(".chartogram__timeline-window"),this.timelineWindowDrag=t.querySelector(".chartogram__timeline-window__drag"),this.timelineWindowRightHandle=t.querySelector(".chartogram__timeline-window__right-handle"),this.timelineOverlayRight=t.querySelector(".chartogram__timeline-overlay-right"),this.timelineCanvas=t.querySelector(".chartogram__timeline-canvas"),this.state={aspectRatio:this.getCanvasAspectRatio()},this.setUpTimelineWindowHandle("left"),this.setUpTimelineWindowHandle("right"),this.setUpTimelineWindow(),window.addEventListener("resize",this.onResizeThrottled),this.onChangeBounds(this.props.fromRatio,this.props.toRatio),this.render()}},{key:"componentWillUnmount",value:function(){window.removeEventListener("resize",this.onResizeThrottled)}},{key:"getCanvasAspectRatio",value:function(){var t=this.timelineCanvas.getBoundingClientRect();return t.width/t.height}},{key:"render",value:function(){var n=this,i=this.props,a=i.canvasWidth,r=i.y,s=i.data,l=i.maxYGlobal,c=i.fixSvgCoordinate,h=i.createPolylinePoints,u=i.graphOpacity,d=this.state.aspectRatio;e(this.timelineCanvas),this.timelineCanvas.setAttribute("viewBox","0 0 ".concat(a," ").concat(c(a/d)));for(var p=0,m=function(){var e=s.y[p],i=e.id,a=e.color,c=e.points,d=u[p];if(r.find(function(t){return t.id===i}).isShown||d>0){var m=o(function e(n,i,a){var o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:Math.max.apply(Math,t(i)),r=arguments.length>4&&void 0!==arguments[4]?arguments[4]:.025,s=arguments.length>5&&void 0!==arguments[5]?arguments[5]:0,l=arguments.length>6&&void 0!==arguments[6]?arguments[6]:new Array(n.length),c=arguments.length>7&&void 0!==arguments[7]?arguments[7]:new Array(n.length),h=arguments.length>8&&void 0!==arguments[8]?arguments[8]:0;if(s+2>n.length-1){for(;s<i.length;)l[h]=n[s],c[h]=i[s],h++,s++;return l=l.slice(0,h),c=c.slice(0,h),l.length<=a?[l,c]:(n.length/l.length<1.1&&(r=Math.min(r+.025,1)),e(l,c,a,o,r))}var u=(i[s+2]+i[s])/2;return Math.abs(u-i[s+1])/o<r?(l[h]=n[s],l[h+1]=n[s+2],c[h]=i[s],c[h+1]=i[s+2],e(n,i,a,o,r,s+2,l,c,h+1)):(l[h]=n[s],l[h+1]=n[s+1],l[h+2]=n[s+2],c[h]=i[s],c[h+1]=i[s+1],c[h+2]=i[s+2],e(n,i,a,o,r,s+2,l,c,h+2))}(s.x.points,c,80),2),v=m[0],f=m[1],g=document.createElement("polyline");g.setAttribute("stroke",a),g.setAttribute("points",h(v.map(n.mapX),f.map(function(t){return n.mapY(l-t)})).join(" ")),g.classList.add("chartogram__graph"),1!==d&&(g.style.opacity=d),n.timelineCanvas.appendChild(g)}p++};p<s.y.length;)m();this.timelineCanvas.innerHTML+=""}},{key:"onChangeBounds",value:function(t,e){this.setTimelineWindowLeft(t),this.setTimelineWindowRight(e)}},{key:"updateBounds",value:function(t,e){this.props.onChangeBounds(t,e),this.props.fromRatio=t,this.props.toRatio=e,this.onChangeBounds(t,e)}}])&&r(l.prototype,c),h&&r(l,h),n}();function c(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function h(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}l.INITIAL_MARKUP='\n\t<div class="chartogram__timeline">\n\t\t<div class="chartogram__timeline-canvas-padding">\n\t\t\t<svg class="chartogram__timeline-canvas" preserveAspectRatio="none"></svg>\n\t\t</div>\n\t\t<div class="chartogram__timeline-overlay-left"></div>\n\t\t<div class="chartogram__timeline-overlay-right"></div>\n\t\t<div class="chartogram__timeline-window">\n\t\t\t<button type="button" class="chartogram__reset-button chartogram__timeline-window__drag"></button>\n\t\t\t<button type="button" class="chartogram__reset-button chartogram__timeline-window__left-handle"></button>\n\t\t\t<button type="button" class="chartogram__reset-button chartogram__timeline-window__right-handle"></button>\n\t\t</div>\n\t</div>\n';var u=function(){function t(e){var n=this;!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),h(this,"createGraphToggler",function(t){var e=t.id,i=t.name,a=t.color,o=document.createElement("button");o.setAttribute("type","button"),o.classList.add("chartogram__chart-toggler"),o.classList.add("chartogram__chart-toggler--on"),o.classList.add("chartogram__reset-button");var r="http://www.w3.org/2000/svg",s=document.createElementNS(r,"svg");s.setAttribute("viewBox","0 0 19 19"),s.setAttribute("class","chartogram__chart-toggler-check");var l=document.createElementNS(r,"circle");l.setAttribute("cx","9.5"),l.setAttribute("cy","9.5"),l.setAttribute("r","9.5"),l.setAttribute("fill",a),s.appendChild(l);var c=document.createElementNS(r,"circle");c.setAttribute("cx","9.5"),c.setAttribute("cy","9.5"),c.setAttribute("r","8"),c.setAttribute("class","chartogram__chart-toggler-check-circle"),s.appendChild(c);var h=document.createElementNS(r,"path");return h.setAttribute("d","M13.64 4.94l-6.2 6.34-1.69-1.9c-.73-.63-1.89.1-1.36 1.06l2 3.38c.3.43 1.04.85 1.78 0 .32-.42 6.31-7.93 6.31-7.93.74-.84-.2-1.58-.84-.95z"),h.setAttribute("fill","white"),h.setAttribute("class","chartogram__chart-toggler-check-mark"),s.appendChild(h),o.appendChild(s),o.appendChild(document.createTextNode(i)),o.addEventListener("click",function(){return n.onToggle(e,o)}),o}),h(this,"onToggle",function(t,e){(0,n.props.onToggle)(t)&&e.classList.toggle("chartogram__chart-toggler--on")}),this.props=e}var n,i,a;return n=t,(i=[{key:"componentDidMount",value:function(){var t=this.props,n=t.rootNode,i=t.data,a=n.querySelector(".chartogram__chart-togglers");e(a);var o=i.y,r=Array.isArray(o),s=0;for(o=r?o:o[Symbol.iterator]();;){var l;if(r){if(s>=o.length)break;l=o[s++]}else{if((s=o.next()).done)break;l=s.value}var c=l;a.appendChild(this.createGraphToggler(c))}}}])&&c(n.prototype,i),a&&c(n,a),t}();function d(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function p(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}u.INITIAL_MARKUP='\n\t<div class="chartogram__chart-togglers"></div>\n';var m=function(){function t(e){var n=this;!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),p(this,"setUpListener",function(){var t,e,i=n.props,a=i.canvas,o=i.canvasWidthPx,r=i.weekdays,s=i.months,l=function(i){var a,l=n.props,c=l.minX,h=l.maxX,u=l.xPoints,d=l.y,p=c+(i-t.left)/t.width*(h-c),m=u.findIndex(function(t){return t>=p}),v=m-1;if(e(m)||(m=-1),e(v)||(v=-1),m<0){if(v<0)return n.unmount();a=v}else if(v<0)a=m;else{var f=u[v],g=u[m];a=p-f>g-p?m:v}var y=u[a];if(y!==n.tooltipForX){n.tooltipForX=y,n.tooltip||n.mount();var w=new Date(y);n.tooltipDate.textContent="".concat(r[w.getDay()],", ").concat(s[w.getMonth()]," ").concat(w.getDate());var b=0,x=d,_=Array.isArray(x),S=0;for(x=_?x:x[Symbol.iterator]();;){var A;if(_){if(S>=x.length)break;A=x[S++]}else{if((S=x.next()).done)break;A=S.value}var C=A,L=C.isShown,T=C.points,k=C.name;L&&(n.tooltipValues.childNodes[2*b].textContent=T[a],n.tooltipValues.childNodes[2*b+1].textContent=k,b++)}var R=(y-c)/(h-c),Y=R*o;Y-=40;var E=n.tooltip.getBoundingClientRect().width;Y<-5?Y=-5:Y+E>o+5&&(Y=o+5-E),n.tooltip.style.left=Y+"px",n.updatePoints(a,R),n.updateLine(y)}},c=function(){t=a.getBoundingClientRect(),e=function(t){var e=n.props.xPoints;return t>=0&&t<e.length}},h=function(t){if(t.touches.length>1)return p();c(),a.addEventListener("touchend",p),a.addEventListener("touchmove",u),a.addEventListener("touchend",p),a.addEventListener("touchcancel",p),u(t)};function u(e){var n=e.changedTouches[0].clientX,i=e.changedTouches[0].clientY;n<t.left||n>t.left+t.width||i<t.top||i>t.top+t.height?p():l(n,i)}function d(t){l(t.clientX,t.clientY)}a.addEventListener("touchstart",h);var p=function t(){a.removeEventListener("pointermove",d),a.removeEventListener("pointerleave",t),a.removeEventListener("pointercancel",t),a.removeEventListener("touchmove",u),a.removeEventListener("touchend",t),a.removeEventListener("touchcancel",t),n.unmount()},m=function(){c(),a.addEventListener("pointermove",d),a.addEventListener("pointerleave",p),a.addEventListener("pointercancel",p)};return a.addEventListener("pointerenter",m),function(){p(),a.removeEventListener(m),a.removeEventListener(h)}}),p(this,"unmountLine",function(){n.props.canvas.removeChild(n.line),n.line=void 0}),p(this,"unmountPoints",function(){var t=n.props.pointsContainer,e=n.points,i=Array.isArray(e),a=0;for(e=i?e:e[Symbol.iterator]();;){var o;if(i){if(a>=e.length)break;o=e[a++]}else{if((a=e.next()).done)break;o=a.value}var r=o;t.removeChild(r)}n.points=void 0}),p(this,"updateLine",function(t){n.isLineRendered()||n.renderLine();var e=n.props,i=e.canvasWidth,a=e.aspectRatio,o=e.fixSvgCoordinate,r=e.mapX;n.line.setAttributeNS(null,"x1",o(r(t))),n.line.setAttributeNS(null,"x2",o(r(t))),n.line.setAttributeNS(null,"y1",0),n.line.setAttributeNS(null,"y2",o(i/a))}),p(this,"updatePoints",function(t,e){for(var i=n.props,a=i.maxY,o=i.y,r=0,s=0;r<o.length;){if(o[r].isShown){var l=n.points[s],c=o[r].points[t]/a;l.style.left="".concat(100*e,"%"),l.style.bottom="".concat(100*c,"%"),s++}r++}}),this.props=e}var e,n,i;return e=t,(n=[{key:"componentDidMount",value:function(){this.unlisten=this.setUpListener()}},{key:"componentWillUnmount",value:function(){this.unlisten(),this.unmount()}},{key:"componentDidUpdate",value:function(t){this.props!==t&&(this.props=t)}},{key:"mount",value:function(){this.renderTooltip(),this.renderPoints(),this.isLineRendered()||this.renderLine()}},{key:"renderTooltip",value:function(){var t=this.props,e=t.y,n=t.container;this.tooltip=document.createElement("div"),this.tooltip.classList.add("chartogram__tooltip"),n.appendChild(this.tooltip),this.tooltipDate=document.createElement("h1"),this.tooltipDate.classList.add("chartogram__tooltip-header"),this.tooltip.appendChild(this.tooltipDate),this.tooltipValues=document.createElement("dl"),this.tooltipValues.classList.add("chartogram__tooltip-values"),this.tooltip.appendChild(this.tooltipValues);var i=e,a=Array.isArray(i),o=0;for(i=a?i:i[Symbol.iterator]();;){var r;if(a){if(o>=i.length)break;r=i[o++]}else{if((o=i.next()).done)break;r=o.value}var s=r,l=s.isShown,c=s.color;if(l){var h=document.createElement("dt");h.style.color=c,this.tooltipValues.appendChild(h);var u=document.createElement("dd");u.style.color=c,this.tooltipValues.appendChild(u)}}}},{key:"renderLine",value:function(){var t=this.props.canvas;this.line=document.createElementNS("http://www.w3.org/2000/svg","line"),this.line.setAttribute("class","chartogram__tooltip-line"),t.insertBefore(this.line,t.querySelector("polyline"))}},{key:"unmount",value:function(){if(this.tooltip){var t=this.props.container;this.tooltipForX=void 0,t.removeChild(this.tooltip),this.tooltip=void 0,this.unmountPoints(),this.isLineRendered()&&this.unmountLine()}}},{key:"isLineRendered",value:function(){var t=this.props.canvas;return this.line&&this.line.parentNode===t}},{key:"renderPoints",value:function(){this.points=[];var t=this.props,e=t.pointsContainer,n=t.y,i=Array.isArray(n),a=0;for(n=i?n:n[Symbol.iterator]();;){var o;if(i){if(a>=n.length)break;o=n[a++]}else{if((a=n.next()).done)break;o=a.value}var r=o;if(r.isShown){var s=document.createElement("div");s.classList.add("chartogram__tooltip-point"),s.style.color=r.color,this.points.push(s),e.appendChild(s)}}}}])&&d(e.prototype,n),i&&d(e,i),t}();function v(t){return function(t){if(Array.isArray(t)){for(var e=0,n=new Array(t.length);e<t.length;e++)n[e]=t[e];return n}}(t)||function(t){if(Symbol.iterator in Object(t)||"[object Arguments]"===Object.prototype.toString.call(t))return Array.from(t)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}function f(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{},i=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(i=i.concat(Object.getOwnPropertySymbols(n).filter(function(t){return Object.getOwnPropertyDescriptor(n,t).enumerable}))),i.forEach(function(e){y(t,e,n[e])})}return t}function g(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function y(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var w=function(){function t(a,o){var r=this,s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"Title",l=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),y(this,"onResize",function(t){r.setState({aspectRatio:r.getCanvasAspectRatio(),canvasWidthPx:r.getCanvasWidthPx()},!1)}),y(this,"onResizeThrottled",i(this.onResize,33)),y(this,"onToggle",function(t){var e=r.state.y.find(function(e){return e.id===t});if(e.isShown&&1===r.state.y.filter(function(t){return t.isShown}).length)return;e.isShown=!e.isShown,r.setState({y:r.state.y});var n=r.calculateMinMaxY(r.state.y),i=n.minY,a=n.maxY,o=n.minYGlobal,s=n.maxYGlobal;return r.transitionState(i,a,o,s,r.state.y.map(function(t){return t.isShown?1:0})),!0}),y(this,"onChangeBounds",function(t,e){r.setState(r.createState(t,e),!1)}),y(this,"createPolylinePoints",function(t,e){return n=t.map(r.fixSvgCoordinate),i=e.map(r.fixSvgCoordinate),n.map(function(t,e){return"".concat(t,",").concat(i[e])});var n,i}),y(this,"fixSvgCoordinate",function(t){var e=r.props.precisionFactor;return Math.round(t*e)/e}),y(this,"mapX",function(t){var e=r.props.canvasWidth,n=r.state,i=n.minX;return(t-i)/(n.maxX-i)*e}),y(this,"mapY",function(t){var e=r.props.canvasWidth,n=r.state,i=n.minY;return(t-i)/(n.maxY-i)*e/n.aspectRatio}),y(this,"transitionStateTick",function(){var t=r.props.transitionEasing,e=r.state,n=e.transitionStartedAt,i=e.transitionDuration,a=e.graphOpacityFrom,o=e.graphOpacityTo,s=e.minYFrom,l=e.minYTo,c=e.maxYFrom,h=e.maxYTo,u=e.minYGlobalFrom,d=e.minYGlobalTo,p=e.maxYGlobalFrom,m=e.maxYGlobalTo,v=Date.now()-n,f=Math.min(v/i,1);f=S[t](f),r.setState({graphOpacity:o.map(function(t,e){return a[e]+(o[e]-a[e])*f}),minY:s+(l-s)*f,maxY:c+(h-c)*f,minYGlobal:u+(d-u)*f,maxYGlobal:p+(m-p)*f}),r.transition=f<1?requestAnimationFrame(r.transitionStateTick):void 0}),y(this,"createGridLine",function(t){var e=r.state,n=e.minX,i=e.maxX,a=(e.minY,e.maxY),o=document.createElement("line");return o.classList.add("chartogram__grid-line"),o.setAttribute("x1",r.fixSvgCoordinate(r.mapX(n))),o.setAttribute("x2",r.fixSvgCoordinate(r.mapX(i))),o.setAttribute("y1",r.fixSvgCoordinate(r.mapY(a-t))),o.setAttribute("y2",r.fixSvgCoordinate(r.mapY(a-t))),o}),y(this,"drawGauges",function(t,i,a,o,s){var l=r.props,c=l.gaugeTickMarksCount,h=l.months;e(r.xAxis),e(r.yAxis),n(r.xAxis,t,i,c,function(t){var e=new Date(t);return"".concat(h[e.getMonth()]," ").concat(e.getDate())}),n(r.yAxis,a,o,c),r.yAxis.style.height="".concat(100/s,"%")}),this.props=f({title:s,transitionDuration:300,transitionEasing:"easeOutQuad",gaugeTickMarksCount:6,timelineWindowSize:40,canvasWidth:512,precisionFactor:Math.pow(10,l.precision||3),months:b,weekdays:x},l),this.rootNode=a,this.data=f({},o,{minX:Math.min.apply(Math,v(o.x.points)),maxX:Math.max.apply(Math,v(o.x.points)),y:o.y.map(function(t){return f({},t,{min:Math.min.apply(Math,v(t.points)),max:Math.max.apply(Math,v(t.points))})})})}var a,o,r;return a=t,(o=[{key:"componentDidMount",value:function(){this.rootNode.classList.add("chartogram"),this.rootNode.innerHTML="\n\t\t\t".concat(_.replace("{title}",this.props.title),"\n\t\t\t").concat(l.INITIAL_MARKUP,"\n\t\t\t").concat(u.INITIAL_MARKUP,"\n\t\t"),this.tooltipContainer=this.rootNode.querySelector(".chartogram__plan"),this.canvas=this.rootNode.querySelector(".chartogram__canvas"),this.canvasWrapper=this.rootNode.querySelector(".chartogram__canvas-wrapper"),this.xAxis=this.rootNode.querySelector(".chartogram__x"),this.yAxis=this.rootNode.querySelector(".chartogram__y"),this.state=this.getInitialState(),this.timeline=new l(this.getTimelineProps()),this.timeline.componentDidMount(),this.togglers=new u(this.getTogglersProps()),this.togglers.componentDidMount(),this.tooltip=new m(this.getTooltipProps()),this.tooltip.componentDidMount(),window.addEventListener("resize",this.onResizeThrottled),this.render()}},{key:"componentWillUnmount",value:function(){this.timeline.componentWillUnmount(),this.rootNode.classList.remove("chartogram"),e(this.rootNode),window.removeEventListener("resize",this.onResizeThrottled)}},{key:"getCanvasAspectRatio",value:function(){var t=this.canvas.getBoundingClientRect();return t.width/t.height}},{key:"getCanvasWidthPx",value:function(){return this.canvas.getBoundingClientRect().width}},{key:"setState",value:function(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];this.state=f({},this.state,t),this.render(),e&&this.timeline.componentDidUpdate(this.getTimelineProps()),this.tooltip.componentDidUpdate(this.getTooltipProps())}},{key:"getTimelineProps",value:function(){return{rootNode:this.rootNode,data:this.data,canvasWidth:this.props.canvasWidth,fixSvgCoordinate:this.fixSvgCoordinate,createPolylinePoints:this.createPolylinePoints,fromRatio:this.state.fromRatio,toRatio:this.state.toRatio,minYGlobal:this.state.minYGlobal,maxYGlobal:this.state.maxYGlobal,y:this.state.y,graphOpacity:this.state.graphOpacity,onChangeBounds:this.onChangeBounds}}},{key:"getTogglersProps",value:function(){return{rootNode:this.rootNode,data:this.data,onToggle:this.onToggle}}},{key:"getTooltipProps",value:function(){return{canvas:this.canvas,canvasWidthPx:this.state.canvasWidthPx,container:this.tooltipContainer,pointsContainer:this.canvasWrapper,weekdays:this.props.weekdays,months:this.props.months,canvasWidth:this.props.canvasWidth,aspectRatio:this.state.aspectRatio,mapX:this.mapX,fixSvgCoordinate:this.fixSvgCoordinate,minX:this.state.minX,maxX:this.state.maxX,maxY:this.state.maxY,xPoints:this.state.xPoints,y:this.state.y}}},{key:"getInitialState",value:function(){var t,e=this.props.timelineWindowSize,n=this.data,i=n.minX,a=n.maxX;t=this.data.x.points.length>e?this.data.x.points.length-e:0;var o=(this.data.x.points[t]-i)/(a-i);return f({},this.createState(o,1),{aspectRatio:this.getCanvasAspectRatio(),canvasWidthPx:this.getCanvasWidthPx(),graphOpacity:this.data.y.map(function(t){return 1})})}},{key:"createState",value:function(t,e){var n,i,a=this,o=this.data.x,r=this.data.minX+t*(this.data.maxX-this.data.minX),s=this.data.minX+e*(this.data.maxX-this.data.minX);n=r===this.data.minX?0:o.points.findIndex(function(t){return t>r})-1,i=s===this.data.maxX?o.points.length-1:o.points.findIndex(function(t){return t>s});var l=o.points.slice(n,i+1),c=l.slice();l.length>=2&&(o.points[n]!==r&&(c[0]=r),o.points[i]!==s&&(c[c.length-1]=s));var h=this.data.y.map(function(t,e){var c=a.data.y[e].points.slice(n,i+1),h=c.slice();if(l.length>=2){if(o.points[n]!==r){var u=a.data.y[e].points[n],d=u+(a.data.y[e].points[n+1]-u)*((r-a.data.x.points[n])/(a.data.x.points[n+1]-a.data.x.points[n]));h[0]=d}if(o.points[i]!==s){var p=a.data.y[e].points[i],m=a.data.y[e].points[i-1],g=m+(p-m)*((s-a.data.x.points[i-1])/(a.data.x.points[i]-a.data.x.points[i-1]));h[h.length-1]=g}}return f({},a.data.y[e],a.state?a.state.y[e]:{isShown:!0},{points:c,graphPoints:h,min:0,max:Math.max.apply(Math,v(h))})});return f({minX:r,maxX:s,fromIndex:n,toIndex:i,fromRatio:t,toRatio:e,xPoints:l,xGraphPoints:c},this.calculateMinMaxY(h),{y:h})}},{key:"calculateMinMaxY",value:function(t){var e=1/0,n=-1/0,i=t,a=Array.isArray(i),o=0;for(i=a?i:i[Symbol.iterator]();;){var r;if(a){if(o>=i.length)break;r=i[o++]}else{if((o=i.next()).done)break;r=o.value}var s=r;s.isShown&&(e=Math.min(e,s.min),n=Math.max(n,s.max))}var l=1/0,c=-1/0,h=function(){if(d){if(p>=u.length)return"break";m=u[p++]}else{if((p=u.next()).done)return"break";m=p.value}var e=m;t.find(function(t){return t.id===e.id}).isShown&&(l=Math.min(l,e.min),c=Math.max(c,e.max))},u=this.data.y,d=Array.isArray(u),p=0;for(u=d?u:u[Symbol.iterator]();;){var m;if("break"===h())break}return{minY:e,maxY:n,minYGlobal:l=0,maxYGlobal:c}}},{key:"render",value:function(){var t=this,n=this.props,i=n.canvasWidth,a=n.gaugeTickMarksCount,o=this.state,r=o.minX,s=o.maxX,l=o.minY,c=o.maxY,h=o.xGraphPoints,u=o.aspectRatio,d=o.graphOpacity;e(this.canvas),this.canvas.setAttribute("viewBox","0 0 ".concat(i," ").concat(this.fixSvgCoordinate(i/u)));var p=l,m=function(t,e){for(t=Math.floor(t);;){if(t<e)return e;if(t%e==0)return t;t--}}(c,10),v=(c-l)/(m-p),f=function(t,e,n){for(var i=new Array(n),a=0;a<n;)i[a]=t+a*(e-t)/(n-1),a++;return i}(p,m,a),g=Array.isArray(f),y=0;for(f=g?f:f[Symbol.iterator]();;){var w;if(g){if(y>=f.length)break;w=f[y++]}else{if((y=f.next()).done)break;w=y.value}var b=w;this.canvas.appendChild(this.createGridLine(b))}for(var x=0;x<this.state.y.length;){var _=this.state.y[x],S=_.color,A=_.graphPoints,C=_.isShown,L=d[x];if(C||L>0){var T=document.createElement("polyline");T.setAttribute("stroke",S),T.setAttribute("points",this.createPolylinePoints(h.map(this.mapX),A.map(function(e){return t.mapY(c-e)})).join(" ")),T.classList.add("chartogram__graph"),1!==L&&(T.style.opacity=L),this.canvas.appendChild(T)}x++}this.canvas.innerHTML+="",this.drawGauges(r,s,p,m,v)}},{key:"transitionState",value:function(t,e,n,i,a){var o=this.props.transitionDuration;this.transition&&cancelAnimationFrame(this.transition);var r=this.state.maxY-this.state.minY,s=Math.abs(e-this.state.maxY)/r,l=Math.abs(t-this.state.minY)/r,c=Math.max(l,s),h=o*Math.max(.1,2*Math.min(c,.5));this.setState({graphOpacityFrom:this.state.graphOpacity,graphOpacityTo:a,minYFrom:this.state.minY,maxYFrom:this.state.maxY,minYTo:t,maxYTo:e,minYGlobalFrom:this.state.minYGlobal,maxYGlobalFrom:this.state.maxYGlobal,minYGlobalTo:n,maxYGlobalTo:i,transitionStartedAt:Date.now(),transitionDuration:h}),this.transition=requestAnimationFrame(this.transitionStateTick)}}])&&g(a.prototype,o),r&&g(a,r),t}(),b=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],x=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],_='\n\t<header class="chartogram__header">\n\t\t<h1 class="chartogram__title">{title}</h1>\n\t</header>\n\t<div class="chartogram__plan-with-axes">\n\t\t<div class="chartogram__plan">\n\t\t\t<div class="chartogram__top-border"></div>\n\t\t\t<div class="chartogram__canvas-wrapper">\n\t\t\t\t<svg class="chartogram__canvas"></svg>\n\t\t\t\t<div class="chartogram__x"></div>\n\t\t\t\t<div class="chartogram__y-wrapper">\n\t\t\t\t\t<div class="chartogram__y"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n',S={linear:function(t){return t},easeInOutSin:function(t){return(1+Math.sin(Math.PI*t-Math.PI/2))/2},easeInOutQuad:function(t){return t<.5?2*t*t:(4-2*t)*t-1},easeInOutCubic:function(t){return t<.5?4*t*t*t:(t-1)*(2*t-2)*(2*t-2)+1},easeOutCubic:function(t){return--t*t*t+1},easeOutQuad:function(t){return t*(2-t)}};return function(t,e,n,i){var a=new w(t,e,n,i);return a.componentDidMount(),function(){a.componentWillUnmount()}}});
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).chartogram=e()}(this,function(){"use strict";function t(t){return function(t){if(Array.isArray(t)){for(var e=0,n=new Array(t.length);e<t.length;e++)n[e]=t[e];return n}}(t)||function(t){if(Symbol.iterator in Object(t)||"[object Arguments]"===Object.prototype.toString.call(t))return Array.from(t)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}function e(t){for(;t.firstChild;)t.removeChild(t.firstChild)}function n(t,e,n,i,a){for(var o=0;o<i;){var r=document.createElement("div"),s=e+o*(n-e)/(i-1);a&&(s=a(s)),r.appendChild(document.createTextNode(s)),t.appendChild(r),o++}}function i(t,e){var n,i=0,a=function(){n=void 0,i=Date.now(),t()};return function(){var o=Date.now(),r=e-(o-i);r<=0?(n&&(clearTimeout(n),n=void 0),i=o,t()):n||(n=setTimeout(a,r))}}function a(t,e,n){function i(t){n(t.changedTouches[0].clientX,t.changedTouches[0].clientY)}function a(t){n(t.clientX,t.clientY)}function o(){window.removeEventListener("pointermove",a),window.removeEventListener("touchmove",i),window.removeEventListener("pointerup",o),window.removeEventListener("pointercancel",o),window.removeEventListener("touchend",o),window.removeEventListener("touchcancel",o)}function r(t){if(t.touches.length>1)return o();e(t.changedTouches[0].clientX,t.changedTouches[0].clientY),window.addEventListener("touchmove",i),window.addEventListener("touchend",o),window.addEventListener("touchcancel",o)}function s(t){e(t.clientX,t.clientY),window.addEventListener("pointermove",a),window.addEventListener("pointerup",o),window.addEventListener("pointercancel",o)}return t.addEventListener("touchstart",r),t.addEventListener("pointerdown",s),function(){o(),t.removeEventListener(s),t.removeEventListener(r)}}function o(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var n=[],i=!0,a=!1,o=void 0;try{for(var r,s=t[Symbol.iterator]();!(i=(r=s.next()).done)&&(n.push(r.value),!e||n.length!==e);i=!0);}catch(t){a=!0,o=t}finally{try{i||null==s.return||s.return()}finally{if(a)throw o}}return n}(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function r(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function s(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var l=function(){function n(t){var e=this;!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,n),s(this,"onResize",function(t){e.setState({aspectRatio:e.getCanvasAspectRatio()})}),s(this,"onResizeThrottled",i(this.onResize,33)),s(this,"setState",function(t){e.state=function(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{},i=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(i=i.concat(Object.getOwnPropertySymbols(n).filter(function(t){return Object.getOwnPropertyDescriptor(n,t).enumerable}))),i.forEach(function(e){s(t,e,n[e])})}return t}({},e.state,t),e.render()}),s(this,"mapX",function(t){var n=e.props,i=n.canvasWidth,a=n.data,o=a.minX;return(t-o)/(a.maxX-o)*i}),s(this,"mapY",function(t){var n=e.props,i=n.canvasWidth,a=n.minYGlobal;return(t-a)/(n.maxYGlobal-a)*i/e.state.aspectRatio}),s(this,"setUpTimelineWindowHandle",function(t){var n,i,o,r,s="left"===t?e.timelineWindowLeftHandle:e.timelineWindowRightHandle,l=parseFloat(getComputedStyle(e.timelineWindow).borderLeftWidth);return a(s,function(a){n=e.timeline.getBoundingClientRect();var s=e.timelineWindow.getBoundingClientRect();"left"===t?(i=n.left,o=s.left+s.width-2*l,r=a-s.left):(i=s.left+2*l,o=n.left+n.width,r=a-(s.left+s.width))},function(a){a-=r;var s=((a=Math.max(Math.min(a,o),i))-n.left)/n.width;"left"===t?e.updateBounds(s,e.props.toRatio):e.updateBounds(e.props.fromRatio,s)})}),s(this,"setUpTimelineWindow",function(){var t,n,i,o,r;return a(e.timelineWindowDrag,function(a){t=e.timeline.getBoundingClientRect(),n=e.timelineWindow.getBoundingClientRect(),r=a-n.left,i=t.left,o=t.left+(t.width-n.width)},function(a){a-=r;var s=((a=Math.max(Math.min(a,o),i))-t.left)/t.width;e.updateBounds(s,s+n.width/t.width)})}),s(this,"setTimelineWindowLeft",function(t){e.timelineOverlayLeft.style.right="".concat(100*(1-t),"%"),e.timelineWindow.style.left="".concat(100*t,"%")}),s(this,"setTimelineWindowRight",function(t){e.timelineOverlayRight.style.left="".concat(100*t,"%"),e.timelineWindow.style.right="".concat(100*(1-t),"%")}),this.props=t}var l,c,h;return l=n,(c=[{key:"componentDidUpdate",value:function(t){this.props!==t&&(this.props=t,this.state={aspectRatio:this.getCanvasAspectRatio()},this.onChangeBounds(this.props.fromRatio,this.props.toRatio),this.render())}},{key:"componentDidMount",value:function(){var t=this.props.rootNode;this.timeline=t.querySelector(".chartogram__timeline"),this.timelineOverlayLeft=t.querySelector(".chartogram__timeline-overlay-left"),this.timelineWindowLeftHandle=t.querySelector(".chartogram__timeline-window__left-handle"),this.timelineWindow=t.querySelector(".chartogram__timeline-window"),this.timelineWindowDrag=t.querySelector(".chartogram__timeline-window__drag"),this.timelineWindowRightHandle=t.querySelector(".chartogram__timeline-window__right-handle"),this.timelineOverlayRight=t.querySelector(".chartogram__timeline-overlay-right"),this.timelineCanvas=t.querySelector(".chartogram__timeline-canvas"),this.state={aspectRatio:this.getCanvasAspectRatio()},this.setUpTimelineWindowHandle("left"),this.setUpTimelineWindowHandle("right"),this.setUpTimelineWindow(),window.addEventListener("resize",this.onResizeThrottled),this.onChangeBounds(this.props.fromRatio,this.props.toRatio),this.render()}},{key:"componentWillUnmount",value:function(){window.removeEventListener("resize",this.onResizeThrottled)}},{key:"getCanvasAspectRatio",value:function(){var t=this.timelineCanvas.getBoundingClientRect();return t.width/t.height}},{key:"render",value:function(){var n=this,i=this.props,a=i.canvasWidth,r=i.y,s=i.data,l=i.maxYGlobal,c=i.fixSvgCoordinate,h=i.createPolylinePoints,u=i.graphOpacity,d=this.state.aspectRatio;e(this.timelineCanvas),this.timelineCanvas.setAttribute("viewBox","0 0 ".concat(a," ").concat(c(a/d)));for(var p=0,m=function(){var e=s.y[p],i=e.id,a=e.color,c=e.points,d=u[p];if(r.find(function(t){return t.id===i}).isShown||d>0){var m=o(function e(n,i,a){var o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:Math.max.apply(Math,t(i)),r=arguments.length>4&&void 0!==arguments[4]?arguments[4]:.025,s=arguments.length>5&&void 0!==arguments[5]?arguments[5]:0,l=arguments.length>6&&void 0!==arguments[6]?arguments[6]:new Array(n.length),c=arguments.length>7&&void 0!==arguments[7]?arguments[7]:new Array(n.length),h=arguments.length>8&&void 0!==arguments[8]?arguments[8]:0;if(s+2>n.length-1){for(;s<i.length;)l[h]=n[s],c[h]=i[s],h++,s++;return l=l.slice(0,h),c=c.slice(0,h),l.length<=a?[l,c]:(n.length/l.length<1.1&&(r=Math.min(r+.025,1)),e(l,c,a,o,r))}var u=(i[s+2]+i[s])/2;return Math.abs(u-i[s+1])/o<r?(l[h]=n[s],l[h+1]=n[s+2],c[h]=i[s],c[h+1]=i[s+2],e(n,i,a,o,r,s+2,l,c,h+1)):(l[h]=n[s],l[h+1]=n[s+1],l[h+2]=n[s+2],c[h]=i[s],c[h+1]=i[s+1],c[h+2]=i[s+2],e(n,i,a,o,r,s+2,l,c,h+2))}(s.x.points,c,80),2),v=m[0],f=m[1],g=document.createElement("polyline");g.setAttribute("stroke",a),g.setAttribute("points",h(v.map(n.mapX),f.map(function(t){return n.mapY(l-t)})).join(" ")),g.classList.add("chartogram__graph"),1!==d&&(g.style.opacity=d),n.timelineCanvas.appendChild(g)}p++};p<s.y.length;)m();this.timelineCanvas.innerHTML+=""}},{key:"onChangeBounds",value:function(t,e){this.setTimelineWindowLeft(t),this.setTimelineWindowRight(e)}},{key:"updateBounds",value:function(t,e){this.props.onChangeBounds(t,e),this.props.fromRatio=t,this.props.toRatio=e,this.onChangeBounds(t,e)}}])&&r(l.prototype,c),h&&r(l,h),n}();function c(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function h(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}l.INITIAL_MARKUP='\n\t<div class="chartogram__timeline">\n\t\t<div class="chartogram__timeline-canvas-padding">\n\t\t\t<svg class="chartogram__timeline-canvas" preserveAspectRatio="none"></svg>\n\t\t</div>\n\t\t<div class="chartogram__timeline-overlay-left"></div>\n\t\t<div class="chartogram__timeline-overlay-right"></div>\n\t\t<div class="chartogram__timeline-window">\n\t\t\t<button type="button" class="chartogram__reset-button chartogram__timeline-window__drag"></button>\n\t\t\t<button type="button" class="chartogram__reset-button chartogram__timeline-window__left-handle"></button>\n\t\t\t<button type="button" class="chartogram__reset-button chartogram__timeline-window__right-handle"></button>\n\t\t</div>\n\t</div>\n';var u=function(){function t(e){var n=this;!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),h(this,"createGraphToggler",function(t){var e=t.id,i=t.name,a=t.color,o=document.createElement("button");o.setAttribute("type","button"),o.classList.add("chartogram__chart-toggler"),o.classList.add("chartogram__chart-toggler--on"),o.classList.add("chartogram__reset-button");var r="http://www.w3.org/2000/svg",s=document.createElementNS(r,"svg");s.setAttribute("viewBox","0 0 19 19"),s.setAttribute("class","chartogram__chart-toggler-check");var l=document.createElementNS(r,"circle");l.setAttribute("cx","9.5"),l.setAttribute("cy","9.5"),l.setAttribute("r","9.5"),l.setAttribute("fill",a),s.appendChild(l);var c=document.createElementNS(r,"circle");c.setAttribute("cx","9.5"),c.setAttribute("cy","9.5"),c.setAttribute("r","8"),c.setAttribute("class","chartogram__chart-toggler-check-circle"),s.appendChild(c);var h=document.createElementNS(r,"path");return h.setAttribute("d","M13.64 4.94l-6.2 6.34-1.69-1.9c-.73-.63-1.89.1-1.36 1.06l2 3.38c.3.43 1.04.85 1.78 0 .32-.42 6.31-7.93 6.31-7.93.74-.84-.2-1.58-.84-.95z"),h.setAttribute("fill","white"),h.setAttribute("class","chartogram__chart-toggler-check-mark"),s.appendChild(h),o.appendChild(s),o.appendChild(document.createTextNode(i)),o.addEventListener("click",function(){return n.onToggle(e,o)}),o}),h(this,"onToggle",function(t,e){(0,n.props.onToggle)(t)&&e.classList.toggle("chartogram__chart-toggler--on")}),this.props=e}var n,i,a;return n=t,(i=[{key:"componentDidMount",value:function(){var t=this.props,n=t.rootNode,i=t.data,a=n.querySelector(".chartogram__chart-togglers");e(a);var o=i.y,r=Array.isArray(o),s=0;for(o=r?o:o[Symbol.iterator]();;){var l;if(r){if(s>=o.length)break;l=o[s++]}else{if((s=o.next()).done)break;l=s.value}var c=l;a.appendChild(this.createGraphToggler(c))}}}])&&c(n.prototype,i),a&&c(n,a),t}();function d(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function p(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}u.INITIAL_MARKUP='\n\t<div class="chartogram__chart-togglers"></div>\n';var m=function(){function t(e){var n=this;!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),p(this,"setUpListener",function(){!function(t,e,n,i){var a;function o(t,e){n(t,e,a)}function r(){a=t.getBoundingClientRect(),e()}function s(e){if(e.touches.length>1)return h();r(),t.addEventListener("touchend",h),t.addEventListener("touchmove",l),t.addEventListener("touchend",h),t.addEventListener("touchcancel",h),l(e)}function l(t){var e=t.changedTouches[0].clientX,n=t.changedTouches[0].clientY;e<a.left||e>a.left+a.width||n<a.top||n>a.top+a.height?h():o(e,n)}function c(t){o(t.clientX,t.clientY)}function h(){t.removeEventListener("pointermove",c),t.removeEventListener("pointerleave",h),t.removeEventListener("pointercancel",h),t.removeEventListener("touchmove",l),t.removeEventListener("touchend",h),t.removeEventListener("touchcancel",h),i()}function u(){r(),t.addEventListener("pointermove",c),t.addEventListener("pointerleave",h),t.addEventListener("pointercancel",h)}t.addEventListener("touchstart",s),t.addEventListener("pointerenter",u)}(n.props.canvas,function(){},n.onTrack,function(){return n.unmount()})}),p(this,"onTrack",function(t,e,i){var a,o=n.props,r=o.minX,s=o.maxX,l=o.xPoints,c=r+(t-i.left)/i.width*(s-r),h=l.findIndex(function(t){return t>=c}),u=h-1;if((h<0||h>=l.length)&&(h=-1),(u<0||u>=l.length)&&(u=-1),h<0){if(u<0)return n.unmount();a=u}else if(u<0)a=h;else{var d=l[u],p=l[h];a=c-d>p-c?h:u}var m=l[a];m!==n.tooltipForX&&(n.tooltipForX=m,n.tooltip||n.mount(),n.updateTooltip(m,a,i.width))}),p(this,"unmountLine",function(){n.props.canvas.removeChild(n.line),n.line=void 0}),p(this,"mountPoints",function(){var t=n.props.pointsContainer;n.points=n.renderPoints();var e=n.points,i=Array.isArray(e),a=0;for(e=i?e:e[Symbol.iterator]();;){var o;if(i){if(a>=e.length)break;o=e[a++]}else{if((a=e.next()).done)break;o=a.value}var r=o;t.appendChild(r)}}),p(this,"unmountPoints",function(){var t=n.props.pointsContainer,e=n.points,i=Array.isArray(e),a=0;for(e=i?e:e[Symbol.iterator]();;){var o;if(i){if(a>=e.length)break;o=e[a++]}else{if((a=e.next()).done)break;o=a.value}var r=o;t.removeChild(r)}n.points=void 0}),p(this,"updateLinePosition",function(t){n.isLineRendered()||n.mountLine();var e=n.props,i=e.canvasWidth,a=e.aspectRatio,o=e.fixSvgCoordinate,r=e.mapX;n.line.setAttributeNS(null,"x1",o(r(t))),n.line.setAttributeNS(null,"x2",o(r(t))),n.line.setAttributeNS(null,"y1",0),n.line.setAttributeNS(null,"y2",o(i/a))}),p(this,"updatePointPositions",function(t,e){for(var i=n.props,a=i.maxY,o=i.y,r=0,s=0;r<o.length;){if(o[r].isShown){var l=n.points[s],c=o[r].points[t]/a;l.style.left="".concat(100*e,"%"),l.style.bottom="".concat(100*c,"%"),s++}r++}}),this.props=e}var e,n,i;return e=t,(n=[{key:"componentDidMount",value:function(){this.unlisten=this.setUpListener()}},{key:"componentWillUnmount",value:function(){this.unlisten(),this.unmount()}},{key:"componentDidUpdate",value:function(t){this.props!==t&&(this.props=t)}},{key:"mount",value:function(){var t=this.props.container;this.tooltip=this.renderTooltip(),t.appendChild(this.tooltip),this.mountPoints(),this.isLineRendered()||this.mountLine()}},{key:"unmount",value:function(){if(this.tooltip){var t=this.props.container;this.tooltipForX=void 0,t.removeChild(this.tooltip),this.tooltip=void 0,this.unmountPoints(),this.isLineRendered()&&this.unmountLine()}}},{key:"mountLine",value:function(){var t=this.props.canvas;this.line=this.renderLine(),t.insertBefore(this.line,t.querySelector("polyline"))}},{key:"renderTooltip",value:function(){var t=this.props.y,e=document.createElement("div");e.classList.add("chartogram__tooltip");var n=document.createElement("h1");n.classList.add("chartogram__tooltip-header"),e.appendChild(n);var i=document.createElement("dl");i.classList.add("chartogram__tooltip-values"),e.appendChild(i);var a=t,o=Array.isArray(a),r=0;for(a=o?a:a[Symbol.iterator]();;){var s;if(o){if(r>=a.length)break;s=a[r++]}else{if((r=a.next()).done)break;s=r.value}var l=s,c=l.isShown,h=l.color;if(c){var u=document.createElement("dt");u.style.color=h,i.appendChild(u);var d=document.createElement("dd");d.style.color=h,i.appendChild(d)}}return e}},{key:"renderLine",value:function(){var t=document.createElementNS("http://www.w3.org/2000/svg","line");return t.setAttribute("class","chartogram__tooltip-line"),t}},{key:"isLineRendered",value:function(){var t=this.props.canvas;return this.line&&this.line.parentNode===t}},{key:"renderPoints",value:function(){var t=[],e=this.props,n=e.pointsContainer,i=e.y,a=Array.isArray(i),o=0;for(i=a?i:i[Symbol.iterator]();;){var r;if(a){if(o>=i.length)break;r=i[o++]}else{if((o=i.next()).done)break;r=o.value}var s=r;if(s.isShown){var l=document.createElement("div");l.classList.add("chartogram__tooltip-point"),l.style.color=s.color,t.push(l),n.appendChild(l)}}return t}},{key:"updateTooltip",value:function(t,e,n){var i=this.props,a=i.minX,o=(t-a)/(i.maxX-a);this.updateTooltipDate(new Date(t)),this.updateTooltipValues(e),this.updateTooltipPosition(o,n),this.updatePointPositions(e,o),this.updateLinePosition(t)}},{key:"updateTooltipPosition",value:function(t,e){var n=this.props,i=n.tooltipShift,a=n.maxOverflow,o=t*e;o-=void 0===i?40:i;var r=this.tooltip.getBoundingClientRect().width,s=void 0===a?5:a;o<-1*s?o=-1*s:o+r>e+s&&(o=e+s-r),this.tooltip.style.left=o+"px"}},{key:"updateTooltipDate",value:function(t){var e=this.props,n=e.weekdays,i=e.months;this.tooltip.childNodes[0].textContent="".concat(n[t.getDay()],", ").concat(i[t.getMonth()]," ").concat(t.getDate())}},{key:"updateTooltipValues",value:function(t){var e=this.props.y,n=this.tooltip.childNodes[1],i=0,a=e,o=Array.isArray(a),r=0;for(a=o?a:a[Symbol.iterator]();;){var s;if(o){if(r>=a.length)break;s=a[r++]}else{if((r=a.next()).done)break;s=r.value}var l=s,c=l.isShown,h=l.points,u=l.name;c&&(n.childNodes[2*i].textContent=h[t],n.childNodes[2*i+1].textContent=u,i++)}}}])&&d(e.prototype,n),i&&d(e,i),t}();function v(t){return function(t){if(Array.isArray(t)){for(var e=0,n=new Array(t.length);e<t.length;e++)n[e]=t[e];return n}}(t)||function(t){if(Symbol.iterator in Object(t)||"[object Arguments]"===Object.prototype.toString.call(t))return Array.from(t)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}function f(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{},i=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(i=i.concat(Object.getOwnPropertySymbols(n).filter(function(t){return Object.getOwnPropertyDescriptor(n,t).enumerable}))),i.forEach(function(e){y(t,e,n[e])})}return t}function g(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function y(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var b=function(){function t(a,o){var r=this,s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"Title",l=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),y(this,"onResize",function(t){r.setState({aspectRatio:r.getCanvasAspectRatio()},!1)}),y(this,"onResizeThrottled",i(this.onResize,33)),y(this,"onToggle",function(t){var e=r.state.y.find(function(e){return e.id===t});if(e.isShown&&1===r.state.y.filter(function(t){return t.isShown}).length)return;e.isShown=!e.isShown,r.setState({y:r.state.y});var n=r.calculateMinMaxY(r.state.y),i=n.minY,a=n.maxY,o=n.minYGlobal,s=n.maxYGlobal;return r.transitionState(i,a,o,s,r.state.y.map(function(t){return t.isShown?1:0})),!0}),y(this,"onChangeBounds",function(t,e){var n=r.createState(t,e),i=n.minY,a=n.maxY;delete n.minY,delete n.maxY,r.setState(n,!1),r.transitionState(i,a)}),y(this,"createPolylinePoints",function(t,e){return n=t.map(r.fixSvgCoordinate),i=e.map(r.fixSvgCoordinate),n.map(function(t,e){return"".concat(t,",").concat(i[e])});var n,i}),y(this,"fixSvgCoordinate",function(t){var e=r.props.precisionFactor;return Math.round(t*e)/e}),y(this,"mapX",function(t){var e=r.props.canvasWidth,n=r.state,i=n.minX;return(t-i)/(n.maxX-i)*e}),y(this,"mapY",function(t){var e=r.props.canvasWidth,n=r.state,i=n.minY;return(t-i)/(n.maxY-i)*e/n.aspectRatio}),y(this,"transitionStateTick",function(){var t=r.props.transitionEasing,e=r.state,n=e.transitionStartedAt,i=e.transitionDuration,a=e.graphOpacityFrom,o=e.graphOpacityTo,s=e.minYFrom,l=e.minYTo,c=e.maxYFrom,h=e.maxYTo,u=e.minYGlobalFrom,d=e.minYGlobalTo,p=e.maxYGlobalFrom,m=e.maxYGlobalTo,v=Date.now()-n,f=Math.min(v/i,1);f=S[t](f);var g={};void 0!==l&&(g.minY=s+(l-s)*f,g.maxY=c+(h-c)*f,1===f&&(g.minYFrom=void 0,g.minYTo=void 0,g.maxYFrom=void 0,g.maxYTo=void 0)),void 0!==d&&(g.minYGlobal=u+(d-u)*f,g.maxYGlobal=p+(m-p)*f,1===f&&(g.minYGlobalFrom=void 0,g.minYGlobalTo=void 0,g.maxYGlobalFrom=void 0,g.maxYGlobalTo=void 0)),void 0!==o&&(g.graphOpacity=o.map(function(t,e){return a[e]+(o[e]-a[e])*f}),1===f&&(g.graphOpacityFrom=void 0,g.graphOpacityTo=void 0)),r.setState(g),r.transition=f<1?requestAnimationFrame(r.transitionStateTick):void 0}),y(this,"createGridLine",function(t){var e=r.state,n=e.minX,i=e.maxX,a=(e.minY,e.maxY),o=document.createElement("line");return o.classList.add("chartogram__grid-line"),o.setAttribute("x1",r.fixSvgCoordinate(r.mapX(n))),o.setAttribute("x2",r.fixSvgCoordinate(r.mapX(i))),o.setAttribute("y1",r.fixSvgCoordinate(r.mapY(a-t))),o.setAttribute("y2",r.fixSvgCoordinate(r.mapY(a-t))),o}),y(this,"drawGauges",function(t,i,a,o,s){var l=r.props,c=l.gaugeTickMarksCount,h=l.months;e(r.xAxis),e(r.yAxis),n(r.xAxis,t,i,c,function(t){var e=new Date(t);return"".concat(h[e.getMonth()]," ").concat(e.getDate())}),n(r.yAxis,a,o,c),r.yAxis.style.height="".concat(100/s,"%")}),this.props=f({title:s,transitionDuration:250,transitionEasing:"easeOutQuad",gaugeTickMarksCount:6,timelineWindowSize:40,canvasWidth:512,precisionFactor:Math.pow(10,l.precision||3),months:w,weekdays:x},l),this.rootNode=a,this.data=f({},o,{minX:Math.min.apply(Math,v(o.x.points)),maxX:Math.max.apply(Math,v(o.x.points)),y:o.y.map(function(t){return f({},t,{min:Math.min.apply(Math,v(t.points)),max:Math.max.apply(Math,v(t.points))})})})}var a,o,r;return a=t,(o=[{key:"componentDidMount",value:function(){this.rootNode.classList.add("chartogram"),this.rootNode.innerHTML="\n\t\t\t".concat(_.replace("{title}",this.props.title),"\n\t\t\t").concat(l.INITIAL_MARKUP,"\n\t\t\t").concat(u.INITIAL_MARKUP,"\n\t\t"),this.tooltipContainer=this.rootNode.querySelector(".chartogram__plan"),this.canvas=this.rootNode.querySelector(".chartogram__canvas"),this.canvasWrapper=this.rootNode.querySelector(".chartogram__canvas-wrapper"),this.xAxis=this.rootNode.querySelector(".chartogram__x"),this.yAxis=this.rootNode.querySelector(".chartogram__y"),this.state=this.getInitialState(),this.timeline=new l(this.getTimelineProps()),this.timeline.componentDidMount(),this.togglers=new u(this.getTogglersProps()),this.togglers.componentDidMount(),this.tooltip=new m(this.getTooltipProps()),this.tooltip.componentDidMount(),window.addEventListener("resize",this.onResizeThrottled),this.render()}},{key:"componentWillUnmount",value:function(){this.timeline.componentWillUnmount(),this.rootNode.classList.remove("chartogram"),e(this.rootNode),window.removeEventListener("resize",this.onResizeThrottled),this.transition&&cancelAnimationFrame(this.transition)}},{key:"getCanvasAspectRatio",value:function(){var t=this.canvas.getBoundingClientRect();return t.width/t.height}},{key:"setState",value:function(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];this.state=f({},this.state,t),this.render(),e&&this.timeline.componentDidUpdate(this.getTimelineProps()),this.tooltip.componentDidUpdate(this.getTooltipProps())}},{key:"getTimelineProps",value:function(){return{rootNode:this.rootNode,data:this.data,canvasWidth:this.props.canvasWidth,fixSvgCoordinate:this.fixSvgCoordinate,createPolylinePoints:this.createPolylinePoints,fromRatio:this.state.fromRatio,toRatio:this.state.toRatio,minYGlobal:this.state.minYGlobal,maxYGlobal:this.state.maxYGlobal,y:this.state.y,graphOpacity:this.state.graphOpacity,onChangeBounds:this.onChangeBounds}}},{key:"getTogglersProps",value:function(){return{rootNode:this.rootNode,data:this.data,onToggle:this.onToggle}}},{key:"getTooltipProps",value:function(){return{canvas:this.canvas,container:this.tooltipContainer,pointsContainer:this.canvasWrapper,weekdays:this.props.weekdays,months:this.props.months,canvasWidth:this.props.canvasWidth,aspectRatio:this.state.aspectRatio,mapX:this.mapX,fixSvgCoordinate:this.fixSvgCoordinate,minX:this.state.minX,maxX:this.state.maxX,maxY:this.state.maxY,xPoints:this.state.xPoints,y:this.state.y}}},{key:"getInitialState",value:function(){var t,e=this.props.timelineWindowSize,n=this.data,i=n.minX,a=n.maxX;t=this.data.x.points.length>e?this.data.x.points.length-e:0;var o=(this.data.x.points[t]-i)/(a-i);return f({},this.createState(o,1),{aspectRatio:this.getCanvasAspectRatio(),graphOpacity:this.data.y.map(function(t){return 1})})}},{key:"createState",value:function(t,e){var n,i,a=this,o=this.data.x,r=this.data.minX+t*(this.data.maxX-this.data.minX),s=this.data.minX+e*(this.data.maxX-this.data.minX);n=r===this.data.minX?0:o.points.findIndex(function(t){return t>r})-1,i=s===this.data.maxX?o.points.length-1:o.points.findIndex(function(t){return t>s});var l=o.points.slice(n,i+1),c=l.slice();l.length>=2&&(o.points[n]!==r&&(c[0]=r),o.points[i]!==s&&(c[c.length-1]=s));var h=this.data.y.map(function(t,e){var c=a.data.y[e].points.slice(n,i+1),h=c.slice();if(l.length>=2){if(o.points[n]!==r){var u=a.data.y[e].points[n],d=u+(a.data.y[e].points[n+1]-u)*((r-a.data.x.points[n])/(a.data.x.points[n+1]-a.data.x.points[n]));h[0]=d}if(o.points[i]!==s){var p=a.data.y[e].points[i],m=a.data.y[e].points[i-1],g=m+(p-m)*((s-a.data.x.points[i-1])/(a.data.x.points[i]-a.data.x.points[i-1]));h[h.length-1]=g}}return f({},a.data.y[e],a.state?a.state.y[e]:{isShown:!0},{points:c,graphPoints:h,min:0,max:Math.max.apply(Math,v(h))})});return f({minX:r,maxX:s,fromIndex:n,toIndex:i,fromRatio:t,toRatio:e,xPoints:l,xGraphPoints:c},this.calculateMinMaxY(h),{y:h})}},{key:"calculateMinMaxY",value:function(t){var e=1/0,n=-1/0,i=t,a=Array.isArray(i),o=0;for(i=a?i:i[Symbol.iterator]();;){var r;if(a){if(o>=i.length)break;r=i[o++]}else{if((o=i.next()).done)break;r=o.value}var s=r;s.isShown&&(e=Math.min(e,s.min),n=Math.max(n,s.max))}var l=1/0,c=-1/0,h=function(){if(d){if(p>=u.length)return"break";m=u[p++]}else{if((p=u.next()).done)return"break";m=p.value}var e=m;t.find(function(t){return t.id===e.id}).isShown&&(l=Math.min(l,e.min),c=Math.max(c,e.max))},u=this.data.y,d=Array.isArray(u),p=0;for(u=d?u:u[Symbol.iterator]();;){var m;if("break"===h())break}return{minY:e,maxY:n,minYGlobal:l=0,maxYGlobal:c}}},{key:"render",value:function(){var t=this,n=this.props,i=n.canvasWidth,a=n.gaugeTickMarksCount,o=this.state,r=o.minX,s=o.maxX,l=o.minY,c=o.maxY,h=o.xGraphPoints,u=o.aspectRatio,d=o.graphOpacity;e(this.canvas),this.canvas.setAttribute("viewBox","0 0 ".concat(i," ").concat(this.fixSvgCoordinate(i/u)));var p=l,m=function(t,e){for(t=Math.floor(t);;){if(t<e)return e;if(t%e==0)return t;t--}}(c,10),v=(c-l)/(m-p),f=function(t,e,n){for(var i=new Array(n),a=0;a<n;)i[a]=t+a*(e-t)/(n-1),a++;return i}(p,m,a),g=Array.isArray(f),y=0;for(f=g?f:f[Symbol.iterator]();;){var b;if(g){if(y>=f.length)break;b=f[y++]}else{if((y=f.next()).done)break;b=y.value}var w=b;this.canvas.appendChild(this.createGridLine(w))}for(var x=0;x<this.state.y.length;){var _=this.state.y[x],S=_.color,A=_.graphPoints,T=_.isShown,C=d[x];if(T||C>0){var k=document.createElement("polyline");k.setAttribute("stroke",S),k.setAttribute("points",this.createPolylinePoints(h.map(this.mapX),A.map(function(e){return t.mapY(c-e)})).join(" ")),k.classList.add("chartogram__graph"),1!==C&&(k.style.opacity=C),this.canvas.appendChild(k)}x++}this.canvas.innerHTML+="",this.drawGauges(r,s,p,m,v)}},{key:"transitionState",value:function(t,e,n,i,a){var o=this.props.transitionDuration;this.transition&&cancelAnimationFrame(this.transition);var r=o;if(void 0!==t){var s=this.state.maxY-this.state.minY,l=Math.abs(e-this.state.maxY)/s,c=Math.abs(t-this.state.minY)/s,h=Math.max(c,l);r=o*Math.max(.2,2*Math.min(h,.5))}var u={transitionStartedAt:Date.now(),transitionDuration:r};void 0!==t&&(u.minYFrom=this.state.minY,u.maxYFrom=this.state.maxY,u.minYTo=t,u.maxYTo=e),void 0!==a&&(u.graphOpacityFrom=this.state.graphOpacity,u.graphOpacityTo=a),void 0!==n&&(u.minYGlobalFrom=this.state.minYGlobal,u.maxYGlobalFrom=this.state.maxYGlobal,u.minYGlobalTo=n,u.maxYGlobalTo=i),this.setState(u),this.transition=requestAnimationFrame(this.transitionStateTick)}}])&&g(a.prototype,o),r&&g(a,r),t}(),w=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],x=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],_='\n\t<header class="chartogram__header">\n\t\t<h1 class="chartogram__title">{title}</h1>\n\t</header>\n\t<div class="chartogram__plan-with-axes">\n\t\t<div class="chartogram__plan">\n\t\t\t<div class="chartogram__top-border"></div>\n\t\t\t<div class="chartogram__canvas-wrapper">\n\t\t\t\t<svg class="chartogram__canvas"></svg>\n\t\t\t\t<div class="chartogram__x"></div>\n\t\t\t\t<div class="chartogram__y-wrapper">\n\t\t\t\t\t<div class="chartogram__y"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n',S={linear:function(t){return t},easeInOutSin:function(t){return(1+Math.sin(Math.PI*t-Math.PI/2))/2},easeInOutQuad:function(t){return t<.5?2*t*t:(4-2*t)*t-1},easeInOutCubic:function(t){return t<.5?4*t*t*t:(t-1)*(2*t-2)*(2*t-2)+1},easeOutCubic:function(t){return--t*t*t+1},easeOutQuad:function(t){return t*(2-t)}};return function(t,e,n,i){var a=new b(t,e,n,i);return a.componentDidMount(),function(){a.componentWillUnmount()}}});
//# sourceMappingURL=chartogram.js.map

@@ -49,4 +49,3 @@ "use strict";

_this.setState({
aspectRatio: _this.getCanvasAspectRatio(),
canvasWidthPx: _this.getCanvasWidthPx()
aspectRatio: _this.getCanvasAspectRatio()
}, false);

@@ -93,3 +92,12 @@ });

_defineProperty(this, "onChangeBounds", function (from, to) {
_this.setState(_this.createState(from, to), false);
var state = _this.createState(from, to);
var minY = state.minY;
var maxY = state.maxY;
delete state.minY;
delete state.maxY;
_this.setState(state, false);
_this.transitionState(minY, maxY);
});

@@ -142,13 +150,41 @@

ratio = EASING[transitionEasing](ratio);
var state = {};
_this.setState({
graphOpacity: graphOpacityTo.map(function (_, i) {
if (minYTo !== undefined) {
state.minY = minYFrom + (minYTo - minYFrom) * ratio;
state.maxY = maxYFrom + (maxYTo - maxYFrom) * ratio;
if (ratio === 1) {
state.minYFrom = undefined;
state.minYTo = undefined;
state.maxYFrom = undefined;
state.maxYTo = undefined;
}
}
if (minYGlobalTo !== undefined) {
state.minYGlobal = minYGlobalFrom + (minYGlobalTo - minYGlobalFrom) * ratio;
state.maxYGlobal = maxYGlobalFrom + (maxYGlobalTo - maxYGlobalFrom) * ratio;
if (ratio === 1) {
state.minYGlobalFrom = undefined;
state.minYGlobalTo = undefined;
state.maxYGlobalFrom = undefined;
state.maxYGlobalTo = undefined;
}
}
if (graphOpacityTo !== undefined) {
state.graphOpacity = graphOpacityTo.map(function (_, i) {
return graphOpacityFrom[i] + (graphOpacityTo[i] - graphOpacityFrom[i]) * ratio;
}),
minY: minYFrom + (minYTo - minYFrom) * ratio,
maxY: maxYFrom + (maxYTo - maxYFrom) * ratio,
minYGlobal: minYGlobalFrom + (minYGlobalTo - minYGlobalFrom) * ratio,
maxYGlobal: maxYGlobalFrom + (maxYGlobalTo - maxYGlobalFrom) * ratio
});
});
if (ratio === 1) {
state.graphOpacityFrom = undefined;
state.graphOpacityTo = undefined;
}
}
_this.setState(state);
if (ratio < 1) {

@@ -192,3 +228,3 @@ _this.transition = requestAnimationFrame(_this.transitionStateTick);

title: title,
transitionDuration: 300,
transitionDuration: 250,
transitionEasing: 'easeOutQuad',

@@ -245,2 +281,6 @@ gaugeTickMarksCount: 6,

window.removeEventListener('resize', this.onResizeThrottled);
if (this.transition) {
cancelAnimationFrame(this.transition);
}
}

@@ -254,8 +294,2 @@ }, {

}, {
key: "getCanvasWidthPx",
value: function getCanvasWidthPx() {
var canvasDimensions = this.canvas.getBoundingClientRect();
return canvasDimensions.width;
}
}, {
key: "setState",

@@ -305,3 +339,2 @@ value: function setState(newState) {

canvas: this.canvas,
canvasWidthPx: this.state.canvasWidthPx,
container: this.tooltipContainer,

@@ -342,3 +375,2 @@ pointsContainer: this.canvasWrapper,

aspectRatio: this.getCanvasAspectRatio(),
canvasWidthPx: this.getCanvasWidthPx(),
graphOpacity: this.data.y.map(function (_) {

@@ -591,22 +623,38 @@ return 1;

var heightBefore = this.state.maxY - this.state.minY;
var deltaMaxY = Math.abs(maxY - this.state.maxY) / heightBefore;
var deltaMinY = Math.abs(minY - this.state.minY) / heightBefore;
var deltaY = Math.max(deltaMinY, deltaMaxY);
var transitionDuration = maxTransitionDuration * Math.max(0.1, Math.min(deltaY, 0.5) * 2);
this.setState({
graphOpacityFrom: this.state.graphOpacity,
graphOpacityTo: graphOpacity,
minYFrom: this.state.minY,
maxYFrom: this.state.maxY,
minYTo: minY,
maxYTo: maxY,
minYGlobalFrom: this.state.minYGlobal,
maxYGlobalFrom: this.state.maxYGlobal,
minYGlobalTo: minYGlobal,
maxYGlobalTo: maxYGlobal,
var transitionDuration = maxTransitionDuration;
if (minY !== undefined) {
var heightBefore = this.state.maxY - this.state.minY;
var deltaMaxY = Math.abs(maxY - this.state.maxY) / heightBefore;
var deltaMinY = Math.abs(minY - this.state.minY) / heightBefore;
var deltaY = Math.max(deltaMinY, deltaMaxY);
transitionDuration = maxTransitionDuration * Math.max(0.2, Math.min(deltaY, 0.5) * 2);
}
var state = {
transitionStartedAt: Date.now(),
transitionDuration: transitionDuration
}); // Place in a `setState()` callback in case of React.
};
if (minY !== undefined) {
state.minYFrom = this.state.minY;
state.maxYFrom = this.state.maxY;
state.minYTo = minY;
state.maxYTo = maxY;
}
if (graphOpacity !== undefined) {
state.graphOpacityFrom = this.state.graphOpacity;
state.graphOpacityTo = graphOpacity;
}
if (minYGlobal !== undefined) {
state.minYGlobalFrom = this.state.minYGlobal;
state.maxYGlobalFrom = this.state.maxYGlobal;
state.minYGlobalTo = minYGlobal;
state.maxYGlobalTo = maxYGlobal;
}
this.setState(state); // Place in a `setState()` callback in case of React.
this.transition = requestAnimationFrame(this.transitionStateTick);

@@ -613,0 +661,0 @@ }

@@ -8,2 +8,4 @@ "use strict";

var _utility = require("./utility");
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

@@ -26,185 +28,88 @@

_defineProperty(this, "setUpListener", function () {
var canvas = _this.props.canvas;
(0, _utility.setUpTouchMove)(canvas, function () {}, _this.onTrack, function () {
return _this.unmount();
});
});
_defineProperty(this, "onTrack", function (screenX, screenY, canvasDimensions) {
var _this$props = _this.props,
canvas = _this$props.canvas,
canvasWidthPx = _this$props.canvasWidthPx,
weekdays = _this$props.weekdays,
months = _this$props.months;
var canvasDimensions;
var isIndexInBounds;
minX = _this$props.minX,
maxX = _this$props.maxX,
xPoints = _this$props.xPoints;
var xScreenRatio = (screenX - canvasDimensions.left) / canvasDimensions.width;
var xPoint = minX + xScreenRatio * (maxX - minX);
var xHigherIndex = xPoints.findIndex(function (_) {
return _ >= xPoint;
});
var xLowerIndex = xHigherIndex - 1;
var onTrack = function onTrack(screenX) {
var _this$props2 = _this.props,
minX = _this$props2.minX,
maxX = _this$props2.maxX,
xPoints = _this$props2.xPoints,
y = _this$props2.y;
var xScreenRatio = (screenX - canvasDimensions.left) / canvasDimensions.width;
var xPoint = minX + xScreenRatio * (maxX - minX);
var xHigherIndex = xPoints.findIndex(function (_) {
return _ >= xPoint;
});
var xLowerIndex = xHigherIndex - 1;
if (xHigherIndex < 0 || xHigherIndex >= xPoints.length) {
xHigherIndex = -1;
}
if (!isIndexInBounds(xHigherIndex)) {
xHigherIndex = -1;
}
if (xLowerIndex < 0 || xLowerIndex >= xPoints.length) {
xLowerIndex = -1;
}
if (!isIndexInBounds(xLowerIndex)) {
xLowerIndex = -1;
}
var xIndex;
var xIndex;
if (xHigherIndex < 0) {
if (xLowerIndex < 0) {
return _this.unmount();
} else {
xIndex = xLowerIndex;
}
if (xHigherIndex < 0) {
if (xLowerIndex < 0) {
return _this.unmount();
} else {
if (xLowerIndex < 0) {
xIndex = xHigherIndex;
} else {
var xLower = xPoints[xLowerIndex];
var xHigher = xPoints[xHigherIndex];
var deltaLower = xPoint - xLower;
var deltaHigher = xHigher - xPoint;
xIndex = deltaLower > deltaHigher ? xHigherIndex : xLowerIndex;
}
xIndex = xLowerIndex;
}
var x = xPoints[xIndex];
if (x !== _this.tooltipForX) {
_this.tooltipForX = x;
if (!_this.tooltip) {
_this.mount();
}
var date = new Date(x);
_this.tooltipDate.textContent = "".concat(weekdays[date.getDay()], ", ").concat(months[date.getMonth()], " ").concat(date.getDate());
var i = 0;
for (var _iterator = y, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
var _ref;
if (_isArray) {
if (_i >= _iterator.length) break;
_ref = _iterator[_i++];
} else {
_i = _iterator.next();
if (_i.done) break;
_ref = _i.value;
}
var _ref2 = _ref,
isShown = _ref2.isShown,
points = _ref2.points,
name = _ref2.name;
if (isShown) {
_this.tooltipValues.childNodes[2 * i].textContent = points[xIndex];
_this.tooltipValues.childNodes[2 * i + 1].textContent = name;
i++;
}
}
var xRatio = (x - minX) / (maxX - minX);
var left = xRatio * canvasWidthPx;
left -= 40;
var tooltipWidth = _this.tooltip.getBoundingClientRect().width;
var overflow = 5;
if (left < -1 * overflow) {
left = -1 * overflow;
} else if (left + tooltipWidth > canvasWidthPx + overflow) {
left = canvasWidthPx + overflow - tooltipWidth;
}
_this.tooltip.style.left = left + 'px';
_this.updatePoints(xIndex, xRatio);
_this.updateLine(x);
} else {
if (xLowerIndex < 0) {
xIndex = xHigherIndex;
} else {
var xLower = xPoints[xLowerIndex];
var xHigher = xPoints[xHigherIndex];
var deltaLower = xPoint - xLower;
var deltaHigher = xHigher - xPoint;
xIndex = deltaLower > deltaHigher ? xHigherIndex : xLowerIndex;
}
};
}
var onTrackStart = function onTrackStart() {
canvasDimensions = canvas.getBoundingClientRect();
var x = xPoints[xIndex];
isIndexInBounds = function isIndexInBounds(index) {
var xPoints = _this.props.xPoints;
return index >= 0 && index < xPoints.length;
};
};
if (x !== _this.tooltipForX) {
_this.tooltipForX = x;
var onTouchStart = function onTouchStart(event) {
// Ignore multitouch.
if (event.touches.length > 1) {
// Reset.
return onTrackStop();
if (!_this.tooltip) {
_this.mount();
}
onTrackStart();
canvas.addEventListener('touchend', onTrackStop);
canvas.addEventListener('touchmove', onTouchMove);
canvas.addEventListener('touchend', onTrackStop);
canvas.addEventListener('touchcancel', onTrackStop);
onTouchMove(event);
}; // Safari doesn't support pointer events.
// https://caniuse.com/#feat=pointer
_this.updateTooltip(x, xIndex, canvasDimensions.width);
}
});
_defineProperty(this, "unmountLine", function () {
var canvas = _this.props.canvas;
canvas.removeChild(_this.line);
_this.line = undefined;
});
canvas.addEventListener('touchstart', onTouchStart);
_defineProperty(this, "mountPoints", function () {
var pointsContainer = _this.props.pointsContainer;
_this.points = _this.renderPoints();
function onTouchMove(event) {
var x = event.changedTouches[0].clientX;
var y = event.changedTouches[0].clientY; // Emulate 'pointerleave' behavior.
for (var _iterator = _this.points, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
var _ref;
if (x < canvasDimensions.left || x > canvasDimensions.left + canvasDimensions.width || y < canvasDimensions.top || y > canvasDimensions.top + canvasDimensions.height) {
onTrackStop();
if (_isArray) {
if (_i >= _iterator.length) break;
_ref = _iterator[_i++];
} else {
onTrack(x, y);
_i = _iterator.next();
if (_i.done) break;
_ref = _i.value;
}
}
function onPointerMove(event) {
onTrack(event.clientX, event.clientY);
var point = _ref;
pointsContainer.appendChild(point);
}
var onTrackStop = function onTrackStop() {
canvas.removeEventListener('pointermove', onPointerMove);
canvas.removeEventListener('pointerleave', onTrackStop);
canvas.removeEventListener('pointercancel', onTrackStop);
canvas.removeEventListener('touchmove', onTouchMove);
canvas.removeEventListener('touchend', onTrackStop);
canvas.removeEventListener('touchcancel', onTrackStop);
_this.unmount();
};
var onPointerEnter = function onPointerEnter() {
onTrackStart();
canvas.addEventListener('pointermove', onPointerMove);
canvas.addEventListener('pointerleave', onTrackStop);
canvas.addEventListener('pointercancel', onTrackStop);
};
canvas.addEventListener('pointerenter', onPointerEnter);
return function () {
onTrackStop();
canvas.removeEventListener(onPointerEnter);
canvas.removeEventListener(onTouchStart);
};
});
_defineProperty(this, "unmountLine", function () {
var canvas = _this.props.canvas;
canvas.removeChild(_this.line);
_this.line = undefined;
});
_defineProperty(this, "unmountPoints", function () {

@@ -214,14 +119,14 @@ var pointsContainer = _this.props.pointsContainer;

for (var _iterator2 = _this.points, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
var _ref3;
var _ref2;
if (_isArray2) {
if (_i2 >= _iterator2.length) break;
_ref3 = _iterator2[_i2++];
_ref2 = _iterator2[_i2++];
} else {
_i2 = _iterator2.next();
if (_i2.done) break;
_ref3 = _i2.value;
_ref2 = _i2.value;
}
var point = _ref3;
var point = _ref2;
pointsContainer.removeChild(point);

@@ -233,12 +138,12 @@ }

_defineProperty(this, "updateLine", function (x) {
_defineProperty(this, "updateLinePosition", function (x) {
if (!_this.isLineRendered()) {
_this.renderLine();
_this.mountLine();
}
var _this$props3 = _this.props,
canvasWidth = _this$props3.canvasWidth,
aspectRatio = _this$props3.aspectRatio,
fixSvgCoordinate = _this$props3.fixSvgCoordinate,
mapX = _this$props3.mapX;
var _this$props2 = _this.props,
canvasWidth = _this$props2.canvasWidth,
aspectRatio = _this$props2.aspectRatio,
fixSvgCoordinate = _this$props2.fixSvgCoordinate,
mapX = _this$props2.mapX;

@@ -254,6 +159,6 @@ _this.line.setAttributeNS(null, 'x1', fixSvgCoordinate(mapX(x)));

_defineProperty(this, "updatePoints", function (xIndex, xRatio) {
var _this$props4 = _this.props,
maxY = _this$props4.maxY,
y = _this$props4.y;
_defineProperty(this, "updatePointPositions", function (xIndex, xRatio) {
var _this$props3 = _this.props,
maxY = _this$props3.maxY,
y = _this$props3.y;
var i = 0;

@@ -300,43 +205,66 @@ var j = 0;

value: function mount() {
this.renderTooltip();
this.renderPoints();
var container = this.props.container;
this.tooltip = this.renderTooltip();
container.appendChild(this.tooltip);
this.mountPoints();
if (!this.isLineRendered()) {
this.renderLine();
this.mountLine();
}
}
}, {
key: "unmount",
value: function unmount() {
if (!this.tooltip) {
return;
}
var container = this.props.container;
this.tooltipForX = undefined;
container.removeChild(this.tooltip);
this.tooltip = undefined;
this.unmountPoints();
if (this.isLineRendered()) {
this.unmountLine();
}
}
}, {
key: "mountLine",
value: function mountLine() {
var canvas = this.props.canvas;
this.line = this.renderLine();
canvas.insertBefore(this.line, canvas.querySelector('polyline'));
}
}, {
key: "renderTooltip",
value: function renderTooltip() {
var _this$props5 = this.props,
y = _this$props5.y,
container = _this$props5.container; // Create tooltip.
var y = this.props.y; // Create tooltip.
this.tooltip = document.createElement('div');
this.tooltip.classList.add('chartogram__tooltip');
container.appendChild(this.tooltip); // Add tooltip title.
var tooltip = document.createElement('div');
tooltip.classList.add('chartogram__tooltip'); // Add tooltip title.
this.tooltipDate = document.createElement('h1');
this.tooltipDate.classList.add('chartogram__tooltip-header');
this.tooltip.appendChild(this.tooltipDate); // Add graph values.
var tooltipDate = document.createElement('h1');
tooltipDate.classList.add('chartogram__tooltip-header');
tooltip.appendChild(tooltipDate); // Add graph values.
this.tooltipValues = document.createElement('dl');
this.tooltipValues.classList.add('chartogram__tooltip-values');
this.tooltip.appendChild(this.tooltipValues); // Add graph values.
var tooltipValues = document.createElement('dl');
tooltipValues.classList.add('chartogram__tooltip-values');
tooltip.appendChild(tooltipValues); // Add graph values.
for (var _iterator3 = y, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
var _ref4;
var _ref3;
if (_isArray3) {
if (_i3 >= _iterator3.length) break;
_ref4 = _iterator3[_i3++];
_ref3 = _iterator3[_i3++];
} else {
_i3 = _iterator3.next();
if (_i3.done) break;
_ref4 = _i3.value;
_ref3 = _i3.value;
}
var _ref5 = _ref4,
isShown = _ref5.isShown,
color = _ref5.color;
var _ref4 = _ref3,
isShown = _ref4.isShown,
color = _ref4.color;

@@ -347,9 +275,11 @@ if (isShown) {

tooltipValue.style.color = color;
this.tooltipValues.appendChild(tooltipValue); // Add graph name.
tooltipValues.appendChild(tooltipValue); // Add graph name.
var tooltipName = document.createElement('dd');
tooltipName.style.color = color;
this.tooltipValues.appendChild(tooltipName);
tooltipValues.appendChild(tooltipName);
}
}
return tooltip;
}

@@ -359,24 +289,8 @@ }, {

value: function renderLine() {
var canvas = this.props.canvas;
var xmlns = 'http://www.w3.org/2000/svg';
this.line = document.createElementNS(xmlns, 'line');
this.line.setAttribute('class', 'chartogram__tooltip-line');
canvas.insertBefore(this.line, canvas.querySelector('polyline'));
var line = document.createElementNS(xmlns, 'line');
line.setAttribute('class', 'chartogram__tooltip-line');
return line;
}
}, {
key: "unmount",
value: function unmount() {
if (this.tooltip) {
var container = this.props.container;
this.tooltipForX = undefined;
container.removeChild(this.tooltip);
this.tooltip = undefined;
this.unmountPoints();
if (this.isLineRendered()) {
this.unmountLine();
}
}
}
}, {
key: "isLineRendered",

@@ -390,20 +304,20 @@ value: function isLineRendered() {

value: function renderPoints() {
this.points = [];
var _this$props6 = this.props,
pointsContainer = _this$props6.pointsContainer,
y = _this$props6.y;
var points = [];
var _this$props4 = this.props,
pointsContainer = _this$props4.pointsContainer,
y = _this$props4.y;
for (var _iterator4 = y, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
var _ref6;
var _ref5;
if (_isArray4) {
if (_i4 >= _iterator4.length) break;
_ref6 = _iterator4[_i4++];
_ref5 = _iterator4[_i4++];
} else {
_i4 = _iterator4.next();
if (_i4.done) break;
_ref6 = _i4.value;
_ref5 = _i4.value;
}
var _y = _ref6;
var _y = _ref5;

@@ -414,7 +328,81 @@ if (_y.isShown) {

point.style.color = _y.color;
this.points.push(point);
points.push(point);
pointsContainer.appendChild(point);
}
}
return points;
}
}, {
key: "updateTooltip",
value: function updateTooltip(x, xIndex, canvasWidth) {
var _this$props5 = this.props,
minX = _this$props5.minX,
maxX = _this$props5.maxX;
var xRatio = (x - minX) / (maxX - minX);
this.updateTooltipDate(new Date(x));
this.updateTooltipValues(xIndex);
this.updateTooltipPosition(xRatio, canvasWidth);
this.updatePointPositions(xIndex, xRatio);
this.updateLinePosition(x);
}
}, {
key: "updateTooltipPosition",
value: function updateTooltipPosition(xRatio, canvasWidth) {
var _this$props6 = this.props,
tooltipShift = _this$props6.tooltipShift,
maxOverflow = _this$props6.maxOverflow;
var left = xRatio * canvasWidth;
left -= tooltipShift === undefined ? 40 : tooltipShift;
var tooltipWidth = this.tooltip.getBoundingClientRect().width;
var overflow = maxOverflow === undefined ? 5 : maxOverflow;
if (left < -1 * overflow) {
left = -1 * overflow;
} else if (left + tooltipWidth > canvasWidth + overflow) {
left = canvasWidth + overflow - tooltipWidth;
}
this.tooltip.style.left = left + 'px';
}
}, {
key: "updateTooltipDate",
value: function updateTooltipDate(date) {
var _this$props7 = this.props,
weekdays = _this$props7.weekdays,
months = _this$props7.months;
var tooltipDate = this.tooltip.childNodes[0];
tooltipDate.textContent = "".concat(weekdays[date.getDay()], ", ").concat(months[date.getMonth()], " ").concat(date.getDate());
}
}, {
key: "updateTooltipValues",
value: function updateTooltipValues(xIndex) {
var y = this.props.y;
var tooltipValues = this.tooltip.childNodes[1];
var i = 0;
for (var _iterator5 = y, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {
var _ref6;
if (_isArray5) {
if (_i5 >= _iterator5.length) break;
_ref6 = _iterator5[_i5++];
} else {
_i5 = _iterator5.next();
if (_i5.done) break;
_ref6 = _i5.value;
}
var _ref7 = _ref6,
isShown = _ref7.isShown,
points = _ref7.points,
name = _ref7.name;
if (isShown) {
tooltipValues.childNodes[2 * i].textContent = points[xIndex];
tooltipValues.childNodes[2 * i + 1].textContent = name;
i++;
}
}
}
}]);

@@ -421,0 +409,0 @@

@@ -14,2 +14,3 @@ "use strict";

exports.setUpDrag = setUpDrag;
exports.setUpTouchMove = setUpTouchMove;

@@ -210,2 +211,75 @@ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }

}
function setUpTouchMove(element, _onTrackStart, _onTrack, _onTrackStop) {
var elementBounds;
function onTrack(x, y) {
_onTrack(x, y, elementBounds);
}
function onTrackStart() {
elementBounds = element.getBoundingClientRect();
_onTrackStart();
}
function onTouchStart(event) {
// Ignore multitouch.
if (event.touches.length > 1) {
// Reset.
return onTrackStop();
}
onTrackStart();
element.addEventListener('touchend', onTrackStop);
element.addEventListener('touchmove', onTouchMove);
element.addEventListener('touchend', onTrackStop);
element.addEventListener('touchcancel', onTrackStop);
onTouchMove(event);
} // Safari doesn't support pointer events.
// https://caniuse.com/#feat=pointer
element.addEventListener('touchstart', onTouchStart);
function onTouchMove(event) {
var x = event.changedTouches[0].clientX;
var y = event.changedTouches[0].clientY; // Emulate 'pointerleave' behavior.
if (x < elementBounds.left || x > elementBounds.left + elementBounds.width || y < elementBounds.top || y > elementBounds.top + elementBounds.height) {
onTrackStop();
} else {
onTrack(x, y);
}
}
function onPointerMove(event) {
onTrack(event.clientX, event.clientY);
}
function onTrackStop() {
element.removeEventListener('pointermove', onPointerMove);
element.removeEventListener('pointerleave', onTrackStop);
element.removeEventListener('pointercancel', onTrackStop);
element.removeEventListener('touchmove', onTouchMove);
element.removeEventListener('touchend', onTrackStop);
element.removeEventListener('touchcancel', onTrackStop);
_onTrackStop();
}
function onPointerEnter() {
onTrackStart();
element.addEventListener('pointermove', onPointerMove);
element.addEventListener('pointerleave', onTrackStop);
element.addEventListener('pointercancel', onTrackStop);
}
element.addEventListener('pointerenter', onPointerEnter);
return function () {
onTrackStop();
element.removeEventListener(onPointerEnter);
element.removeEventListener(onTouchStart);
};
}
//# sourceMappingURL=utility.js.map

@@ -37,4 +37,3 @@ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }

_this.setState({
aspectRatio: _this.getCanvasAspectRatio(),
canvasWidthPx: _this.getCanvasWidthPx()
aspectRatio: _this.getCanvasAspectRatio()
}, false);

@@ -81,3 +80,12 @@ });

_defineProperty(this, "onChangeBounds", function (from, to) {
_this.setState(_this.createState(from, to), false);
var state = _this.createState(from, to);
var minY = state.minY;
var maxY = state.maxY;
delete state.minY;
delete state.maxY;
_this.setState(state, false);
_this.transitionState(minY, maxY);
});

@@ -130,13 +138,41 @@

ratio = EASING[transitionEasing](ratio);
var state = {};
_this.setState({
graphOpacity: graphOpacityTo.map(function (_, i) {
if (minYTo !== undefined) {
state.minY = minYFrom + (minYTo - minYFrom) * ratio;
state.maxY = maxYFrom + (maxYTo - maxYFrom) * ratio;
if (ratio === 1) {
state.minYFrom = undefined;
state.minYTo = undefined;
state.maxYFrom = undefined;
state.maxYTo = undefined;
}
}
if (minYGlobalTo !== undefined) {
state.minYGlobal = minYGlobalFrom + (minYGlobalTo - minYGlobalFrom) * ratio;
state.maxYGlobal = maxYGlobalFrom + (maxYGlobalTo - maxYGlobalFrom) * ratio;
if (ratio === 1) {
state.minYGlobalFrom = undefined;
state.minYGlobalTo = undefined;
state.maxYGlobalFrom = undefined;
state.maxYGlobalTo = undefined;
}
}
if (graphOpacityTo !== undefined) {
state.graphOpacity = graphOpacityTo.map(function (_, i) {
return graphOpacityFrom[i] + (graphOpacityTo[i] - graphOpacityFrom[i]) * ratio;
}),
minY: minYFrom + (minYTo - minYFrom) * ratio,
maxY: maxYFrom + (maxYTo - maxYFrom) * ratio,
minYGlobal: minYGlobalFrom + (minYGlobalTo - minYGlobalFrom) * ratio,
maxYGlobal: maxYGlobalFrom + (maxYGlobalTo - maxYGlobalFrom) * ratio
});
});
if (ratio === 1) {
state.graphOpacityFrom = undefined;
state.graphOpacityTo = undefined;
}
}
_this.setState(state);
if (ratio < 1) {

@@ -180,3 +216,3 @@ _this.transition = requestAnimationFrame(_this.transitionStateTick);

title: title,
transitionDuration: 300,
transitionDuration: 250,
transitionEasing: 'easeOutQuad',

@@ -233,2 +269,6 @@ gaugeTickMarksCount: 6,

window.removeEventListener('resize', this.onResizeThrottled);
if (this.transition) {
cancelAnimationFrame(this.transition);
}
}

@@ -242,8 +282,2 @@ }, {

}, {
key: "getCanvasWidthPx",
value: function getCanvasWidthPx() {
var canvasDimensions = this.canvas.getBoundingClientRect();
return canvasDimensions.width;
}
}, {
key: "setState",

@@ -293,3 +327,2 @@ value: function setState(newState) {

canvas: this.canvas,
canvasWidthPx: this.state.canvasWidthPx,
container: this.tooltipContainer,

@@ -330,3 +363,2 @@ pointsContainer: this.canvasWrapper,

aspectRatio: this.getCanvasAspectRatio(),
canvasWidthPx: this.getCanvasWidthPx(),
graphOpacity: this.data.y.map(function (_) {

@@ -579,22 +611,38 @@ return 1;

var heightBefore = this.state.maxY - this.state.minY;
var deltaMaxY = Math.abs(maxY - this.state.maxY) / heightBefore;
var deltaMinY = Math.abs(minY - this.state.minY) / heightBefore;
var deltaY = Math.max(deltaMinY, deltaMaxY);
var transitionDuration = maxTransitionDuration * Math.max(0.1, Math.min(deltaY, 0.5) * 2);
this.setState({
graphOpacityFrom: this.state.graphOpacity,
graphOpacityTo: graphOpacity,
minYFrom: this.state.minY,
maxYFrom: this.state.maxY,
minYTo: minY,
maxYTo: maxY,
minYGlobalFrom: this.state.minYGlobal,
maxYGlobalFrom: this.state.maxYGlobal,
minYGlobalTo: minYGlobal,
maxYGlobalTo: maxYGlobal,
var transitionDuration = maxTransitionDuration;
if (minY !== undefined) {
var heightBefore = this.state.maxY - this.state.minY;
var deltaMaxY = Math.abs(maxY - this.state.maxY) / heightBefore;
var deltaMinY = Math.abs(minY - this.state.minY) / heightBefore;
var deltaY = Math.max(deltaMinY, deltaMaxY);
transitionDuration = maxTransitionDuration * Math.max(0.2, Math.min(deltaY, 0.5) * 2);
}
var state = {
transitionStartedAt: Date.now(),
transitionDuration: transitionDuration
}); // Place in a `setState()` callback in case of React.
};
if (minY !== undefined) {
state.minYFrom = this.state.minY;
state.maxYFrom = this.state.maxY;
state.minYTo = minY;
state.maxYTo = maxY;
}
if (graphOpacity !== undefined) {
state.graphOpacityFrom = this.state.graphOpacity;
state.graphOpacityTo = graphOpacity;
}
if (minYGlobal !== undefined) {
state.minYGlobalFrom = this.state.minYGlobal;
state.maxYGlobalFrom = this.state.maxYGlobal;
state.minYGlobalTo = minYGlobal;
state.maxYGlobalTo = maxYGlobal;
}
this.setState(state); // Place in a `setState()` callback in case of React.
this.transition = requestAnimationFrame(this.transitionStateTick);

@@ -601,0 +649,0 @@ }

@@ -9,2 +9,4 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

import { setUpTouchMove } from './utility';
var Tooltip =

@@ -19,185 +21,88 @@ /*#__PURE__*/

_defineProperty(this, "setUpListener", function () {
var canvas = _this.props.canvas;
setUpTouchMove(canvas, function () {}, _this.onTrack, function () {
return _this.unmount();
});
});
_defineProperty(this, "onTrack", function (screenX, screenY, canvasDimensions) {
var _this$props = _this.props,
canvas = _this$props.canvas,
canvasWidthPx = _this$props.canvasWidthPx,
weekdays = _this$props.weekdays,
months = _this$props.months;
var canvasDimensions;
var isIndexInBounds;
minX = _this$props.minX,
maxX = _this$props.maxX,
xPoints = _this$props.xPoints;
var xScreenRatio = (screenX - canvasDimensions.left) / canvasDimensions.width;
var xPoint = minX + xScreenRatio * (maxX - minX);
var xHigherIndex = xPoints.findIndex(function (_) {
return _ >= xPoint;
});
var xLowerIndex = xHigherIndex - 1;
var onTrack = function onTrack(screenX) {
var _this$props2 = _this.props,
minX = _this$props2.minX,
maxX = _this$props2.maxX,
xPoints = _this$props2.xPoints,
y = _this$props2.y;
var xScreenRatio = (screenX - canvasDimensions.left) / canvasDimensions.width;
var xPoint = minX + xScreenRatio * (maxX - minX);
var xHigherIndex = xPoints.findIndex(function (_) {
return _ >= xPoint;
});
var xLowerIndex = xHigherIndex - 1;
if (xHigherIndex < 0 || xHigherIndex >= xPoints.length) {
xHigherIndex = -1;
}
if (!isIndexInBounds(xHigherIndex)) {
xHigherIndex = -1;
}
if (xLowerIndex < 0 || xLowerIndex >= xPoints.length) {
xLowerIndex = -1;
}
if (!isIndexInBounds(xLowerIndex)) {
xLowerIndex = -1;
}
var xIndex;
var xIndex;
if (xHigherIndex < 0) {
if (xLowerIndex < 0) {
return _this.unmount();
} else {
xIndex = xLowerIndex;
}
if (xHigherIndex < 0) {
if (xLowerIndex < 0) {
return _this.unmount();
} else {
if (xLowerIndex < 0) {
xIndex = xHigherIndex;
} else {
var xLower = xPoints[xLowerIndex];
var xHigher = xPoints[xHigherIndex];
var deltaLower = xPoint - xLower;
var deltaHigher = xHigher - xPoint;
xIndex = deltaLower > deltaHigher ? xHigherIndex : xLowerIndex;
}
xIndex = xLowerIndex;
}
var x = xPoints[xIndex];
if (x !== _this.tooltipForX) {
_this.tooltipForX = x;
if (!_this.tooltip) {
_this.mount();
}
var date = new Date(x);
_this.tooltipDate.textContent = "".concat(weekdays[date.getDay()], ", ").concat(months[date.getMonth()], " ").concat(date.getDate());
var i = 0;
for (var _iterator = y, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
var _ref;
if (_isArray) {
if (_i >= _iterator.length) break;
_ref = _iterator[_i++];
} else {
_i = _iterator.next();
if (_i.done) break;
_ref = _i.value;
}
var _ref2 = _ref,
isShown = _ref2.isShown,
points = _ref2.points,
name = _ref2.name;
if (isShown) {
_this.tooltipValues.childNodes[2 * i].textContent = points[xIndex];
_this.tooltipValues.childNodes[2 * i + 1].textContent = name;
i++;
}
}
var xRatio = (x - minX) / (maxX - minX);
var left = xRatio * canvasWidthPx;
left -= 40;
var tooltipWidth = _this.tooltip.getBoundingClientRect().width;
var overflow = 5;
if (left < -1 * overflow) {
left = -1 * overflow;
} else if (left + tooltipWidth > canvasWidthPx + overflow) {
left = canvasWidthPx + overflow - tooltipWidth;
}
_this.tooltip.style.left = left + 'px';
_this.updatePoints(xIndex, xRatio);
_this.updateLine(x);
} else {
if (xLowerIndex < 0) {
xIndex = xHigherIndex;
} else {
var xLower = xPoints[xLowerIndex];
var xHigher = xPoints[xHigherIndex];
var deltaLower = xPoint - xLower;
var deltaHigher = xHigher - xPoint;
xIndex = deltaLower > deltaHigher ? xHigherIndex : xLowerIndex;
}
};
}
var onTrackStart = function onTrackStart() {
canvasDimensions = canvas.getBoundingClientRect();
var x = xPoints[xIndex];
isIndexInBounds = function isIndexInBounds(index) {
var xPoints = _this.props.xPoints;
return index >= 0 && index < xPoints.length;
};
};
if (x !== _this.tooltipForX) {
_this.tooltipForX = x;
var onTouchStart = function onTouchStart(event) {
// Ignore multitouch.
if (event.touches.length > 1) {
// Reset.
return onTrackStop();
if (!_this.tooltip) {
_this.mount();
}
onTrackStart();
canvas.addEventListener('touchend', onTrackStop);
canvas.addEventListener('touchmove', onTouchMove);
canvas.addEventListener('touchend', onTrackStop);
canvas.addEventListener('touchcancel', onTrackStop);
onTouchMove(event);
}; // Safari doesn't support pointer events.
// https://caniuse.com/#feat=pointer
_this.updateTooltip(x, xIndex, canvasDimensions.width);
}
});
_defineProperty(this, "unmountLine", function () {
var canvas = _this.props.canvas;
canvas.removeChild(_this.line);
_this.line = undefined;
});
canvas.addEventListener('touchstart', onTouchStart);
_defineProperty(this, "mountPoints", function () {
var pointsContainer = _this.props.pointsContainer;
_this.points = _this.renderPoints();
function onTouchMove(event) {
var x = event.changedTouches[0].clientX;
var y = event.changedTouches[0].clientY; // Emulate 'pointerleave' behavior.
for (var _iterator = _this.points, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
var _ref;
if (x < canvasDimensions.left || x > canvasDimensions.left + canvasDimensions.width || y < canvasDimensions.top || y > canvasDimensions.top + canvasDimensions.height) {
onTrackStop();
if (_isArray) {
if (_i >= _iterator.length) break;
_ref = _iterator[_i++];
} else {
onTrack(x, y);
_i = _iterator.next();
if (_i.done) break;
_ref = _i.value;
}
}
function onPointerMove(event) {
onTrack(event.clientX, event.clientY);
var point = _ref;
pointsContainer.appendChild(point);
}
var onTrackStop = function onTrackStop() {
canvas.removeEventListener('pointermove', onPointerMove);
canvas.removeEventListener('pointerleave', onTrackStop);
canvas.removeEventListener('pointercancel', onTrackStop);
canvas.removeEventListener('touchmove', onTouchMove);
canvas.removeEventListener('touchend', onTrackStop);
canvas.removeEventListener('touchcancel', onTrackStop);
_this.unmount();
};
var onPointerEnter = function onPointerEnter() {
onTrackStart();
canvas.addEventListener('pointermove', onPointerMove);
canvas.addEventListener('pointerleave', onTrackStop);
canvas.addEventListener('pointercancel', onTrackStop);
};
canvas.addEventListener('pointerenter', onPointerEnter);
return function () {
onTrackStop();
canvas.removeEventListener(onPointerEnter);
canvas.removeEventListener(onTouchStart);
};
});
_defineProperty(this, "unmountLine", function () {
var canvas = _this.props.canvas;
canvas.removeChild(_this.line);
_this.line = undefined;
});
_defineProperty(this, "unmountPoints", function () {

@@ -207,14 +112,14 @@ var pointsContainer = _this.props.pointsContainer;

for (var _iterator2 = _this.points, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
var _ref3;
var _ref2;
if (_isArray2) {
if (_i2 >= _iterator2.length) break;
_ref3 = _iterator2[_i2++];
_ref2 = _iterator2[_i2++];
} else {
_i2 = _iterator2.next();
if (_i2.done) break;
_ref3 = _i2.value;
_ref2 = _i2.value;
}
var point = _ref3;
var point = _ref2;
pointsContainer.removeChild(point);

@@ -226,12 +131,12 @@ }

_defineProperty(this, "updateLine", function (x) {
_defineProperty(this, "updateLinePosition", function (x) {
if (!_this.isLineRendered()) {
_this.renderLine();
_this.mountLine();
}
var _this$props3 = _this.props,
canvasWidth = _this$props3.canvasWidth,
aspectRatio = _this$props3.aspectRatio,
fixSvgCoordinate = _this$props3.fixSvgCoordinate,
mapX = _this$props3.mapX;
var _this$props2 = _this.props,
canvasWidth = _this$props2.canvasWidth,
aspectRatio = _this$props2.aspectRatio,
fixSvgCoordinate = _this$props2.fixSvgCoordinate,
mapX = _this$props2.mapX;

@@ -247,6 +152,6 @@ _this.line.setAttributeNS(null, 'x1', fixSvgCoordinate(mapX(x)));

_defineProperty(this, "updatePoints", function (xIndex, xRatio) {
var _this$props4 = _this.props,
maxY = _this$props4.maxY,
y = _this$props4.y;
_defineProperty(this, "updatePointPositions", function (xIndex, xRatio) {
var _this$props3 = _this.props,
maxY = _this$props3.maxY,
y = _this$props3.y;
var i = 0;

@@ -293,43 +198,66 @@ var j = 0;

value: function mount() {
this.renderTooltip();
this.renderPoints();
var container = this.props.container;
this.tooltip = this.renderTooltip();
container.appendChild(this.tooltip);
this.mountPoints();
if (!this.isLineRendered()) {
this.renderLine();
this.mountLine();
}
}
}, {
key: "unmount",
value: function unmount() {
if (!this.tooltip) {
return;
}
var container = this.props.container;
this.tooltipForX = undefined;
container.removeChild(this.tooltip);
this.tooltip = undefined;
this.unmountPoints();
if (this.isLineRendered()) {
this.unmountLine();
}
}
}, {
key: "mountLine",
value: function mountLine() {
var canvas = this.props.canvas;
this.line = this.renderLine();
canvas.insertBefore(this.line, canvas.querySelector('polyline'));
}
}, {
key: "renderTooltip",
value: function renderTooltip() {
var _this$props5 = this.props,
y = _this$props5.y,
container = _this$props5.container; // Create tooltip.
var y = this.props.y; // Create tooltip.
this.tooltip = document.createElement('div');
this.tooltip.classList.add('chartogram__tooltip');
container.appendChild(this.tooltip); // Add tooltip title.
var tooltip = document.createElement('div');
tooltip.classList.add('chartogram__tooltip'); // Add tooltip title.
this.tooltipDate = document.createElement('h1');
this.tooltipDate.classList.add('chartogram__tooltip-header');
this.tooltip.appendChild(this.tooltipDate); // Add graph values.
var tooltipDate = document.createElement('h1');
tooltipDate.classList.add('chartogram__tooltip-header');
tooltip.appendChild(tooltipDate); // Add graph values.
this.tooltipValues = document.createElement('dl');
this.tooltipValues.classList.add('chartogram__tooltip-values');
this.tooltip.appendChild(this.tooltipValues); // Add graph values.
var tooltipValues = document.createElement('dl');
tooltipValues.classList.add('chartogram__tooltip-values');
tooltip.appendChild(tooltipValues); // Add graph values.
for (var _iterator3 = y, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
var _ref4;
var _ref3;
if (_isArray3) {
if (_i3 >= _iterator3.length) break;
_ref4 = _iterator3[_i3++];
_ref3 = _iterator3[_i3++];
} else {
_i3 = _iterator3.next();
if (_i3.done) break;
_ref4 = _i3.value;
_ref3 = _i3.value;
}
var _ref5 = _ref4,
isShown = _ref5.isShown,
color = _ref5.color;
var _ref4 = _ref3,
isShown = _ref4.isShown,
color = _ref4.color;

@@ -340,9 +268,11 @@ if (isShown) {

tooltipValue.style.color = color;
this.tooltipValues.appendChild(tooltipValue); // Add graph name.
tooltipValues.appendChild(tooltipValue); // Add graph name.
var tooltipName = document.createElement('dd');
tooltipName.style.color = color;
this.tooltipValues.appendChild(tooltipName);
tooltipValues.appendChild(tooltipName);
}
}
return tooltip;
}

@@ -352,24 +282,8 @@ }, {

value: function renderLine() {
var canvas = this.props.canvas;
var xmlns = 'http://www.w3.org/2000/svg';
this.line = document.createElementNS(xmlns, 'line');
this.line.setAttribute('class', 'chartogram__tooltip-line');
canvas.insertBefore(this.line, canvas.querySelector('polyline'));
var line = document.createElementNS(xmlns, 'line');
line.setAttribute('class', 'chartogram__tooltip-line');
return line;
}
}, {
key: "unmount",
value: function unmount() {
if (this.tooltip) {
var container = this.props.container;
this.tooltipForX = undefined;
container.removeChild(this.tooltip);
this.tooltip = undefined;
this.unmountPoints();
if (this.isLineRendered()) {
this.unmountLine();
}
}
}
}, {
key: "isLineRendered",

@@ -383,20 +297,20 @@ value: function isLineRendered() {

value: function renderPoints() {
this.points = [];
var _this$props6 = this.props,
pointsContainer = _this$props6.pointsContainer,
y = _this$props6.y;
var points = [];
var _this$props4 = this.props,
pointsContainer = _this$props4.pointsContainer,
y = _this$props4.y;
for (var _iterator4 = y, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
var _ref6;
var _ref5;
if (_isArray4) {
if (_i4 >= _iterator4.length) break;
_ref6 = _iterator4[_i4++];
_ref5 = _iterator4[_i4++];
} else {
_i4 = _iterator4.next();
if (_i4.done) break;
_ref6 = _i4.value;
_ref5 = _i4.value;
}
var _y = _ref6;
var _y = _ref5;

@@ -407,7 +321,81 @@ if (_y.isShown) {

point.style.color = _y.color;
this.points.push(point);
points.push(point);
pointsContainer.appendChild(point);
}
}
return points;
}
}, {
key: "updateTooltip",
value: function updateTooltip(x, xIndex, canvasWidth) {
var _this$props5 = this.props,
minX = _this$props5.minX,
maxX = _this$props5.maxX;
var xRatio = (x - minX) / (maxX - minX);
this.updateTooltipDate(new Date(x));
this.updateTooltipValues(xIndex);
this.updateTooltipPosition(xRatio, canvasWidth);
this.updatePointPositions(xIndex, xRatio);
this.updateLinePosition(x);
}
}, {
key: "updateTooltipPosition",
value: function updateTooltipPosition(xRatio, canvasWidth) {
var _this$props6 = this.props,
tooltipShift = _this$props6.tooltipShift,
maxOverflow = _this$props6.maxOverflow;
var left = xRatio * canvasWidth;
left -= tooltipShift === undefined ? 40 : tooltipShift;
var tooltipWidth = this.tooltip.getBoundingClientRect().width;
var overflow = maxOverflow === undefined ? 5 : maxOverflow;
if (left < -1 * overflow) {
left = -1 * overflow;
} else if (left + tooltipWidth > canvasWidth + overflow) {
left = canvasWidth + overflow - tooltipWidth;
}
this.tooltip.style.left = left + 'px';
}
}, {
key: "updateTooltipDate",
value: function updateTooltipDate(date) {
var _this$props7 = this.props,
weekdays = _this$props7.weekdays,
months = _this$props7.months;
var tooltipDate = this.tooltip.childNodes[0];
tooltipDate.textContent = "".concat(weekdays[date.getDay()], ", ").concat(months[date.getMonth()], " ").concat(date.getDate());
}
}, {
key: "updateTooltipValues",
value: function updateTooltipValues(xIndex) {
var y = this.props.y;
var tooltipValues = this.tooltip.childNodes[1];
var i = 0;
for (var _iterator5 = y, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {
var _ref6;
if (_isArray5) {
if (_i5 >= _iterator5.length) break;
_ref6 = _iterator5[_i5++];
} else {
_i5 = _iterator5.next();
if (_i5.done) break;
_ref6 = _i5.value;
}
var _ref7 = _ref6,
isShown = _ref7.isShown,
points = _ref7.points,
name = _ref7.name;
if (isShown) {
tooltipValues.childNodes[2 * i].textContent = points[xIndex];
tooltipValues.childNodes[2 * i + 1].textContent = name;
i++;
}
}
}
}]);

@@ -414,0 +402,0 @@

@@ -188,2 +188,74 @@ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }

}
export function setUpTouchMove(element, _onTrackStart, _onTrack, _onTrackStop) {
var elementBounds;
function onTrack(x, y) {
_onTrack(x, y, elementBounds);
}
function onTrackStart() {
elementBounds = element.getBoundingClientRect();
_onTrackStart();
}
function onTouchStart(event) {
// Ignore multitouch.
if (event.touches.length > 1) {
// Reset.
return onTrackStop();
}
onTrackStart();
element.addEventListener('touchend', onTrackStop);
element.addEventListener('touchmove', onTouchMove);
element.addEventListener('touchend', onTrackStop);
element.addEventListener('touchcancel', onTrackStop);
onTouchMove(event);
} // Safari doesn't support pointer events.
// https://caniuse.com/#feat=pointer
element.addEventListener('touchstart', onTouchStart);
function onTouchMove(event) {
var x = event.changedTouches[0].clientX;
var y = event.changedTouches[0].clientY; // Emulate 'pointerleave' behavior.
if (x < elementBounds.left || x > elementBounds.left + elementBounds.width || y < elementBounds.top || y > elementBounds.top + elementBounds.height) {
onTrackStop();
} else {
onTrack(x, y);
}
}
function onPointerMove(event) {
onTrack(event.clientX, event.clientY);
}
function onTrackStop() {
element.removeEventListener('pointermove', onPointerMove);
element.removeEventListener('pointerleave', onTrackStop);
element.removeEventListener('pointercancel', onTrackStop);
element.removeEventListener('touchmove', onTouchMove);
element.removeEventListener('touchend', onTrackStop);
element.removeEventListener('touchcancel', onTrackStop);
_onTrackStop();
}
function onPointerEnter() {
onTrackStart();
element.addEventListener('pointermove', onPointerMove);
element.addEventListener('pointerleave', onTrackStop);
element.addEventListener('pointercancel', onTrackStop);
}
element.addEventListener('pointerenter', onPointerEnter);
return function () {
onTrackStop();
element.removeEventListener(onPointerEnter);
element.removeEventListener(onTouchStart);
};
}
//# sourceMappingURL=utility.js.map
{
"name": "chartogram",
"version": "0.1.8",
"version": "0.1.9",
"description": "Charts in JS with no dependencies",

@@ -5,0 +5,0 @@ "main": "index.commonjs.js",

@@ -18,3 +18,3 @@ import {

title,
transitionDuration: 300,
transitionDuration: 250,
transitionEasing: 'easeOutQuad',

@@ -83,2 +83,5 @@ gaugeTickMarksCount: 6,

window.removeEventListener('resize', this.onResizeThrottled)
if (this.transition) {
cancelAnimationFrame(this.transition)
}
}

@@ -88,4 +91,3 @@

this.setState({
aspectRatio: this.getCanvasAspectRatio(),
canvasWidthPx: this.getCanvasWidthPx()
aspectRatio: this.getCanvasAspectRatio()
}, false)

@@ -101,7 +103,2 @@ }

getCanvasWidthPx() {
const canvasDimensions = this.canvas.getBoundingClientRect()
return canvasDimensions.width
}
setState(newState, renderTimeline = true) {

@@ -147,3 +144,2 @@ this.state = {

canvas: this.canvas,
canvasWidthPx: this.state.canvasWidthPx,
container: this.tooltipContainer,

@@ -180,3 +176,2 @@ pointsContainer: this.canvasWrapper,

aspectRatio: this.getCanvasAspectRatio(),
canvasWidthPx: this.getCanvasWidthPx(),
graphOpacity: this.data.y.map(_ => 1)

@@ -312,3 +307,9 @@ }

onChangeBounds = (from, to) => {
this.setState(this.createState(from, to), false)
const state = this.createState(from, to)
const minY = state.minY
const maxY = state.maxY
delete state.minY
delete state.maxY
this.setState(state, false)
this.transitionState(minY, maxY)
}

@@ -394,21 +395,31 @@

}
const heightBefore = this.state.maxY - this.state.minY
const deltaMaxY = Math.abs(maxY - this.state.maxY) / heightBefore
const deltaMinY = Math.abs(minY - this.state.minY) / heightBefore
const deltaY = Math.max(deltaMinY, deltaMaxY)
const transitionDuration = maxTransitionDuration * Math.max(0.1, Math.min(deltaY, 0.5) * 2)
this.setState({
graphOpacityFrom: this.state.graphOpacity,
graphOpacityTo: graphOpacity,
minYFrom: this.state.minY,
maxYFrom: this.state.maxY,
minYTo: minY,
maxYTo: maxY,
minYGlobalFrom: this.state.minYGlobal,
maxYGlobalFrom: this.state.maxYGlobal,
minYGlobalTo: minYGlobal,
maxYGlobalTo: maxYGlobal,
let transitionDuration = maxTransitionDuration
if (minY !== undefined) {
const heightBefore = this.state.maxY - this.state.minY
const deltaMaxY = Math.abs(maxY - this.state.maxY) / heightBefore
const deltaMinY = Math.abs(minY - this.state.minY) / heightBefore
const deltaY = Math.max(deltaMinY, deltaMaxY)
transitionDuration = maxTransitionDuration * Math.max(0.2, Math.min(deltaY, 0.5) * 2)
}
const state = {
transitionStartedAt: Date.now(),
transitionDuration
})
}
if (minY !== undefined) {
state.minYFrom = this.state.minY
state.maxYFrom = this.state.maxY
state.minYTo = minY
state.maxYTo = maxY
}
if (graphOpacity !== undefined) {
state.graphOpacityFrom = this.state.graphOpacity
state.graphOpacityTo = graphOpacity
}
if (minYGlobal !== undefined) {
state.minYGlobalFrom = this.state.minYGlobal
state.maxYGlobalFrom = this.state.maxYGlobal
state.minYGlobalTo = minYGlobal
state.maxYGlobalTo = maxYGlobal
}
this.setState(state)
// Place in a `setState()` callback in case of React.

@@ -439,9 +450,31 @@ this.transition = requestAnimationFrame(this.transitionStateTick)

ratio = EASING[transitionEasing](ratio)
this.setState({
graphOpacity: graphOpacityTo.map((_, i) => graphOpacityFrom[i] + (graphOpacityTo[i] - graphOpacityFrom[i]) * ratio),
minY: minYFrom + (minYTo - minYFrom) * ratio,
maxY: maxYFrom + (maxYTo - maxYFrom) * ratio,
minYGlobal: minYGlobalFrom + (minYGlobalTo - minYGlobalFrom) * ratio,
maxYGlobal: maxYGlobalFrom + (maxYGlobalTo - maxYGlobalFrom) * ratio
})
const state = {}
if (minYTo !== undefined) {
state.minY = minYFrom + (minYTo - minYFrom) * ratio
state.maxY = maxYFrom + (maxYTo - maxYFrom) * ratio
if (ratio === 1) {
state.minYFrom = undefined
state.minYTo = undefined
state.maxYFrom = undefined
state.maxYTo = undefined
}
}
if (minYGlobalTo !== undefined) {
state.minYGlobal = minYGlobalFrom + (minYGlobalTo - minYGlobalFrom) * ratio
state.maxYGlobal = maxYGlobalFrom + (maxYGlobalTo - maxYGlobalFrom) * ratio
if (ratio === 1) {
state.minYGlobalFrom = undefined
state.minYGlobalTo = undefined
state.maxYGlobalFrom = undefined
state.maxYGlobalTo = undefined
}
}
if (graphOpacityTo !== undefined) {
state.graphOpacity = graphOpacityTo.map((_, i) => graphOpacityFrom[i] + (graphOpacityTo[i] - graphOpacityFrom[i]) * ratio)
if (ratio === 1) {
state.graphOpacityFrom = undefined
state.graphOpacityTo = undefined
}
}
this.setState(state)
if (ratio < 1) {

@@ -448,0 +481,0 @@ this.transition = requestAnimationFrame(this.transitionStateTick)

@@ -0,1 +1,3 @@

import { setUpTouchMove } from './utility'
export default class Tooltip {

@@ -22,150 +24,116 @@ constructor(props) {

setUpListener = () => {
const { canvas, canvasWidthPx, weekdays, months } = this.props
let canvasDimensions
let isIndexInBounds
const onTrack = (screenX) => {
const { minX, maxX, xPoints, y } = this.props
const xScreenRatio = (screenX - canvasDimensions.left) / canvasDimensions.width
const xPoint = minX + xScreenRatio * (maxX - minX)
let xHigherIndex = xPoints.findIndex(_ => _ >= xPoint)
let xLowerIndex = xHigherIndex - 1
if (!isIndexInBounds(xHigherIndex)) {
xHigherIndex = -1
}
if (!isIndexInBounds(xLowerIndex)) {
xLowerIndex = -1
}
let xIndex
if (xHigherIndex < 0) {
if (xLowerIndex < 0) {
return this.unmount()
} else {
xIndex = xLowerIndex
}
} else {
if (xLowerIndex < 0) {
xIndex = xHigherIndex
} else {
const xLower = xPoints[xLowerIndex]
const xHigher = xPoints[xHigherIndex]
const deltaLower = xPoint - xLower
const deltaHigher = xHigher - xPoint
xIndex = deltaLower > deltaHigher ? xHigherIndex : xLowerIndex
}
}
const x = xPoints[xIndex]
if (x !== this.tooltipForX) {
this.tooltipForX = x
if (!this.tooltip) {
this.mount()
}
const date = new Date(x)
this.tooltipDate.textContent = `${weekdays[date.getDay()]}, ${months[date.getMonth()]} ${date.getDate()}`
let i = 0
for (const { isShown, points, name } of y) {
if (isShown) {
this.tooltipValues.childNodes[2 * i].textContent = points[xIndex]
this.tooltipValues.childNodes[2 * i + 1].textContent = name
i++
}
}
const xRatio = (x - minX) / (maxX - minX)
let left = xRatio * canvasWidthPx
left -= 40
const tooltipWidth = this.tooltip.getBoundingClientRect().width
const overflow = 5
if (left < -1 * overflow) {
left = -1 * overflow
} else if (left + tooltipWidth > canvasWidthPx + overflow) {
left = (canvasWidthPx + overflow) - tooltipWidth
}
this.tooltip.style.left = left + 'px'
this.updatePoints(xIndex, xRatio)
this.updateLine(x)
}
const { canvas } = this.props
setUpTouchMove(
canvas,
() => {},
this.onTrack,
() => this.unmount()
)
}
onTrack = (screenX, screenY, canvasDimensions) => {
const { minX, maxX, xPoints } = this.props
const xScreenRatio = (screenX - canvasDimensions.left) / canvasDimensions.width
const xPoint = minX + xScreenRatio * (maxX - minX)
let xHigherIndex = xPoints.findIndex(_ => _ >= xPoint)
let xLowerIndex = xHigherIndex - 1
if (xHigherIndex < 0 || xHigherIndex >= xPoints.length) {
xHigherIndex = -1
}
const onTrackStart = () => {
canvasDimensions = canvas.getBoundingClientRect()
isIndexInBounds = (index) => {
const { xPoints } = this.props
return index >= 0 && index < xPoints.length
}
if (xLowerIndex < 0 || xLowerIndex >= xPoints.length) {
xLowerIndex = -1
}
const onTouchStart = (event) => {
// Ignore multitouch.
if (event.touches.length > 1) {
// Reset.
return onTrackStop()
let xIndex
if (xHigherIndex < 0) {
if (xLowerIndex < 0) {
return this.unmount()
} else {
xIndex = xLowerIndex
}
onTrackStart()
canvas.addEventListener('touchend', onTrackStop)
canvas.addEventListener('touchmove', onTouchMove)
canvas.addEventListener('touchend', onTrackStop)
canvas.addEventListener('touchcancel', onTrackStop)
onTouchMove(event)
}
// Safari doesn't support pointer events.
// https://caniuse.com/#feat=pointer
canvas.addEventListener('touchstart', onTouchStart)
function onTouchMove(event) {
const x = event.changedTouches[0].clientX
const y = event.changedTouches[0].clientY
// Emulate 'pointerleave' behavior.
if (x < canvasDimensions.left ||
x > canvasDimensions.left + canvasDimensions.width ||
y < canvasDimensions.top ||
y > canvasDimensions.top + canvasDimensions.height) {
onTrackStop()
} else {
if (xLowerIndex < 0) {
xIndex = xHigherIndex
} else {
onTrack(x, y)
const xLower = xPoints[xLowerIndex]
const xHigher = xPoints[xHigherIndex]
const deltaLower = xPoint - xLower
const deltaHigher = xHigher - xPoint
xIndex = deltaLower > deltaHigher ? xHigherIndex : xLowerIndex
}
}
function onPointerMove(event) {
onTrack(event.clientX, event.clientY)
const x = xPoints[xIndex]
if (x !== this.tooltipForX) {
this.tooltipForX = x
if (!this.tooltip) {
this.mount()
}
this.updateTooltip(x, xIndex, canvasDimensions.width)
}
const onTrackStop = () => {
canvas.removeEventListener('pointermove', onPointerMove)
canvas.removeEventListener('pointerleave', onTrackStop)
canvas.removeEventListener('pointercancel', onTrackStop)
canvas.removeEventListener('touchmove', onTouchMove)
canvas.removeEventListener('touchend', onTrackStop)
canvas.removeEventListener('touchcancel', onTrackStop)
this.unmount()
}
mount() {
const { container } = this.props
this.tooltip = this.renderTooltip()
container.appendChild(this.tooltip)
this.mountPoints()
if (!this.isLineRendered()) {
this.mountLine()
}
const onPointerEnter = () => {
onTrackStart()
canvas.addEventListener('pointermove', onPointerMove)
canvas.addEventListener('pointerleave', onTrackStop)
canvas.addEventListener('pointercancel', onTrackStop)
}
unmount() {
if (!this.tooltip) {
return
}
canvas.addEventListener('pointerenter', onPointerEnter)
return () => {
onTrackStop()
canvas.removeEventListener(onPointerEnter)
canvas.removeEventListener(onTouchStart)
const { container } = this.props
this.tooltipForX = undefined
container.removeChild(this.tooltip)
this.tooltip = undefined
this.unmountPoints()
if (this.isLineRendered()) {
this.unmountLine()
}
}
mount() {
this.renderTooltip()
this.renderPoints()
if (!this.isLineRendered()) {
this.renderLine()
mountLine() {
const { canvas } = this.props
this.line = this.renderLine()
canvas.insertBefore(this.line, canvas.querySelector('polyline'))
}
unmountLine = () => {
const { canvas } = this.props
canvas.removeChild(this.line)
this.line = undefined
}
mountPoints = () => {
const { pointsContainer } = this.props
this.points = this.renderPoints()
for (const point of this.points) {
pointsContainer.appendChild(point)
}
}
unmountPoints = () => {
const { pointsContainer } = this.props
for (const point of this.points) {
pointsContainer.removeChild(point)
}
this.points = undefined
}
renderTooltip() {
const { y, container } = this.props
const { y } = this.props
// Create tooltip.
this.tooltip = document.createElement('div')
this.tooltip.classList.add('chartogram__tooltip')
container.appendChild(this.tooltip)
const tooltip = document.createElement('div')
tooltip.classList.add('chartogram__tooltip')
// Add tooltip title.
this.tooltipDate = document.createElement('h1')
this.tooltipDate.classList.add('chartogram__tooltip-header')
this.tooltip.appendChild(this.tooltipDate)
const tooltipDate = document.createElement('h1')
tooltipDate.classList.add('chartogram__tooltip-header')
tooltip.appendChild(tooltipDate)
// Add graph values.
this.tooltipValues = document.createElement('dl')
this.tooltipValues.classList.add('chartogram__tooltip-values')
this.tooltip.appendChild(this.tooltipValues)
const tooltipValues = document.createElement('dl')
tooltipValues.classList.add('chartogram__tooltip-values')
tooltip.appendChild(tooltipValues)
// Add graph values.

@@ -177,32 +145,19 @@ for (const { isShown, color } of y) {

tooltipValue.style.color = color
this.tooltipValues.appendChild(tooltipValue)
tooltipValues.appendChild(tooltipValue)
// Add graph name.
const tooltipName = document.createElement('dd')
tooltipName.style.color = color
this.tooltipValues.appendChild(tooltipName)
tooltipValues.appendChild(tooltipName)
}
}
return tooltip
}
renderLine() {
const { canvas } = this.props
const xmlns = 'http://www.w3.org/2000/svg'
this.line = document.createElementNS(xmlns, 'line')
this.line.setAttribute('class', 'chartogram__tooltip-line')
canvas.insertBefore(this.line, canvas.querySelector('polyline'))
const line = document.createElementNS(xmlns, 'line')
line.setAttribute('class', 'chartogram__tooltip-line')
return line
}
unmount() {
if (this.tooltip) {
const { container } = this.props
this.tooltipForX = undefined
container.removeChild(this.tooltip)
this.tooltip = undefined
this.unmountPoints()
if (this.isLineRendered()) {
this.unmountLine()
}
}
}
isLineRendered() {

@@ -213,10 +168,4 @@ const { canvas } = this.props

unmountLine = () => {
const { canvas } = this.props
canvas.removeChild(this.line)
this.line = undefined
}
renderPoints() {
this.points = []
const points = []
const { pointsContainer, y } = this.props

@@ -228,19 +177,55 @@ for (const _y of y) {

point.style.color = _y.color
this.points.push(point)
points.push(point)
pointsContainer.appendChild(point)
}
}
return points
}
unmountPoints = () => {
const { pointsContainer } = this.props
for (const point of this.points) {
pointsContainer.removeChild(point)
updateTooltip(x, xIndex, canvasWidth) {
const { minX, maxX } = this.props
const xRatio = (x - minX) / (maxX - minX)
this.updateTooltipDate(new Date(x))
this.updateTooltipValues(xIndex)
this.updateTooltipPosition(xRatio, canvasWidth)
this.updatePointPositions(xIndex, xRatio)
this.updateLinePosition(x)
}
updateTooltipPosition(xRatio, canvasWidth) {
const { tooltipShift, maxOverflow } = this.props
let left = xRatio * canvasWidth
left -= tooltipShift === undefined ? 40 : tooltipShift
const tooltipWidth = this.tooltip.getBoundingClientRect().width
const overflow = maxOverflow === undefined ? 5 : maxOverflow
if (left < -1 * overflow) {
left = -1 * overflow
} else if (left + tooltipWidth > canvasWidth + overflow) {
left = (canvasWidth + overflow) - tooltipWidth
}
this.points = undefined
this.tooltip.style.left = left + 'px'
}
updateLine = (x) => {
updateTooltipDate(date) {
const { weekdays, months } = this.props
const tooltipDate = this.tooltip.childNodes[0]
tooltipDate.textContent = `${weekdays[date.getDay()]}, ${months[date.getMonth()]} ${date.getDate()}`
}
updateTooltipValues(xIndex) {
const { y } = this.props
const tooltipValues = this.tooltip.childNodes[1]
let i = 0
for (const { isShown, points, name } of y) {
if (isShown) {
tooltipValues.childNodes[2 * i].textContent = points[xIndex]
tooltipValues.childNodes[2 * i + 1].textContent = name
i++
}
}
}
updateLinePosition = (x) => {
if (!this.isLineRendered()) {
this.renderLine()
this.mountLine()
}

@@ -254,3 +239,3 @@ const { canvasWidth, aspectRatio, fixSvgCoordinate, mapX } = this.props

updatePoints = (xIndex, xRatio) => {
updatePointPositions = (xIndex, xRatio) => {
const { maxY, y } = this.props

@@ -257,0 +242,0 @@ let i = 0

@@ -156,2 +156,66 @@ export function clearElement(element) {

}
}
export function setUpTouchMove(element, _onTrackStart, _onTrack, _onTrackStop) {
let elementBounds
function onTrack(x, y) {
_onTrack(x, y, elementBounds)
}
function onTrackStart() {
elementBounds = element.getBoundingClientRect()
_onTrackStart()
}
function onTouchStart(event) {
// Ignore multitouch.
if (event.touches.length > 1) {
// Reset.
return onTrackStop()
}
onTrackStart()
element.addEventListener('touchend', onTrackStop)
element.addEventListener('touchmove', onTouchMove)
element.addEventListener('touchend', onTrackStop)
element.addEventListener('touchcancel', onTrackStop)
onTouchMove(event)
}
// Safari doesn't support pointer events.
// https://caniuse.com/#feat=pointer
element.addEventListener('touchstart', onTouchStart)
function onTouchMove(event) {
const x = event.changedTouches[0].clientX
const y = event.changedTouches[0].clientY
// Emulate 'pointerleave' behavior.
if (x < elementBounds.left ||
x > elementBounds.left + elementBounds.width ||
y < elementBounds.top ||
y > elementBounds.top + elementBounds.height) {
onTrackStop()
} else {
onTrack(x, y)
}
}
function onPointerMove(event) {
onTrack(event.clientX, event.clientY)
}
function onTrackStop() {
element.removeEventListener('pointermove', onPointerMove)
element.removeEventListener('pointerleave', onTrackStop)
element.removeEventListener('pointercancel', onTrackStop)
element.removeEventListener('touchmove', onTouchMove)
element.removeEventListener('touchend', onTrackStop)
element.removeEventListener('touchcancel', onTrackStop)
_onTrackStop()
}
function onPointerEnter() {
onTrackStart()
element.addEventListener('pointermove', onPointerMove)
element.addEventListener('pointerleave', onTrackStop)
element.addEventListener('pointercancel', onTrackStop)
}
element.addEventListener('pointerenter', onPointerEnter)
return () => {
onTrackStop()
element.removeEventListener(onPointerEnter)
element.removeEventListener(onTouchStart)
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc