{"remainingRequest":"/usr/local/lib/node_modules/@vue/cli-service-global/node_modules/vue-loader/lib/index.js??vue-loader-options!/Applications/MAMP/htdocs/vue-funnel-graph-js/src/lib-components/vue-funnel-graph.vue?vue&type=script&lang=js&","dependencies":[{"path":"/Applications/MAMP/htdocs/vue-funnel-graph-js/src/lib-components/vue-funnel-graph.vue","mtime":1551737349293},{"path":"/usr/local/lib/node_modules/@vue/cli-service-global/node_modules/babel-loader/lib/index.js","mtime":499162500000},{"path":"/usr/local/lib/node_modules/@vue/cli-service-global/node_modules/cache-loader/dist/cjs.js","mtime":499162500000},{"path":"/usr/local/lib/node_modules/@vue/cli-service-global/node_modules/vue-loader/lib/index.js","mtime":499162500000}],"contextDependencies":[],"result":["//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\nimport { interpolate } from 'polymorph-js';\nimport TWEEN from '@tweenjs/tween.js';\nimport FunnelGraph from 'funnel-graph-js';\nimport { formatNumber } from 'funnel-graph-js/src/js/number';\nimport { getDefaultColors } from 'funnel-graph-js/src/js/graph';\nimport 'funnel-graph-js/src/scss/main.scss';\nimport 'funnel-graph-js/src/scss/theme.scss';\n\nexport default {\n    name: 'VueFunnelGraph',\n    props: {\n        animated: {\n            type: Boolean,\n            default: false\n        },\n        width: [String, Number],\n        height: [String, Number],\n        values: Array,\n        labels: Array,\n        colors: {\n            type: Array,\n            default() { return []; }\n        },\n        subLabels: Array,\n        direction: {\n            type: String,\n            default: 'horizontal'\n        },\n        gradientDirection: {\n            type: String,\n            default: 'horizontal'\n        },\n        displayPercentage: {\n            type: Boolean,\n            default: true\n        }\n    },\n    data() {\n        return {\n            paths: [],\n            prevPaths: [], // paths before update, used for animations\n            graph: null,\n            animationRunning: false,\n            defaultColors: getDefaultColors(10)\n        };\n    },\n    computed: {\n        valuesFormatted() {\n            if (this.graph.is2d()) {\n                return this.graph.getValues2d().map(value => formatNumber(value));\n            }\n            return this.values.map(value => formatNumber(value));\n        },\n        colorSet() {\n            const colorSet = [];\n            let gradientCount = 0;\n\n            for (let i = 0; i < this.paths.length; i++) {\n                const values = this.graph.is2d() ? this.getColors[i] : this.getColors;\n                const fillMode = (typeof values === 'string' || values.length === 1) ? 'solid' : 'gradient';\n                if (fillMode === 'gradient') gradientCount += 1;\n                colorSet.push({\n                    values,\n                    fillMode,\n                    fill: fillMode === 'solid' ? values : `url('#funnelGradient-${gradientCount}')`\n                });\n            }\n            return colorSet;\n        },\n        gradientSet() {\n            const gradientSet = [];\n            this.colorSet.forEach((colors) => {\n                if (colors.fillMode === 'gradient') {\n                    gradientSet.push(colors);\n                }\n            });\n            return gradientSet;\n        },\n        getColors() {\n            if (this.colors instanceof Array && this.colors.length === 0) {\n                return getDefaultColors(this.is2d() ? this.values[0].length : 2);\n            }\n            if (this.colors.length < this.paths.length) {\n                return [...this.colors].concat(\n                    [...this.defaultColors].splice(this.paths.length, this.paths.length - this.colors.length)\n                );\n            }\n            return this.colors;\n        },\n        gradientAngle() {\n            return `rotate(${this.gradientDirection === 'vertical' ? 90 : 0})`;\n        }\n    },\n    methods: {\n        enterTransition(el, done) {\n            if (!this.animated) done();\n        },\n        leaveTransition(el, done) {\n            if (!this.animated) done();\n        },\n        is2d() {\n            return this.graph.is2d();\n        },\n        percentages() {\n            return this.graph.createPercentages();\n        },\n        twoDimPercentages() {\n            if (!this.is2d()) {\n                return [];\n            }\n            return this.graph.getPercentages2d();\n        },\n        offsetColor(index, length) {\n            return `${Math.round(100 * index / (length - 1))}%`;\n        },\n        makeAnimations() {\n            const interpolators = [];\n            const dimensionChanged = this.prevPaths.length !== this.paths.length;\n\n            let origin = { x: 0.5, y: 0.5 };\n            if (dimensionChanged) {\n                origin = { x: 0, y: 0.5 };\n                if (this.graph.isVertical()) {\n                    origin = { x: 1, y: 1 };\n                }\n                if (!this.graph.is2d()) {\n                    origin = { x: 0, y: 1 };\n                }\n            }\n\n            this.paths.forEach((path, index) => {\n                let oldPath = this.prevPaths[index] || this.graph.getPathMedian(index);\n                if (dimensionChanged) oldPath = this.graph.getPathMedian(index);\n                const interpolator = interpolate([oldPath, path], {\n                    addPoints: 1,\n                    origin,\n                    optimize: 'fill',\n                    precision: 1\n                });\n\n                interpolators.push(interpolator);\n            });\n\n            function animate() {\n                if (TWEEN.update()) {\n                    requestAnimationFrame(animate);\n                }\n            }\n\n            const position = { value: 0 };\n            const tween = new TWEEN.Tween(position)\n                .to({ value: 1 }, 700)\n                .easing(TWEEN.Easing.Cubic.InOut)\n                .onStart(() => {\n                    this.animationRunning = true;\n                })\n                .onUpdate(() => {\n                    for (let index = 0; index < this.paths.length; index++) {\n                        this.paths[index] = interpolators[index](position.value);\n                        // eslint-disable-next-line no-underscore-dangle\n                        this.paths.__ob__.dep.notify();\n                    }\n                })\n                .onComplete(() => {\n                    this.animationRunning = false;\n                });\n\n            if (this.animationRunning === false) tween.start();\n\n            animate();\n        },\n        drawPaths() {\n            this.prevPaths = this.paths;\n            this.paths = [];\n            const definitions = this.graph.getPathDefinitions();\n\n            definitions.forEach((d) => {\n                this.paths.push(d);\n            });\n        }\n    },\n    beforeMount() {\n        this.graph = new FunnelGraph({\n            height: this.height,\n            width: this.width,\n            data: {\n                labels: this.labels,\n                values: this.values\n            }\n        });\n        this.drawPaths();\n        if (this.animated) this.makeAnimations();\n    },\n    watch: {\n        values() {\n            this.graph.setValues(this.values);\n            this.drawPaths();\n            if (this.animated) this.makeAnimations();\n        },\n        direction() {\n            this.graph.setDirection(this.direction)\n                .setWidth(this.width)\n                .setHeight(this.height);\n            this.drawPaths();\n        }\n    }\n};\n",{"version":3,"sources":["vue-funnel-graph.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"vue-funnel-graph.vue","sourceRoot":".","sourcesContent":["<template>\n    <div class=\"funnel svg-funnel-js\" :class=\"{'svg-funnel-js--vertical': direction === 'vertical'}\">\n        <div class=\"svg-funnel-js__container\">\n            <svg :width=\"width\" :height=\"height\">\n                <defs>\n                    <linearGradient :id=\"`funnelGradient-${(index+1)}`\"\n                                    v-for=\"(colors, index) in gradientSet\"\n                                    :key=\"index\"\n                                    :gradientTransform=\"gradientAngle\"\n                    >\n                        <stop :stop-color=\"color\"\n                              :offset=\"offsetColor(index, colors.values.length)\"\n                              v-for=\"(color, index) in colors.values\"\n                              :key=\"index\"\n                        ></stop>\n                    </linearGradient>\n                </defs>\n                <path :fill=\"colorSet[index].fill\" :stroke=\"colorSet[index].fill\"\n                      :d=\"path\" v-for=\"(path, index) in paths\" :key=\"index\"\n                ></path>\n            </svg>\n        </div>\n        <transition-group class=\"svg-funnel-js__labels\" name=\"appear\" tag=\"div\"\n                          v-on:enter=\"enterTransition\" v-on:leave=\"leaveTransition\"\n        >\n            <div class=\"svg-funnel-js__label\" :class=\"`label-${(index+1)}`\"\n                 v-for=\"(value, index) in valuesFormatted\" :key=\"labels[index].toLowerCase().replace(' ', '-')\"\n            >\n                <div class=\"label__value\">{{ value }}</div>\n                <div class=\"label__title\" v-if=\"labels\">{{ labels[index] }}</div>\n                <div class=\"label__percentage\" v-if=\"displayPercentage && percentages()[index] !== 100\">\n                    {{ percentages()[index] }}%\n                </div>\n                <div class=\"label__segment-percentages\" v-if=\"is2d()\">\n                    <ul class=\"segment-percentage__list\">\n                        <li v-for=\"(subLabel, j) in subLabels\" :key=\"j\">\n                            {{ subLabel }}:\n                            <span class=\"percentage__list-label\">{{ twoDimPercentages()[index][j] }}%</span>\n                        </li>\n                    </ul>\n                </div>\n            </div>\n        </transition-group>\n    </div>\n</template>\n\n<script>\n    import { interpolate } from 'polymorph-js';\n    import TWEEN from '@tweenjs/tween.js';\n    import FunnelGraph from 'funnel-graph-js';\n    import { formatNumber } from 'funnel-graph-js/src/js/number';\n    import { getDefaultColors } from 'funnel-graph-js/src/js/graph';\n    import 'funnel-graph-js/src/scss/main.scss';\n    import 'funnel-graph-js/src/scss/theme.scss';\n\n    export default {\n        name: 'VueFunnelGraph',\n        props: {\n            animated: {\n                type: Boolean,\n                default: false\n            },\n            width: [String, Number],\n            height: [String, Number],\n            values: Array,\n            labels: Array,\n            colors: {\n                type: Array,\n                default() { return []; }\n            },\n            subLabels: Array,\n            direction: {\n                type: String,\n                default: 'horizontal'\n            },\n            gradientDirection: {\n                type: String,\n                default: 'horizontal'\n            },\n            displayPercentage: {\n                type: Boolean,\n                default: true\n            }\n        },\n        data() {\n            return {\n                paths: [],\n                prevPaths: [], // paths before update, used for animations\n                graph: null,\n                animationRunning: false,\n                defaultColors: getDefaultColors(10)\n            };\n        },\n        computed: {\n            valuesFormatted() {\n                if (this.graph.is2d()) {\n                    return this.graph.getValues2d().map(value => formatNumber(value));\n                }\n                return this.values.map(value => formatNumber(value));\n            },\n            colorSet() {\n                const colorSet = [];\n                let gradientCount = 0;\n\n                for (let i = 0; i < this.paths.length; i++) {\n                    const values = this.graph.is2d() ? this.getColors[i] : this.getColors;\n                    const fillMode = (typeof values === 'string' || values.length === 1) ? 'solid' : 'gradient';\n                    if (fillMode === 'gradient') gradientCount += 1;\n                    colorSet.push({\n                        values,\n                        fillMode,\n                        fill: fillMode === 'solid' ? values : `url('#funnelGradient-${gradientCount}')`\n                    });\n                }\n                return colorSet;\n            },\n            gradientSet() {\n                const gradientSet = [];\n                this.colorSet.forEach((colors) => {\n                    if (colors.fillMode === 'gradient') {\n                        gradientSet.push(colors);\n                    }\n                });\n                return gradientSet;\n            },\n            getColors() {\n                if (this.colors instanceof Array && this.colors.length === 0) {\n                    return getDefaultColors(this.is2d() ? this.values[0].length : 2);\n                }\n                if (this.colors.length < this.paths.length) {\n                    return [...this.colors].concat(\n                        [...this.defaultColors].splice(this.paths.length, this.paths.length - this.colors.length)\n                    );\n                }\n                return this.colors;\n            },\n            gradientAngle() {\n                return `rotate(${this.gradientDirection === 'vertical' ? 90 : 0})`;\n            }\n        },\n        methods: {\n            enterTransition(el, done) {\n                if (!this.animated) done();\n            },\n            leaveTransition(el, done) {\n                if (!this.animated) done();\n            },\n            is2d() {\n                return this.graph.is2d();\n            },\n            percentages() {\n                return this.graph.createPercentages();\n            },\n            twoDimPercentages() {\n                if (!this.is2d()) {\n                    return [];\n                }\n                return this.graph.getPercentages2d();\n            },\n            offsetColor(index, length) {\n                return `${Math.round(100 * index / (length - 1))}%`;\n            },\n            makeAnimations() {\n                const interpolators = [];\n                const dimensionChanged = this.prevPaths.length !== this.paths.length;\n\n                let origin = { x: 0.5, y: 0.5 };\n                if (dimensionChanged) {\n                    origin = { x: 0, y: 0.5 };\n                    if (this.graph.isVertical()) {\n                        origin = { x: 1, y: 1 };\n                    }\n                    if (!this.graph.is2d()) {\n                        origin = { x: 0, y: 1 };\n                    }\n                }\n\n                this.paths.forEach((path, index) => {\n                    let oldPath = this.prevPaths[index] || this.graph.getPathMedian(index);\n                    if (dimensionChanged) oldPath = this.graph.getPathMedian(index);\n                    const interpolator = interpolate([oldPath, path], {\n                        addPoints: 1,\n                        origin,\n                        optimize: 'fill',\n                        precision: 1\n                    });\n\n                    interpolators.push(interpolator);\n                });\n\n                function animate() {\n                    if (TWEEN.update()) {\n                        requestAnimationFrame(animate);\n                    }\n                }\n\n                const position = { value: 0 };\n                const tween = new TWEEN.Tween(position)\n                    .to({ value: 1 }, 700)\n                    .easing(TWEEN.Easing.Cubic.InOut)\n                    .onStart(() => {\n                        this.animationRunning = true;\n                    })\n                    .onUpdate(() => {\n                        for (let index = 0; index < this.paths.length; index++) {\n                            this.paths[index] = interpolators[index](position.value);\n                            // eslint-disable-next-line no-underscore-dangle\n                            this.paths.__ob__.dep.notify();\n                        }\n                    })\n                    .onComplete(() => {\n                        this.animationRunning = false;\n                    });\n\n                if (this.animationRunning === false) tween.start();\n\n                animate();\n            },\n            drawPaths() {\n                this.prevPaths = this.paths;\n                this.paths = [];\n                const definitions = this.graph.getPathDefinitions();\n\n                definitions.forEach((d) => {\n                    this.paths.push(d);\n                });\n            }\n        },\n        beforeMount() {\n            this.graph = new FunnelGraph({\n                height: this.height,\n                width: this.width,\n                data: {\n                    labels: this.labels,\n                    values: this.values\n                }\n            });\n            this.drawPaths();\n            if (this.animated) this.makeAnimations();\n        },\n        watch: {\n            values() {\n                this.graph.setValues(this.values);\n                this.drawPaths();\n                if (this.animated) this.makeAnimations();\n            },\n            direction() {\n                this.graph.setDirection(this.direction)\n                    .setWidth(this.width)\n                    .setHeight(this.height);\n                this.drawPaths();\n            }\n        }\n    };\n</script>\n\n<style scoped>\n    .appear-enter-active, .appear-leave-active {\n        transition: all .7s ease-in-out;\n    }\n\n    .appear-enter-to, .appear-leave {\n        max-width: 100%;\n        max-height: 100%;\n        opacity: 1;\n    }\n\n    .appear-enter, .appear-leave-to {\n        max-width: 0;\n        max-height: 0;\n        opacity: 0;\n    }\n</style>\n"]}]}