function updatePathViewModels(parcatsViewModel) {
    // Initialize an array of the y position of the top of the next path to be added to each category.
    //
    // nextYPositions[d][c] is the y position of the next path through category with index c of dimension with index d
    var dimensionViewModels = parcatsViewModel.dimensions;
    var parcatsModel = parcatsViewModel.model;
    var nextYPositions = dimensionViewModels.map(
        function(d) {
            return d.categories.map(
                function(c) {
                    return c.y;
                });
        });

    // Array from category index to category display index for each true dimension index
    var catToDisplayIndPerDim = parcatsViewModel.model.dimensions.map(
        function(d) {
            return d.categories.map(function(c) {return c.displayInd;});
        });

    // Array from true dimension index to dimension display index
    var dimToDisplayInd = parcatsViewModel.model.dimensions.map(function(d) {return d.displayInd;});
    var displayToDimInd = parcatsViewModel.dimensions.map(function(d) {return d.model.dimensionInd;});

    // Array of the x position of the left edge of the rectangles for each dimension
    var leftXPositions = dimensionViewModels.map(
        function(d) {
            return d.x;
        });

    // Compute dimension widths
    var dimWidths = dimensionViewModels.map(function(d) {return d.width;});

    // Build sorted Array of PathModel objects
    var pathModels = [];
    for(var p in parcatsModel.paths) {
        if(parcatsModel.paths.hasOwnProperty(p)) {
            pathModels.push(parcatsModel.paths[p]);
        }
    }

    // Compute category display inds to use for sorting paths
    function pathDisplayCategoryInds(pathModel) {
        var dimensionInds = pathModel.categoryInds.map(function(catInd, dimInd) {return catToDisplayIndPerDim[dimInd][catInd];});
        var displayInds = displayToDimInd.map(function(dimInd) {
            return dimensionInds[dimInd];
        });
        return displayInds;
    }

    // Sort in ascending order by display index array
    pathModels.sort(function(v1, v2) {
        // Build display inds for each path
        var sortArray1 = pathDisplayCategoryInds(v1);
        var sortArray2 = pathDisplayCategoryInds(v2);

        // Handle path sort order
        if(parcatsViewModel.sortpaths === 'backward') {
            sortArray1.reverse();
            sortArray2.reverse();
        }

        // Append the first value index of the path to break ties
        sortArray1.push(v1.valueInds[0]);
        sortArray2.push(v2.valueInds[0]);

        // Handle color bundling
        if(parcatsViewModel.bundlecolors) {
            // Prepend sort array with the raw color value
            sortArray1.unshift(v1.rawColor);
            sortArray2.unshift(v2.rawColor);
        }

        // colors equal, sort by display categories
        if(sortArray1 < sortArray2) {
            return -1;
        }
        if(sortArray1 > sortArray2) {
            return 1;
        }

        return 0;
    });

    // Create path models
    var pathViewModels = new Array(pathModels.length);
    var totalCount = dimensionViewModels[0].model.count;
    var totalHeight = dimensionViewModels[0].categories
        .map(function(c) { return c.height; })
        .reduce(function(v1, v2) { return v1 + v2; });


    for(var pathNumber = 0; pathNumber < pathModels.length; pathNumber++) {
        var pathModel = pathModels[pathNumber];

        var pathHeight;
        if(totalCount > 0) {
            pathHeight = totalHeight * (pathModel.count / totalCount);
        } else {
            pathHeight = 0;
        }

        // Build path y coords
        var pathYs = new Array(nextYPositions.length);
        for(var d = 0; d < pathModel.categoryInds.length; d++) {
            var catInd = pathModel.categoryInds[d];
            var catDisplayInd = catToDisplayIndPerDim[d][catInd];
            var dimDisplayInd = dimToDisplayInd[d];

            // Update next y position
            pathYs[dimDisplayInd] = nextYPositions[dimDisplayInd][catDisplayInd];
            nextYPositions[dimDisplayInd][catDisplayInd] += pathHeight;

            // Update category color information
            var catViewModle = parcatsViewModel.dimensions[dimDisplayInd].categories[catDisplayInd];
            var numBands = catViewModle.bands.length;
            var lastCatBand = catViewModle.bands[numBands - 1];

            if(lastCatBand === undefined || pathModel.rawColor !== lastCatBand.rawColor) {
                // Create a new band
                var bandY = lastCatBand === undefined ? 0 : lastCatBand.y + lastCatBand.height;
                catViewModle.bands.push({
                    key: bandY,
                    color: pathModel.color,
                    rawColor: pathModel.rawColor,
                    height: pathHeight,
                    width: catViewModle.width,
                    count: pathModel.count,
                    y: bandY,
                    categoryViewModel: catViewModle,
                    parcatsViewModel: parcatsViewModel
                });
            } else {
                // Extend current band
                var currentBand = catViewModle.bands[numBands - 1];
                currentBand.height += pathHeight;
                currentBand.count += pathModel.count;
            }
        }

        // build svg path
        var svgD;
        if(parcatsViewModel.pathShape === 'hspline') {
            svgD = buildSvgPath(leftXPositions, pathYs, dimWidths, pathHeight, 0.5);
        } else {
            svgD = buildSvgPath(leftXPositions, pathYs, dimWidths, pathHeight, 0);
        }

        pathViewModels[pathNumber] = {
            key: pathModel.valueInds[0],
            model: pathModel,
            height: pathHeight,
            leftXs: leftXPositions,
            topYs: pathYs,
            dimWidths: dimWidths,
            svgD: svgD,
            parcatsViewModel: parcatsViewModel
        };
    }

    parcatsViewModel.paths = pathViewModels;

 // * @property key
 // *  Unique key for this model
 // * @property {PathModel} model
 // *  Source path model
 // * @property {Number} height
 // *  Height of this path (pixels)
 // * @property {String} svgD
 // *  SVG path "d" attribute string
}
Update the path view models based on the dimension view models in a ParcatsViewModel

@param {ParcatsViewModel} parcatsViewModel
 View model for trace