c3_chart_internal_fn.updateLegend = function()

in TestApplications/Web/js/lib/components/c3-0.4.2/c3.js [3743:3953]


    c3_chart_internal_fn.updateLegend = function (targetIds, options, transitions) {
        var $$ = this, config = $$.config;
        var xForLegend, xForLegendText, xForLegendRect, yForLegend, yForLegendText, yForLegendRect;
        var paddingTop = 4, paddingRight = 10, maxWidth = 0, maxHeight = 0, posMin = 10, tileWidth = 15;
        var l, totalLength = 0, offsets = {}, widths = {}, heights = {}, margins = [0], steps = {}, step = 0;
        var withTransition, withTransitionForTransform;
        var hasFocused = $$.legend.selectAll('.' + CLASS.legendItemFocused).size();
        var texts, rects, tiles, background;

        options = options || {};
        withTransition = getOption(options, "withTransition", true);
        withTransitionForTransform = getOption(options, "withTransitionForTransform", true);

        function updatePositions(textElement, id, index) {
            var reset = index === 0, isLast = index === targetIds.length - 1,
                box = $$.getTextRect(textElement.textContent, CLASS.legendItem),
                itemWidth = box.width + tileWidth + (isLast && !($$.isLegendRight || $$.isLegendInset) ? 0 : paddingRight),
                itemHeight = box.height + paddingTop,
                itemLength = $$.isLegendRight || $$.isLegendInset ? itemHeight : itemWidth,
                areaLength = $$.isLegendRight || $$.isLegendInset ? $$.getLegendHeight() : $$.getLegendWidth(),
                margin, maxLength;

            // MEMO: care about condifion of step, totalLength
            function updateValues(id, withoutStep) {
                if (!withoutStep) {
                    margin = (areaLength - totalLength - itemLength) / 2;
                    if (margin < posMin) {
                        margin = (areaLength - itemLength) / 2;
                        totalLength = 0;
                        step++;
                    }
                }
                steps[id] = step;
                margins[step] = $$.isLegendInset ? 10 : margin;
                offsets[id] = totalLength;
                totalLength += itemLength;
            }

            if (reset) {
                totalLength = 0;
                step = 0;
                maxWidth = 0;
                maxHeight = 0;
            }

            if (config.legend_show && !$$.isLegendToShow(id)) {
                widths[id] = heights[id] = steps[id] = offsets[id] = 0;
                return;
            }

            widths[id] = itemWidth;
            heights[id] = itemHeight;

            if (!maxWidth || itemWidth >= maxWidth) { maxWidth = itemWidth; }
            if (!maxHeight || itemHeight >= maxHeight) { maxHeight = itemHeight; }
            maxLength = $$.isLegendRight || $$.isLegendInset ? maxHeight : maxWidth;

            if (config.legend_equally) {
                Object.keys(widths).forEach(function (id) { widths[id] = maxWidth; });
                Object.keys(heights).forEach(function (id) { heights[id] = maxHeight; });
                margin = (areaLength - maxLength * targetIds.length) / 2;
                if (margin < posMin) {
                    totalLength = 0;
                    step = 0;
                    targetIds.forEach(function (id) { updateValues(id); });
                }
                else {
                    updateValues(id, true);
                }
            } else {
                updateValues(id);
            }
        }

        if ($$.isLegendInset) {
            step = config.legend_inset_step ? config.legend_inset_step : targetIds.length;
            $$.updateLegendStep(step);
        }

        if ($$.isLegendRight) {
            xForLegend = function (id) { return maxWidth * steps[id]; };
            yForLegend = function (id) { return margins[steps[id]] + offsets[id]; };
        } else if ($$.isLegendInset) {
            xForLegend = function (id) { return maxWidth * steps[id] + 10; };
            yForLegend = function (id) { return margins[steps[id]] + offsets[id]; };
        } else {
            xForLegend = function (id) { return margins[steps[id]] + offsets[id]; };
            yForLegend = function (id) { return maxHeight * steps[id]; };
        }
        xForLegendText = function (id, i) { return xForLegend(id, i) + 14; };
        yForLegendText = function (id, i) { return yForLegend(id, i) + 9; };
        xForLegendRect = function (id, i) { return xForLegend(id, i); };
        yForLegendRect = function (id, i) { return yForLegend(id, i) - 5; };

        // Define g for legend area
        l = $$.legend.selectAll('.' + CLASS.legendItem)
            .data(targetIds)
            .enter().append('g')
            .attr('class', function (id) { return $$.generateClass(CLASS.legendItem, id); })
            .style('visibility', function (id) { return $$.isLegendToShow(id) ? 'visible' : 'hidden'; })
            .style('cursor', 'pointer')
            .on('click', function (id) {
                if (config.legend_item_onclick) {
                    config.legend_item_onclick.call($$, id);
                } else {
                    if ($$.d3.event.altKey) {
                        $$.api.hide();
                        $$.api.show(id);
                    } else {
                        $$.api.toggle(id);
                        $$.isTargetToShow(id) ? $$.api.focus(id) : $$.api.revert();
                    }
                }
            })
            .on('mouseover', function (id) {
                $$.d3.select(this).classed(CLASS.legendItemFocused, true);
                if (!$$.transiting && $$.isTargetToShow(id)) {
                    $$.api.focus(id);
                }
                if (config.legend_item_onmouseover) {
                    config.legend_item_onmouseover.call($$, id);
                }
            })
            .on('mouseout', function (id) {
                $$.d3.select(this).classed(CLASS.legendItemFocused, false);
                $$.api.revert();
                if (config.legend_item_onmouseout) {
                    config.legend_item_onmouseout.call($$, id);
                }
            });
        l.append('text')
            .text(function (id) { return isDefined(config.data_names[id]) ? config.data_names[id] : id; })
            .each(function (id, i) { updatePositions(this, id, i); })
            .style("pointer-events", "none")
            .attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200)
            .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendText);
        l.append('rect')
            .attr("class", CLASS.legendItemEvent)
            .style('fill-opacity', 0)
            .attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendRect : -200)
            .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendRect);
        l.append('rect')
            .attr("class", CLASS.legendItemTile)
            .style("pointer-events", "none")
            .style('fill', $$.color)
            .attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200)
            .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegend)
            .attr('width', 10)
            .attr('height', 10);

        // Set background for inset legend
        background = $$.legend.select('.' + CLASS.legendBackground + ' rect');
        if ($$.isLegendInset && maxWidth > 0 && background.size() === 0) {
            background = $$.legend.insert('g', '.' + CLASS.legendItem)
                .attr("class", CLASS.legendBackground)
                .append('rect');
        }

        texts = $$.legend.selectAll('text')
            .data(targetIds)
            .text(function (id) { return isDefined(config.data_names[id]) ? config.data_names[id] : id; }) // MEMO: needed for update
            .each(function (id, i) { updatePositions(this, id, i); });
        (withTransition ? texts.transition() : texts)
            .attr('x', xForLegendText)
            .attr('y', yForLegendText);

        rects = $$.legend.selectAll('rect.' + CLASS.legendItemEvent)
            .data(targetIds);
        (withTransition ? rects.transition() : rects)
            .attr('width', function (id) { return widths[id]; })
            .attr('height', function (id) { return heights[id]; })
            .attr('x', xForLegendRect)
            .attr('y', yForLegendRect);

        tiles = $$.legend.selectAll('rect.' + CLASS.legendItemTile)
            .data(targetIds);
        (withTransition ? tiles.transition() : tiles)
            .style('fill', $$.color)
            .attr('x', xForLegend)
            .attr('y', yForLegend);

        if (background) {
            (withTransition ? background.transition() : background)
                .attr('height', $$.getLegendHeight() - 12)
                .attr('width', maxWidth * (step + 1) + 10);
        }

        // toggle legend state
        $$.legend.selectAll('.' + CLASS.legendItem)
            .classed(CLASS.legendItemHidden, function (id) { return !$$.isTargetToShow(id); })
            .transition()
            .style('opacity', function (id) {
                var This = $$.d3.select(this);
                if ($$.isTargetToShow(id)) {
                    return !hasFocused || This.classed(CLASS.legendItemFocused) ? $$.opacityForLegend(This) : $$.opacityForUnfocusedLegend(This);
                } else {
                    return $$.legendOpacityForHidden;
                }
            });

        // Update all to reflect change of legend
        $$.updateLegendItemWidth(maxWidth);
        $$.updateLegendItemHeight(maxHeight);
        $$.updateLegendStep(step);
        // Update size and scale
        $$.updateSizes();
        $$.updateScales();
        $$.updateSvgSize();
        // Update g positions
        $$.transformAll(withTransitionForTransform, transitions);
    };