# Visualizing text using Markdown in Power BI Now and then, I want to add a visual to a report page that contains only text (more or less). This text may contain information already visualized using one of the many other data visualization types that are available in Power BI or is simply adding additional information. The critical aspect is that the text should also be formatted for better readability and emphasize single pieces of information. I know that this can be achieved (to some extent) using various visuals, either one of the core visuals or one of the available custom visuals. For some reasons, I think these visuals are not suitable either because they are lacking formatting/styling options or because my HTMLfoo is not strong enogh. During the MVP Summit 2025, I met Daniel Marsh-Patrick (the creator of Deneb and some other custom visuals. During one of our conversations, I mentioned the need to visualize "spiced-up" text, and here we are today: Daniel will **add a Markdown renderer to his custom visuals** (it's not there yet): + HTML Content and + HTML Content (lite) Tada! 🎉 # Why Markdown? I can not explain Markdown in more detail in this article but If you have no idea about Markdown, go here: https://www.markdownguide.org/basic-syntax/ I encounter Markdown a lot, even when writing this article because I use Obsidian for all my articles and simple notes. Obsidian is my second brain. However, Markdown is also used when we add comments inside Microsoft Fabric notebooks; you can use Markdown all over git and in many other places. For this reason, I'm much more familiar with Markdown syntax than HTML's formatting tags. I'm delighted that Daniel will bring a Markdown renderer to both versions of the HTML Content visuals; I prefer the (lite) variant because it's certified (but this is related to the defined rules in our organization). Some formatting options are not supported in Markdown, e.g., embedding a list into a table's cell; for this reason, some extra CSS styling is needed. I have to admit that I have never used CSS before; please excuse me. Admittedly, my CSS mojo is not as strong as my DAX mojo and most likely never will be. I'm pretty much confident that there will more articles where CSS styling is combined with DAX statements to create text that contains more information than the title of a bar chart 😎 # The custom visual - HTML Content (lite) I'm not familiar with the HTML Content or the HTML Content (lite) visual, because my HTML foo is not strong. If you want to learn more about the visual I recommend you to read this:https://coacervo.co/html-content-lite ## Activating the Markdown rendering method With the addition of the Markdown rendering, activating the rendering is simple (please be aware that the featute is currently not available, but will be soon): ![[Pasted image 20250328220030.png]] ## The CSS stylesheet as a measure One great feature is that I can pass my styling as a measure instead of embedding it inside each measure. This allows me to use this measure as a template across all my reports and easily adapt to organizational design requirements. My stylesheet measure looks like this (for now): ``` md - stylesheet = " table, th, td {     border: 1px solid darkgrey;     border-collapse: collapse; } .emphasis-good {    color: blue; } ul.list-squares {   list-style-type: square;   color: orange; } " ``` The next image shows how this is added to the visual: ![[Pasted image 20250328221101.png]] If you are wondering why the tags ```<style>``` and ```</style>```are missing. The definition will be injected into the overall HTML document that you can view by enabling the option "Show raw HTML." # What I did The image below shows an example of formatted text using the developer version of the HTML Content (lite) custom visual. The visual will containing the Markdown rendering capability will appear sooner rather than later. ![[Pasted image 20250328214930.png]] The above image shows a numeric slicer and the result from a single measure using the custom visual. The custom visual renders two text paragraphs that surround a table. What is special about the table is that the values of the second column are formatted as a list. Basic Markdown does not allow a list inside a table, so a little CSS styling is required. The measure: ``` md - table dynamic more CSS = -- the number of rows inside the table var topNCount = [topn Value] --all selected customer keys var allSelectedOuter = ALLSELECTED( 'DimCustomer'[CustomerKey] ) --only the topN customer var topNList =     TOPN(         topNCount,         allSelectedOuter,         [SalesAmount (ms)],         DESC     ) --the value represented by all customers var allSelectedValue = CALCULATE( [SalesAmount (ms)] , allSelectedOuter ) -- the value represented by the top n var topNValue = CALCULATE( [SalesAmount (ms)] , topNList ) -- the first paragraph -- this also shows how a class from the stylesheet is referenced and applied only to a part of the text var openingText = "The top " & topNCount & " are contributing <span class='emphasis-good'>" & format(topNValue, "#,0,,.00M") & "</span> out of " & format(allSelectedValue, "#,0,,.00M")  & unichar(10) -- the second text paragraph var closingText = "Thank you for a memorable event! Please take a moment to share your feedback and complete the event evaluation. Sessions are being made available on demand." --emedded style sheet, this is not used here because the stylesheet is injecteed to the visual, mmeaning this is only for demonstration see the measure [md - stylesheet] // var theStyleSheet = // " // <style> // table, th, td { //     border: 1px solid red; //     border-collapse: collapse; // } // .emphasis-red { //    color: red; // } // </style> // " --compsing the table var theTable =     ADDCOLUMNS(         topNList,         "topNListInner",             "<ul class='list-squares'>" & CONCATENATEX(                 TOPN(                     topNCount,                     ALLSELECTED( 'DimProduct'[ColorName] ),                     [SalesAmount (ms)],                     DESC                 ),                 "<li>" & [ColorName] & "</li>",                 ,                 [SalesAmount (ms)],                 DESC             ) & "</ul>"     ) -- the Markdown table definition -- defining the table header     var tableheader = "| CustomerKey | TopNProducts | " & unichar(10) -- table definition and text alignment of the columns var tablecreator = "|:-:|:-| " & unichar(10) -- creating the markdown table -- the following iterator is for demonstration purposes, all required Markdown can be added using a single iterator var tableMarkDown = CONCATENATEX(     theTable     ,     "|" & [CustomerKey] & "|" & [topNListInner] & "|" & unichar(10) ) -- these are fragments from an early stage, they are still here as the did not have a proper place in my second brain -- var firstrow = "|Header|<span style='color: green;'>Green</span>|" & unichar(10) -- var lastrow = "|List   |<span class='emphasis-good'>The red list</span><ul> " & aSimpleList & "</ul>|" return -- constructing the markdown document -- theStyleSheet & -- this is not used because of the style-sheet is injected to the visual as a measure openingText & unichar(10) & tableheader & tablecreator & tableMarkDown & unichar(10) & closingText ``` And this is what the measure returns when it's added to a table: ![[Pasted image 20250328224712.png]] Enjoy visualizing text! Thank you for reading, Tom # Resources + Basic Syntax Markdown: https://www.markdownguide.org/basic-syntax/ + CSS Styling: https://www.w3schools.com/css/default.asp