private void WriteTextBlockConcept(ConceptMember conceptMember, IDictionary <Member, FactModel> facts) { // To create a new table after the text block. var tableContext = _activeTables.Peek(); tableContext.Table = null; var xConceptH2 = CreateMemberElement(conceptMember, HtmlXNames.H2); _xActiveNetwork.Add(xConceptH2); var occupiedMembers = facts.Where(item => item.Value != null).ToList(); if (!occupiedMembers.Any()) { return; } var xValueDiv = new XElement(HtmlXNames.Div); xValueDiv.AddClass(InlineXbrlClassNames.Fact); xValueDiv.AddClass(string.Format(InlineXbrlClassNames.Level, conceptMember.Depth)); _xActiveNetwork.Add(xValueDiv); if (occupiedMembers.Count > 1) { xValueDiv.Add($"Found {occupiedMembers.Count} facts for this text block, but there should be at most one."); return; } var singleFact = occupiedMembers.First().Value; xValueDiv.Add(CreateFactElement(singleFact, conceptMember)); }
private XElement CreateHtmlTable(XmlBasedTableContext tableContext) { var xColGroup = new XElement(HtmlXNames.Colgroup); xColGroup.Add(new XElement(HtmlXNames.Col, new XAttribute("class", "concept"))); var xHeaderTr = new XElement(HtmlXNames.Tr, new XElement(HtmlXNames.Th)); foreach (var member in tableContext.LinearisedHorizontalAxis) { xColGroup.Add(new XElement(HtmlXNames.Col, new XAttribute("class", "fact"))); var xTh = new XElement(HtmlXNames.Th, CreateMemberElement(member, HtmlXNames.Div)); xHeaderTr.Add(xTh); } var xTable = new XElement(HtmlXNames.Table); xTable.AddData("horizontal-axis-role", tableContext.HorizontalAxis.Name.LocalName); xTable.AddClass(InlineXbrlClassNames.Table); xTable.Add(xColGroup); xTable.Add(new XElement(HtmlXNames.Thead, xHeaderTr)); xTable.Add(new XElement(HtmlXNames.Tbody)); _xActiveNetwork.Add(xTable); return(xTable); }
private void CreateNonFractionFactElement(XElement element, Fact fact, ConceptMember conceptMember) { var item = conceptMember.Item; element.AddClass(InlineXbrlClassNames.NonFractionFact); // Values in iXBRL are always absolute and a sign attribute is used to express a negative fact value. // This is for two reasons: // 1. There are several ways negative amounts can be rendered, e.g. leading dash, brackets, colour-coded. // 2. With negated labels, the sign of the fact value is the opposite of what is displayed. var accountingValue = fact.GetAccountingValue(item.BalanceType); var scaledAbsoluteValue = Math.Abs(accountingValue) / Math.Pow(10, _settings.Scale); var formattedValue = scaledAbsoluteValue.ToString("N", _settings.Culture); var isAccoutingValueNegative = accountingValue < 0; var decimals = _settings.Culture.NumberFormat.NumberDecimalDigits; var xNonFraction = new XElement(Namespaces.Ix + "nonFraction"); xNonFraction.SetAttributeValue("name", item.Name.ToColonSeparated(_xHtml)); xNonFraction.SetAttributeValue("contextRef", fact.GetContextId(_xHtml)); xNonFraction.SetAttributeValue("unitRef", fact.Unit.Id); xNonFraction.SetAttributeValue("scale", _settings.Scale); xNonFraction.SetAttributeValue("decimals", decimals); xNonFraction.SetAttributeValue("format", $"ixt:{_numberFormat}"); if (isAccoutingValueNegative) { xNonFraction.SetAttributeValue("sign", "-"); } xNonFraction.Value = formattedValue; element.Add(xNonFraction); var isDisplayNegative = LabelRoles.Negatives.Contains(conceptMember.PreferredLabelRole) ? !isAccoutingValueNegative : isAccoutingValueNegative; element.AddClass(isDisplayNegative ? InlineXbrlClassNames.NegativeFact : InlineXbrlClassNames.PositiveFact); if (isDisplayNegative) { element.AddFirst("("); element.Add(")"); } }
private void PopulateItemMemberElement(XElement xContainer, ItemMember itemMember) { xContainer.Value = RemoveBracketedMarkers(itemMember.Label); xContainer.AddClass(InlineXbrlClassNames.ItemMember); if (itemMember.Item.IsAbstract) { xContainer.AddClass(InlineXbrlClassNames.AbstractMember); } var conceptMember = itemMember as ConceptMember; if (conceptMember != null && LabelRoles.Totals.Contains(conceptMember.PreferredLabelRole)) { xContainer.AddClass(InlineXbrlClassNames.TotalMember); } xContainer.AddData("info", SerializeJson(CreateItemMemberInfo(itemMember))); }
private XElement CreateMemberElement(Member member, XName containerName) { var xSpan = new XElement(containerName); xSpan.AddClass(InlineXbrlClassNames.Member); xSpan.AddClass(string.Format(InlineXbrlClassNames.Level, member.Depth)); var itemMember = member as ItemMember; if (itemMember != null) { PopulateItemMemberElement(xSpan, itemMember); } else { xSpan.Value = member.ToString(_settings.Culture); } return(xSpan); }
public override void WriteBeginPresentationNetwork(PresentationNetwork presentationNetwork) { _xActiveNetwork = new XElement(HtmlXNames.Article); _xActiveNetwork.AddData("role", presentationNetwork.Role.AbsoluteUri); _xActiveNetwork.AddClass(InlineXbrlClassNames.Network); _xNetworksSection.Add(_xActiveNetwork); var xHeader = new XElement(HtmlXNames.Header, new XElement(HtmlXNames.H1, presentationNetwork.Name)); _xActiveNetwork.Add(xHeader); }
// TODO: inline HTML inside text blocks. private void CreateTextualFactElement(XElement element, Fact fact, Item item) { element.AddClass(InlineXbrlClassNames.NonNumericFact); var xNonNumeric = new XElement(Namespaces.Ix + "nonNumeric"); xNonNumeric.SetAttributeValue("name", item.Name.ToColonSeparated(_xHtml)); xNonNumeric.SetAttributeValue("contextRef", fact.GetContextId(_xHtml)); xNonNumeric.Value = fact.Value; element.Add(xNonNumeric); }
public static void ToggleClass(this XElement @this, string @class) { if (@this == null) { throw new ArgumentNullException(); } if (@this.HasClass(@class)) { @this.RemoveClass(@class); } else { @this.AddClass(@class); } }
private XElement CreateFactElement(FactModel factModel, ConceptMember conceptMember) { var item = conceptMember.Item; var xSpan = new XElement(HtmlXNames.Span); xSpan.AddClass(InlineXbrlClassNames.Fact); if (item.DataType == DataTypeRegistry.Monetary) { CreateNonFractionFactElement(xSpan, factModel.Fact, conceptMember); } else if (DataTypeRegistry.Textual.Contains(item.DataType)) { CreateTextualFactElement(xSpan, factModel.Fact, item); } return(xSpan); }