def cartesianProductExpander(childStructuralNode, view, depth, axisDisposition, facts, tblAxisRels, i): if i is not None: # recurse table relationships for cartesian product for j, tblRel in enumerate(tblAxisRels[i+1:]): tblObj = tblRel.toModelObject if isinstance(tblObj, (ModelEuAxisCoord, ModelDefinitionNode)) and axisDisposition == tblRel.axisDisposition: addBreakdownNode(view, axisDisposition, tblObj) #if tblObj.cardinalityAndDepth(childStructuralNode)[1] or axisDisposition == "z": if axisDisposition == "z": subOrdTblCntx = StructuralNode(childStructuralNode, tblObj, tblObj) subOrdTblCntx._choiceStructuralNodes = [] # this is a breakdwon node subOrdTblCntx.indent = 0 # separate breakdown not indented] depth = 0 # cartesian next z is also depth 0 childStructuralNode.childStructuralNodes.append(subOrdTblCntx) else: # non-ordinate composition subOrdTblCntx = childStructuralNode # predefined axes need facts sub-filtered if isinstance(childStructuralNode.definitionNode, ModelClosedDefinitionNode): matchingFacts = childStructuralNode.evaluate(childStructuralNode.definitionNode, childStructuralNode.definitionNode.filteredFacts, evalArgs=(facts,)) else: matchingFacts = facts # returns whether there were no structural node results subOrdTblCntx.abstract = True # can't be abstract across breakdown expandDefinition(view, subOrdTblCntx, tblObj, tblObj, depth, # depth + (0 if axisDisposition == 'z' else 1), axisDisposition, matchingFacts, j + i + 1, tblAxisRels) #cartesian product break
def cartesianProductExpander(childStructuralNode, view, depth, axisDisposition, facts, tblAxisRels, i): if i is not None: # recurse table relationships for cartesian product for j, tblRel in enumerate(tblAxisRels[i + 1:]): tblObj = tblRel.toModelObject if isinstance(tblObj, (ModelEuAxisCoord, ModelDefinitionNode )) and axisDisposition == tblRel.axisDisposition: #addBreakdownNode(view, axisDisposition, tblObj) #if tblObj.cardinalityAndDepth(childStructuralNode)[1] or axisDisposition == "z": if axisDisposition == "z": subOrdTblCntx = StructuralNode(childStructuralNode, tblObj, tblObj) subOrdTblCntx._choiceStructuralNodes = [ ] # this is a breakdwon node subOrdTblCntx.indent = 0 # separate breakdown not indented] depth = 0 # cartesian next z is also depth 0 childStructuralNode.childStructuredNodeList.append( subOrdTblCntx) else: # non-ordinate composition subOrdTblCntx = childStructuralNode # predefined axes need facts sub-filtered if isinstance(childStructuralNode.definitionNode, ModelClosedDefinitionNode): matchingFacts = childStructuralNode.evaluate( childStructuralNode.definitionNode, childStructuralNode.definitionNode.filteredFacts, evalArgs=(facts, )) else: matchingFacts = facts # returns whether there were no structural node results subOrdTblCntx.abstract = True # can't be abstract across breakdown expandDefinition( view, subOrdTblCntx, tblObj, tblObj, depth, # depth + (0 if axisDisposition == 'z' else 1), axisDisposition, matchingFacts, j + i + 1, tblAxisRels) #cartesian product break
def resolveTableAxesStructure(view, table, tblAxisRelSet): view.dataCols = 0 view.dataRows = 0 view.colHdrNonStdRoles = [] view.colHdrDocRow = False view.colHdrCodeRow = False view.colHdrRows = 0 view.rowHdrNonStdRoles = [] view.rowHdrCols = 0 view.rowHdrColWidth = [0,] view.rowNonAbstractHdrSpanMin = [0,] view.rowHdrDocCol = False view.rowHdrCodeCol = False view.zAxisRows = 0 view.aspectModel = table.aspectModel view.zmostOrdCntx = None view.modelTable = table view.topRollup = {"x": ROLLUP_NOT_ANALYZED, "y": ROLLUP_NOT_ANALYZED} view.aspectEntryObjectId = 0 xTopStructuralNode = yTopStructuralNode = zTopStructuralNode = None # must be cartesian product of top level relationships tblAxisRels = tblAxisRelSet.fromModelObject(table) facts = view.modelXbrl.factsInInstance view.breakdownNodes = defaultdict(list) # breakdown nodes # do z's first to set variables needed by x and y axes expressions for disposition in ("z", "x", "y"): for i, tblAxisRel in enumerate(tblAxisRels): definitionNode = tblAxisRel.toModelObject if (tblAxisRel.axisDisposition == disposition and isinstance(definitionNode, (ModelEuAxisCoord, ModelBreakdown, ModelDefinitionNode))): if disposition == "x" and xTopStructuralNode is None: xTopStructuralNode = StructuralNode(None, definitionNode, definitionNode, view.zmostOrdCntx, tableNode=table) xTopStructuralNode.hasOpenNode = False if isinstance(definitionNode,(ModelBreakdown, ModelClosedDefinitionNode)) and definitionNode.parentChildOrder is not None: addBreakdownNode(view, disposition, definitionNode) view.xTopRollup = CHILD_ROLLUP_LAST if definitionNode.parentChildOrder == "children-first" else CHILD_ROLLUP_FIRST expandDefinition(view, xTopStructuralNode, definitionNode, definitionNode, 1, disposition, facts, i, tblAxisRels) view.dataCols = xTopStructuralNode.leafNodeCount break elif disposition == "y" and yTopStructuralNode is None: yTopStructuralNode = StructuralNode(None, definitionNode, definitionNode, view.zmostOrdCntx, tableNode=table) yTopStructuralNode.hasOpenNode = False if isinstance(definitionNode,(ModelBreakdown, ModelClosedDefinitionNode)) and definitionNode.parentChildOrder is not None: addBreakdownNode(view, disposition, definitionNode) view.yAxisChildrenFirst.set(definitionNode.parentChildOrder == "children-first") view.yTopRollup = CHILD_ROLLUP_LAST if definitionNode.parentChildOrder == "children-first" else CHILD_ROLLUP_FIRST expandDefinition(view, yTopStructuralNode, definitionNode, definitionNode, 1, disposition, facts, i, tblAxisRels) view.dataRows = yTopStructuralNode.leafNodeCount break elif disposition == "z" and zTopStructuralNode is None: zTopStructuralNode = StructuralNode(None, definitionNode, definitionNode, tableNode=table) zTopStructuralNode._choiceStructuralNodes = [] zTopStructuralNode.hasOpenNode = False addBreakdownNode(view, disposition, definitionNode) expandDefinition(view, zTopStructuralNode, definitionNode, definitionNode, 1, disposition, facts, i, tblAxisRels) break ''' def jsonDefaultEncoder(obj): if isinstance(obj, StructuralNode): return {'1StructNode': str(obj), '2Depth': obj.structuralDepth, '2Group': obj.breakdownNode(view.tblELR).genLabel(), '3Label': obj.header() or obj.xlinkLabel, '4ChildNodes': obj.childStructuralNodes} raise TypeError("Type {} is not supported for json output".format(type(obj).__name__)) with io.open(r"c:\temp\test.json", 'wt') as fh: json.dump({"x":xTopStructuralNode, "y":yTopStructuralNode, "z":zTopStructuralNode}, fh, sort_keys=True, ensure_ascii=False, indent=2, default=jsonDefaultEncoder) ''' view.colHdrTopRow = view.zAxisRows + 1 # need rest if combobox used (2 if view.zAxisRows else 1) for i in range(view.rowHdrCols): if view.rowNonAbstractHdrSpanMin[i]: lastRowMinWidth = view.rowNonAbstractHdrSpanMin[i] - sum(view.rowHdrColWidth[i] for j in range(i, view.rowHdrCols - 1)) if lastRowMinWidth > view.rowHdrColWidth[view.rowHdrCols - 1]: view.rowHdrColWidth[view.rowHdrCols - 1] = lastRowMinWidth #view.rowHdrColWidth = (60,60,60,60,60,60,60,60,60,60,60,60,60,60) # use as wraplength for all row hdr name columns 200 + fixed indent and abstract mins (not incl last name col) view.rowHdrWrapLength = 200 + sum(view.rowHdrColWidth[i] for i in range(view.rowHdrCols - 1)) view.dataFirstRow = view.colHdrTopRow + view.colHdrRows + len(view.colHdrNonStdRoles) view.dataFirstCol = 1 + view.rowHdrCols + len(view.rowHdrNonStdRoles) #view.dataFirstRow = view.colHdrTopRow + view.colHdrRows + view.colHdrDocRow + view.colHdrCodeRow #view.dataFirstCol = 1 + view.rowHdrCols + view.rowHdrDocCol + view.rowHdrCodeCol #for i in range(view.dataFirstRow + view.dataRows): # view.gridView.rowconfigure(i) #for i in range(view.dataFirstCol + view.dataCols): # view.gridView.columnconfigure(i) view.modelTable = table # organize hdrNonStdRoles so code (if any) is after documentation (if any) for hdrNonStdRoles in (view.colHdrNonStdRoles, view.rowHdrNonStdRoles): iCodeRole = -1 for i, hdrNonStdRole in enumerate(hdrNonStdRoles): if 'code' in os.path.basename(hdrNonStdRole).lower(): iCodeRole = i break if iCodeRole >= 0 and len(hdrNonStdRoles) > 1 and iCodeRole < len(hdrNonStdRoles) - 1: del hdrNonStdRoles[iCodeRole] hdrNonStdRoles.append(hdrNonStdRole) if view.topRollup["x"]: view.xAxisChildrenFirst.set(view.topRollup["x"] == CHILD_ROLLUP_LAST) if view.topRollup["y"]: view.yAxisChildrenFirst.set(view.topRollup["y"] == CHILD_ROLLUP_LAST) return (tblAxisRelSet, xTopStructuralNode, yTopStructuralNode, zTopStructuralNode)
def resolveTableAxesStructure(view, table, tblAxisRelSet): view.dataCols = 0 view.dataRows = 0 view.colHdrNonStdRoles = [] view.colHdrDocRow = False view.colHdrCodeRow = False view.colHdrRows = 0 view.rowHdrNonStdRoles = [] view.rowHdrCols = 0 view.rowHdrColWidth = [ 0, ] view.rowNonAbstractHdrSpanMin = [ 0, ] view.rowHdrDocCol = False view.rowHdrCodeCol = False view.zAxisRows = 0 view.aspectModel = table.aspectModel view.zmostOrdCntx = None view.modelTable = table view.topRollup = {"x": ROLLUP_NOT_ANALYZED, "y": ROLLUP_NOT_ANALYZED} view.aspectEntryObjectId = 0 view.modelTable = table view.rendrCntx = table.renderingXPathContext xTopStructuralNode = yTopStructuralNode = zTopStructuralNode = None # must be cartesian product of top level relationships tblAxisRels = tblAxisRelSet.fromModelObject(table) facts = table.filteredFacts( view.rendrCntx, view.modelXbrl.factsInInstance) # apply table filters view.breakdownNodes = defaultdict(list) # breakdown nodes for tblAxisRel in tblAxisRels: definitionNode = tblAxisRel.toModelObject addBreakdownNode(view, tblAxisRel.axisDisposition, definitionNode) # do z's first to set variables needed by x and y axes expressions for disposition in ("z", "x", "y"): for i, tblAxisRel in enumerate(tblAxisRels): definitionNode = tblAxisRel.toModelObject if (tblAxisRel.axisDisposition == disposition and isinstance( definitionNode, (ModelEuAxisCoord, ModelBreakdown, ModelDefinitionNode))): if disposition == "x" and xTopStructuralNode is None: xTopStructuralNode = StructuralNode( None, definitionNode, definitionNode, view.zmostOrdCntx, tableNode=table, rendrCntx=view.rendrCntx) xTopStructuralNode.hasOpenNode = False if isinstance( definitionNode, (ModelBreakdown, ModelClosedDefinitionNode )) and definitionNode.parentChildOrder is not None: #addBreakdownNode(view, disposition, definitionNode) view.xTopRollup = CHILD_ROLLUP_LAST if definitionNode.parentChildOrder == "children-first" else CHILD_ROLLUP_FIRST expandDefinition(view, xTopStructuralNode, definitionNode, definitionNode, 1, disposition, facts, i, tblAxisRels) view.dataCols = xTopStructuralNode.leafNodeCount break elif disposition == "y" and yTopStructuralNode is None: yTopStructuralNode = StructuralNode( None, definitionNode, definitionNode, view.zmostOrdCntx, tableNode=table, rendrCntx=view.rendrCntx) yTopStructuralNode.hasOpenNode = False if isinstance( definitionNode, (ModelBreakdown, ModelClosedDefinitionNode )) and definitionNode.parentChildOrder is not None: #addBreakdownNode(view, disposition, definitionNode) view.yAxisChildrenFirst.set( definitionNode.parentChildOrder == "children-first") view.yTopRollup = CHILD_ROLLUP_LAST if definitionNode.parentChildOrder == "children-first" else CHILD_ROLLUP_FIRST expandDefinition(view, yTopStructuralNode, definitionNode, definitionNode, 1, disposition, facts, i, tblAxisRels) view.dataRows = yTopStructuralNode.leafNodeCount break elif disposition == "z" and zTopStructuralNode is None: zTopStructuralNode = StructuralNode( None, definitionNode, definitionNode, tableNode=table, rendrCntx=view.rendrCntx) zTopStructuralNode._choiceStructuralNodes = [] zTopStructuralNode.hasOpenNode = False #addBreakdownNode(view, disposition, definitionNode) expandDefinition(view, zTopStructuralNode, definitionNode, definitionNode, 1, disposition, facts, i, tblAxisRels) break ''' def jsonDefaultEncoder(obj): if isinstance(obj, StructuralNode): return {'1StructNode': str(obj), '2Depth': obj.structuralDepth, '2Group': obj.breakdownNode(view.tblELR).genLabel(), '3Label': obj.header() or obj.xlinkLabel, '4ChildNodes': obj.childStructuralNodes} raise TypeError("Type {} is not supported for json output".format(type(obj).__name__)) with io.open(r"c:\temp\test.json", 'wt') as fh: json.dump({"x":xTopStructuralNode, "y":yTopStructuralNode, "z":zTopStructuralNode}, fh, sort_keys=True, ensure_ascii=False, indent=2, default=jsonDefaultEncoder) ''' view.colHdrTopRow = view.zAxisRows + 1 # need rest if combobox used (2 if view.zAxisRows else 1) for i in range(view.rowHdrCols): if view.rowNonAbstractHdrSpanMin[i]: lastRowMinWidth = view.rowNonAbstractHdrSpanMin[i] - sum( view.rowHdrColWidth[i] for j in range(i, view.rowHdrCols - 1)) if lastRowMinWidth > view.rowHdrColWidth[view.rowHdrCols - 1]: view.rowHdrColWidth[view.rowHdrCols - 1] = lastRowMinWidth #view.rowHdrColWidth = (60,60,60,60,60,60,60,60,60,60,60,60,60,60) # use as wraplength for all row hdr name columns 200 + fixed indent and abstract mins (not incl last name col) view.rowHdrWrapLength = 200 + sum( view.rowHdrColWidth[:view.rowHdrCols + 1]) view.dataFirstRow = view.colHdrTopRow + view.colHdrRows + len( view.colHdrNonStdRoles) view.dataFirstCol = 1 + view.rowHdrCols + len(view.rowHdrNonStdRoles) #view.dataFirstRow = view.colHdrTopRow + view.colHdrRows + view.colHdrDocRow + view.colHdrCodeRow #view.dataFirstCol = 1 + view.rowHdrCols + view.rowHdrDocCol + view.rowHdrCodeCol #for i in range(view.dataFirstRow + view.dataRows): # view.gridView.rowconfigure(i) #for i in range(view.dataFirstCol + view.dataCols): # view.gridView.columnconfigure(i) # organize hdrNonStdRoles so code (if any) is after documentation (if any) for hdrNonStdRoles in (view.colHdrNonStdRoles, view.rowHdrNonStdRoles): iCodeRole = -1 for i, hdrNonStdRole in enumerate(hdrNonStdRoles): if 'code' in os.path.basename(hdrNonStdRole).lower(): iCodeRole = i break if iCodeRole >= 0 and len( hdrNonStdRoles) > 1 and iCodeRole < len(hdrNonStdRoles) - 1: del hdrNonStdRoles[iCodeRole] hdrNonStdRoles.append(hdrNonStdRole) if view.topRollup["x"]: view.xAxisChildrenFirst.set(view.topRollup["x"] == CHILD_ROLLUP_LAST) if view.topRollup["y"]: view.yAxisChildrenFirst.set(view.topRollup["y"] == CHILD_ROLLUP_LAST) return (tblAxisRelSet, xTopStructuralNode, yTopStructuralNode, zTopStructuralNode)