{"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=style&index=0&id=5dd8f15e&scoped=true&lang=scss&","dependencies":[{"path":"/Applications/MAMP/htdocs/vue-funnel-graph-js/src/lib-components/vue-funnel-graph.vue","mtime":1580653633982},{"path":"/usr/local/lib/node_modules/@vue/cli-service-global/node_modules/css-loader/index.js","mtime":499162500000},{"path":"/usr/local/lib/node_modules/@vue/cli-service-global/node_modules/vue-loader/lib/loaders/stylePostLoader.js","mtime":499162500000},{"path":"/Applications/MAMP/htdocs/vue-funnel-graph-js/node_modules/sass-loader/dist/cjs.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\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\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\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\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\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\n\n\n\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\n.fade-enter-active, .fade-leave-active {\n    transition: all .3s ease;\n}\n\n.fade-enter-to, .fade-leave {\n    opacity: 1;\n}\n\n.fade-enter, .fade-leave-to {\n    opacity: 0;\n}\n",{"version":3,"sources":["vue-funnel-graph.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwRA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA","file":"vue-funnel-graph.vue","sourceRoot":"lib-components","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().split(' ').join('-')\"\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\" v-if=\"subLabelValue === 'percent'\">{{ twoDimPercentages()[index][j] }}%</span>\n                            <span class=\"percentage__list-label\" v-else>{{ values[index][j] | format }}</span>\n                        </li>\n                    </ul>\n                </div>\n            </div>\n        </transition-group>\n        <transition name=\"fade\" v-on:enter=\"enterTransition\" v-on:leave=\"leaveTransition\">\n            <div class=\"svg-funnel-js__subLabels\" v-if=\"is2d()\">\n                <div :class=\"`svg-funnel-js__subLabel svg-funnel-js__subLabel-${(index + 1)}`\"\n                     v-for=\"(subLabel, index) in subLabels\"\n                     :key=\"index\"\n                >\n                    <div class=\"svg-funnel-js__subLabel--color\"\n                         :style=\"subLabelBackgrounds(index)\"></div>\n                    <div class=\"svg-funnel-js__subLabel--title\">{{ subLabel }}</div>\n                </div>\n            </div>\n        </transition>\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, generateLegendBackground } 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            subLabelValue: {\n                type: String,\n                default: 'percent'\n            },\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                tween: null,\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                setTimeout(() => done(), 700);\n            },\n            leaveTransition(el, done) {\n                if (!this.animated) done();\n                setTimeout(() => done(), 700);\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            subLabelBackgrounds(index) {\n                if (!this.is2d()) {\n                    return [];\n                }\n                return generateLegendBackground(this.getColors[index], this.gradientDirection);\n            },\n            offsetColor(index, length) {\n                return `${Math.round(100 * index / (length - 1))}%`;\n            },\n            makeAnimations() {\n                if (this.tween !== null) { this.tween.stop(); }\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                this.tween = new TWEEN.Tween(position)\n                    .to({ value: 1 }, 700)\n                    .easing(TWEEN.Easing.Cubic.InOut)\n                    .onUpdate(() => {\n                        for (let index = 0; index < this.paths.length; index++) {\n                            this.$set(this.paths, index, interpolators[index](position.value));\n                        }\n                    });\n\n                this.tween.start();\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        created() {\n            this.graph = new FunnelGraph({\n                height: this.height,\n                width: this.width,\n                direction: this.direction,\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        filters: {\n            format: function (value) {\n                return formatNumber(value)\n            }\n        }\n    };\n</script>\n\n<style scoped lang=\"scss\">\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\n    .fade-enter-active, .fade-leave-active {\n        transition: all .3s ease;\n    }\n\n    .fade-enter-to, .fade-leave {\n        opacity: 1;\n    }\n\n    .fade-enter, .fade-leave-to {\n        opacity: 0;\n    }\n</style>\n"]}]}