"})}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.code,{children:"onMouseEnter"}),": Shows a tooltip with complete content if the text content overflows and is truncated due to the CSS text-overflow property."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.code,{children:"onMouseLeave"}),": Hides the tooltip if it is visible."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Root
"})}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.code,{children:"onMouseLeave"}),": Hides the callout if it is visible."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"known-issues",children:"Known issues"}),"\n",(0,i.jsx)(t.h2,{id:"design-figma",children:"Design figma"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://www.figma.com/file/WOoCs0CmNYZhYl9xXeCGpi/Data-viz-(Archive)?type=design&node-id=21153-107659&mode=design&t=z2rzYs6YG3VbbVoG-4",children:"Horizontal bar chart \u2013 Figma"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://www.figma.com/file/WOoCs0CmNYZhYl9xXeCGpi/Data-viz-(Archive)?type=design&node-id=18708-74877&mode=design&t=z2rzYs6YG3VbbVoG-4",children:"Horizontal bar chart: Part to whole \u2013 Figma"})}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"learnings",children:"Learnings"}),"\n",(0,i.jsx)(t.h2,{id:"extensions",children:"Extensions"})]})}function d(e={}){const{wrapper:t}={...(0,s.a)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},2811:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/horizontalbarchart-test-coverage-debe6586d4011ebdc19688eff29c2135.png"},1151:(e,t,n)=>{n.d(t,{Z:()=>a,a:()=>o});var i=n(7294);const s={},r=i.createContext(s);function o(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/5181bfc2.1cd0a538.js b/assets/js/5181bfc2.1cd0a538.js
new file mode 100644
index 0000000000..bb0db0f7b1
--- /dev/null
+++ b/assets/js/5181bfc2.1cd0a538.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[7659],{5417:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>h});var s=n(5893),i=n(1151);const r={},a="Stacked Bar Chart",o={id:"Charting-Concepts/StackedBarChart",title:"Stacked Bar Chart",description:"A stacked bar chart is a type of data visualization that represents data using rectangular bars with lengths proportional to the values they represent. In a stacked bar chart, each bar is divided into segments, and the segments represent different categories or components. The segments are stacked next to each other to show the total value of each bar.",source:"@site/../../docs/Charting-Concepts/StackedBarChart.md",sourceDirName:"Charting-Concepts",slug:"/Charting-Concepts/StackedBarChart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/StackedBarChart",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Sparkline Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/SparklineChart"},next:{title:"Vertical Bar Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/VerticalBarChart"}},l={},h=[{value:"Use cases",id:"use-cases",level:2},{value:"Dev Design details",id:"dev-design-details",level:2},{value:"Mathematical/Geometrical concepts",id:"mathematicalgeometrical-concepts",level:2},{value:"Performance",id:"performance",level:2},{value:"Accessibility",id:"accessibility",level:2},{value:"Testing",id:"testing",level:2},{value:"Variants",id:"variants",level:2},{value:"Theming",id:"theming",level:2},{value:"Debugging",id:"debugging",level:2},{value:"Error scenarios",id:"error-scenarios",level:2},{value:"Localization aspects",id:"localization-aspects",level:2},{value:"Some notable PRs and their brief description",id:"some-notable-prs-and-their-brief-description",level:2},{value:"Future improvements",id:"future-improvements",level:2},{value:"Rendering details",id:"rendering-details",level:2},{value:"Interactions",id:"interactions",level:2},{value:"Known issues",id:"known-issues",level:2},{value:"Design figma",id:"design-figma",level:2},{value:"Learnings",id:"learnings",level:2},{value:"Extensions",id:"extensions",level:2}];function c(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"stacked-bar-chart",children:"Stacked Bar Chart"}),"\n",(0,s.jsx)(t.p,{children:"A stacked bar chart is a type of data visualization that represents data using rectangular bars with lengths proportional to the values they represent. In a stacked bar chart, each bar is divided into segments, and the segments represent different categories or components. The segments are stacked next to each other to show the total value of each bar."}),"\n",(0,s.jsx)(t.h2,{id:"use-cases",children:"Use cases"}),"\n",(0,s.jsx)(t.p,{children:"Here are some common use cases for stacked bar charts:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Tracking Trends Over Time: Show changes in category proportions over time, allowing you to analyze how the distribution of data points evolves."}),"\n",(0,s.jsx)(t.li,{children:"Highlighting Part-to-Whole Relationships: Emphasize the contribution of individual categories to the whole, helping viewers understand the significance of each component."}),"\n",(0,s.jsx)(t.li,{children:"Visualizing Survey Data: Present the distribution of responses in a survey across various answer choices for different questions, providing insights into the survey's results."}),"\n",(0,s.jsx)(t.li,{children:"Resource Allocation: Show how resources, such as budget or time, are allocated among various tasks, projects, or departments within an organization."}),"\n",(0,s.jsx)(t.li,{children:"Market Share Analysis: Illustrate the market share of different companies or products within a specific industry, helping in competitive analysis."}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"dev-design-details",children:"Dev Design details"}),"\n",(0,s.jsx)(t.p,{children:"The stacked bar chart comprises the following components and subcomponents:"}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"StackedBarChart"}),": This is the main component responsible for rendering and managing subcomponents, such as bar titles, bars, bar labels, benchmark and triangle indicators, and other components. It handles user interactions and provides the overall functionality of the chart."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"FocusZone"}),": This component facilitates focus navigation within the chart. It allows users to navigate between focusable subcomponents, such as bars and bar segments, using the tab and arrow keys."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"FocusableTooltipText"}),": This component is used to render a bar title with a tooltip. It monitors the size of the container to detect if the text content overflows. If it does, it truncates the text with ellipsis and enables users to view the tooltip with complete content by focusing or hovering over the element."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Legends"}),": Legends are a unique list of strings that identify each bar segment in the chart. The Legends component renders a button for each legend, enabling users to highlight the corresponding segment by hovering over or selecting the legend."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Callout"}),": This component functions as an anchored tip, offering additional information about the bar segment that is currently hovered over or focused without blocking the user."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"ChartHoverCard"}),": This component acts as the body of the callout, presenting relevant details in a well-organized manner."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Benchmark & Target indicators"}),": Currently, these indicators are only supported by the stacked bar chart and not the multi-stacked bar chart. They act as visual reference points, making it easier for users to compare bar values to the benchmark/target value."]}),"\n",(0,s.jsx)(t.h2,{id:"mathematicalgeometrical-concepts",children:"Mathematical/Geometrical concepts"}),"\n",(0,s.jsx)(t.p,{children:"All calculations are performed in percentages to ensure the responsiveness of the chart."}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"First, the spacing between bar segments is determined as a percentage of the chart's width when the component mounts."}),"\n",(0,s.jsx)(t.li,{children:"The total width required for all the gaps between segments is calculated by multiplying the number of gaps (which is one less than the number of segments) by the width of a single gap, as calculated previously."}),"\n",(0,s.jsx)(t.li,{children:"The sum of widths for each segment is computed, ensuring that even segments with very small values remain visible and accessible to users. This sum is always equal to or greater than 100. In the absolute-scale variant of the multi-stacked bar chart, the width percentage of each segment is calculated against the total value of the longest bar."}),"\n",(0,s.jsx)(t.li,{children:"The total width required for rendering all the segments without any gaps is derived by subtracting the total width of all the gaps from 100. A scale factor is then obtained by dividing the real length (the total width of all segments without gaps) by the scale length (the sum of segment widths). This scale factor is used to calculate the precise width of each segment."}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"performance",children:"Performance"}),"\n",(0,s.jsx)(t.h2,{id:"accessibility",children:"Accessibility"}),"\n",(0,s.jsx)(t.p,{children:"The following subcomponents are accessible using a screen reader:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Chart title
"}),": It is already accessible to screen readers."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Chart data
"}),": It is already accessible to screen readers. Users can provide a custom accessible name or description for it using the chartDataAccessibilityData prop."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Chart
"}),": The following attributes provide an accessible label for the bar."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"aria-label"})," = the bar title, which is referred to as chartTitle in the component"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Bar segment "}),": The following attributes provide an accessible description for the bar segment."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"role"}),' = "img"']}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"aria-label"}),' = "{legend}, {segmentValue}."']}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Users can customize this description using the xAxisCalloutData, yAxisCalloutData and callOutAccessibilityData props."}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Bar label "}),": The bar labels are limited to the absolute-scale variant of the multi-stacked bar chart. It is already accessible to screen readers, but the content doesn\u2019t convey complete information. The following attributes specify a different accessible name for the bar label."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"role"}),' = "img"']}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"aria-label"}),' = "Total: {barTotalValue}"']}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"testing",children:"Testing"}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Test coverage report",src:n(1968).Z+"",width:"3679",height:"1505"})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.a,{href:"/fluentui-charting-contrib/docs/Test%20Plans/StackedBarChart/ComponentTests",children:"StackedBarChart test plan"})}),"\n",(0,s.jsx)(t.h2,{id:"variants",children:"Variants"}),"\n",(0,s.jsx)(t.p,{children:"Here are the props available for customizing the stacked bar chart:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"data"}),": Use this prop to provide a series of bar data, including colors and values, to populate the chart."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"width"}),": Use this prop to set the width of the chart. If not provided, the chart will occupy the total available width."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"barHeight"}),": Use this prop to set the height of the bars in the chart. If not provided, a default bar height of 12px is used."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"hideDenominator"}),": Use this prop to hide the denominator of the chart data when it is displayed as a fraction/ratio. In the case of the multi-stacked bar chart, it takes an array of booleans with length equal to the number of bars in the chart, where each element determines whether to hide the denominator for the corresponding bar."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"benchmarkData"})," (Stacked): Use this prop to show a benchmark indicator/triangle above the bar."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"targetData"})," (Stacked): Use this prop to show a target indicator/triangle above the bar."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"hideNumberDisplay"})," (Stacked): Use this prop to hide the chart data from above the bar."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"ignoreFixStyle"})," (Stacked): By default, the chart data with a length of 1 is displayed as a number, and a length of 2 is displayed as a fraction/ratio. Use this prop to ignore the default display pattern and hide the chart data, irrespective of its length."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"hideRatio"})," (Multi-Stacked): This prop takes an array of booleans with length equal to the number of bars in the chart, where each element determines whether to hide the chart data for the corresponding bar."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"variant"})," (Multi-Stacked): Select the presentation style of the multi-stacked bar chart from the following options:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.em,{children:"MultiStackedBarChartVariant.PartToWhole"})," (default): In this variant, each bar represents a part or segment of a whole. It is excellent for showing how each category or segment contributes to the total or whole."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.em,{children:"MultiStackedBarChartVariant.AbsoluteScale"}),": In this variant, each bar's length is directly proportional to its absolute value or quantity. It is useful for comparing magnitudes across different categories."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"hideLabels"})," (Multi-Stacked): Use this prop to hide bar labels when using the AbsoluteScale variant."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["For more details, see ",(0,s.jsx)(t.a,{href:"https://developer.microsoft.com/en-us/fluentui#/controls/web/horizontalbarchart/stackedbarchart",children:"Fluent UI - Controls - React - HorizontalBarChart - Stacked"})," and ",(0,s.jsx)(t.a,{href:"https://developer.microsoft.com/en-us/fluentui#/controls/web/horizontalbarchart/multistackedbarchart",children:"Fluent UI - Controls - React - HorizontalBarChart - Multi Stacked"})]}),"\n",(0,s.jsx)(t.h2,{id:"theming",children:"Theming"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The styles file contains a function called getStyles, which returns styles for different areas or subcomponents of the chart based on the props passed to it. The base component is wrapped with the styled HOC, which passes the theme (set by the user) and the concatenated styles (obtained from the styling function and any additional styles provided by the user) as props to the base component. Within the base component, the styles are applied to corresponding elements after converting them into class names. This conversion is done by passing theme and other style props as arguments to the function returned by the classNamesFunction utility. To learn more about component styling, refer ",(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/wiki/Component-Styling",children:"this"}),"."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"debugging",children:"Debugging"}),"\n",(0,s.jsx)(t.h2,{id:"error-scenarios",children:"Error scenarios"}),"\n",(0,s.jsx)(t.h2,{id:"localization-aspects",children:"Localization aspects"}),"\n",(0,s.jsx)(t.p,{children:"Currently, the chart supports localization only for the chart data texts and the callout content."}),"\n",(0,s.jsx)(t.h2,{id:"some-notable-prs-and-their-brief-description",children:"Some notable PRs and their brief description"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/28414",children:"Focus indicator bug in bar charts by yush-singla \xb7 Pull Request #28414 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/27580",children:"Disable focus on non-interactive elements by krkshitij \xb7 Pull Request #27580 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/26082",children:"Add new variant to horizontal bar chart by krkshitij \xb7 Pull Request #26082 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/24563",children:"Fix legends selection bugs by krkshitij \xb7 Pull Request #24563 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/24835",children:"Set minimum width of 1% for multi stacked horizontal bar chart by AtishayMsft \xb7 Pull Request #24835 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/24631",children:"Fix min width of bars as 1% for horizontal bar charts by AtishayMsft \xb7 Pull Request #24631 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/21750",children:"Fix charting callout not hoverable using mouse and callout flickering by AtishayMsft \xb7 Pull Request #21750 \xb7 microsoft/fluentui (github.com)"})}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"future-improvements",children:"Future improvements"}),"\n",(0,s.jsx)(t.h2,{id:"rendering-details",children:"Rendering details"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"When no data is provided by the user, an empty div is rendered in place of the chart."}),"\n",(0,s.jsx)(t.li,{children:"By default, chart data with a length of 1 is displayed as a number, and data with a length of 2 is displayed as a fraction/ratio above the bar. However, in the absolute-scale variant of the multi-stacked bar chart, the sum of the values of all highlighted bar segments is displayed as a number beside the bar."}),"\n",(0,s.jsx)(t.li,{children:"Changes in layout direction do not affect the stacking order of the bars but rather the text anchor. Therefore, the stacking order of the bars is reversed by adjusting the x attribute according to the layout direction, making it easier for the respective users to read the chart."}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"interactions",children:"Interactions"}),"\n",(0,s.jsx)(t.p,{children:"The chart is wrapped with a FocusZone component to allow focus on its interactive subcomponents. The following subcomponents are accessible using the keyboard:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Bar segment "})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"data-is-focusable"}),": True if the hideTooltip prop is falsy."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onFocus"}),": Shows a callout near the element containing the segment details."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onBlur"}),": Does nothing."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Chart title "})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"data-is-focusable"}),": True if the text content overflows and is truncated."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onFocus"}),": Shows a tooltip with complete content."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onBlur"}),": Hides the tooltip if it is visible."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Legend "})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"data-is-focusable"}),": Depends on the allowFocusOnLegends prop, which is true by default."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onFocus"}),": Highlights the corresponding bar segment."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onBlur"}),": Unhighlights the corresponding bar segment."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Users can interact with the following subcomponents using the mouse:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Bar segment "})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onMouseOver"}),": Shows a callout near the element containing the segment details."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onMouseMove"}),": Shows the callout if it is not already visible."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onMouseLeave"}),": Does nothing."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Chart title "})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onMouseEnter"}),": Shows a tooltip with complete content if the text content overflows and is truncated."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onMouseLeave"}),": Hides the tooltip if it is visible."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Root
"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onMouseLeave"}),": Hides the callout if it is visible."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Legend
"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onMouseOver"}),": Highlights the corresponding bar segment."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onMouseOut"}),": Unhighlights the corresponding bar segment."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onClick"}),": Highlights the corresponding bar segment if the legend is not already selected, otherwise unhighlights it."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"known-issues",children:"Known issues"}),"\n",(0,s.jsx)(t.h2,{id:"design-figma",children:"Design figma"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://www.figma.com/file/WOoCs0CmNYZhYl9xXeCGpi/Data-viz-(Archive)?type=design&node-id=21153-107763&mode=design&t=Ubd0AoDYFIsZ770q-4",children:"Horizontal stacked bar chart \u2013 Figma"})}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"learnings",children:"Learnings"}),"\n",(0,s.jsx)(t.h2,{id:"extensions",children:"Extensions"})]})}function d(e={}){const{wrapper:t}={...(0,i.a)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},1968:(e,t,n)=>{n.d(t,{Z:()=>s});const s=n.p+"assets/images/stackedbarchart-test-coverage-60e746591e727d9b5a4aeadf84c995d5.png"},1151:(e,t,n)=>{n.d(t,{Z:()=>o,a:()=>a});var s=n(7294);const i={},r=s.createContext(i);function a(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/5181bfc2.b1d31591.js b/assets/js/5181bfc2.b1d31591.js
deleted file mode 100644
index 54cdef654d..0000000000
--- a/assets/js/5181bfc2.b1d31591.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[7659],{5417:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>h});var s=n(5893),i=n(1151);const r={},a="Contributor guide: Stacked Bar Chart",o={id:"Charting-Concepts/StackedBarChart",title:"Contributor guide: Stacked Bar Chart",description:"A stacked bar chart is a type of data visualization that represents data using rectangular bars with lengths proportional to the values they represent. In a stacked bar chart, each bar is divided into segments, and the segments represent different categories or components. The segments are stacked next to each other to show the total value of each bar.",source:"@site/../../docs/Charting-Concepts/StackedBarChart.md",sourceDirName:"Charting-Concepts",slug:"/Charting-Concepts/StackedBarChart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/StackedBarChart",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Contributor guide: Sparkline Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/SparklineChart"},next:{title:"Contributor guide: Vertical Bar Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/VerticalBarChart"}},l={},h=[{value:"Use cases",id:"use-cases",level:2},{value:"Dev Design details",id:"dev-design-details",level:2},{value:"Mathematical/Geometrical concepts",id:"mathematicalgeometrical-concepts",level:2},{value:"Performance",id:"performance",level:2},{value:"Accessibility",id:"accessibility",level:2},{value:"Testing",id:"testing",level:2},{value:"Variants",id:"variants",level:2},{value:"Theming",id:"theming",level:2},{value:"Debugging",id:"debugging",level:2},{value:"Error scenarios",id:"error-scenarios",level:2},{value:"Localization aspects",id:"localization-aspects",level:2},{value:"Some notable PRs and their brief description",id:"some-notable-prs-and-their-brief-description",level:2},{value:"Future improvements",id:"future-improvements",level:2},{value:"Rendering details",id:"rendering-details",level:2},{value:"Interactions",id:"interactions",level:2},{value:"Known issues",id:"known-issues",level:2},{value:"Design figma",id:"design-figma",level:2},{value:"Learnings",id:"learnings",level:2},{value:"Extensions",id:"extensions",level:2}];function c(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"contributor-guide-stacked-bar-chart",children:"Contributor guide: Stacked Bar Chart"}),"\n",(0,s.jsx)(t.p,{children:"A stacked bar chart is a type of data visualization that represents data using rectangular bars with lengths proportional to the values they represent. In a stacked bar chart, each bar is divided into segments, and the segments represent different categories or components. The segments are stacked next to each other to show the total value of each bar."}),"\n",(0,s.jsx)(t.h2,{id:"use-cases",children:"Use cases"}),"\n",(0,s.jsx)(t.p,{children:"Here are some common use cases for stacked bar charts:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Tracking Trends Over Time: Show changes in category proportions over time, allowing you to analyze how the distribution of data points evolves."}),"\n",(0,s.jsx)(t.li,{children:"Highlighting Part-to-Whole Relationships: Emphasize the contribution of individual categories to the whole, helping viewers understand the significance of each component."}),"\n",(0,s.jsx)(t.li,{children:"Visualizing Survey Data: Present the distribution of responses in a survey across various answer choices for different questions, providing insights into the survey's results."}),"\n",(0,s.jsx)(t.li,{children:"Resource Allocation: Show how resources, such as budget or time, are allocated among various tasks, projects, or departments within an organization."}),"\n",(0,s.jsx)(t.li,{children:"Market Share Analysis: Illustrate the market share of different companies or products within a specific industry, helping in competitive analysis."}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"dev-design-details",children:"Dev Design details"}),"\n",(0,s.jsx)(t.p,{children:"The stacked bar chart comprises the following components and subcomponents:"}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"StackedBarChart"}),": This is the main component responsible for rendering and managing subcomponents, such as bar titles, bars, bar labels, benchmark and triangle indicators, and other components. It handles user interactions and provides the overall functionality of the chart."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"FocusZone"}),": This component facilitates focus navigation within the chart. It allows users to navigate between focusable subcomponents, such as bars and bar segments, using the tab and arrow keys."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"FocusableTooltipText"}),": This component is used to render a bar title with a tooltip. It monitors the size of the container to detect if the text content overflows. If it does, it truncates the text with ellipsis and enables users to view the tooltip with complete content by focusing or hovering over the element."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Legends"}),": Legends are a unique list of strings that identify each bar segment in the chart. The Legends component renders a button for each legend, enabling users to highlight the corresponding segment by hovering over or selecting the legend."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Callout"}),": This component functions as an anchored tip, offering additional information about the bar segment that is currently hovered over or focused without blocking the user."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"ChartHoverCard"}),": This component acts as the body of the callout, presenting relevant details in a well-organized manner."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Benchmark & Target indicators"}),": Currently, these indicators are only supported by the stacked bar chart and not the multi-stacked bar chart. They act as visual reference points, making it easier for users to compare bar values to the benchmark/target value."]}),"\n",(0,s.jsx)(t.h2,{id:"mathematicalgeometrical-concepts",children:"Mathematical/Geometrical concepts"}),"\n",(0,s.jsx)(t.p,{children:"All calculations are performed in percentages to ensure the responsiveness of the chart."}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"First, the spacing between bar segments is determined as a percentage of the chart's width when the component mounts."}),"\n",(0,s.jsx)(t.li,{children:"The total width required for all the gaps between segments is calculated by multiplying the number of gaps (which is one less than the number of segments) by the width of a single gap, as calculated previously."}),"\n",(0,s.jsx)(t.li,{children:"The sum of widths for each segment is computed, ensuring that even segments with very small values remain visible and accessible to users. This sum is always equal to or greater than 100. In the absolute-scale variant of the multi-stacked bar chart, the width percentage of each segment is calculated against the total value of the longest bar."}),"\n",(0,s.jsx)(t.li,{children:"The total width required for rendering all the segments without any gaps is derived by subtracting the total width of all the gaps from 100. A scale factor is then obtained by dividing the real length (the total width of all segments without gaps) by the scale length (the sum of segment widths). This scale factor is used to calculate the precise width of each segment."}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"performance",children:"Performance"}),"\n",(0,s.jsx)(t.h2,{id:"accessibility",children:"Accessibility"}),"\n",(0,s.jsx)(t.p,{children:"The following subcomponents are accessible using a screen reader:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Chart title "}),": It is already accessible to screen readers."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Chart data
"}),": It is already accessible to screen readers. Users can provide a custom accessible name or description for it using the chartDataAccessibilityData prop."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Chart
"}),": The following attributes provide an accessible label for the bar."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"aria-label"})," = the bar title, which is referred to as chartTitle in the component"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Bar segment "}),": The following attributes provide an accessible description for the bar segment."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"role"}),' = "img"']}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"aria-label"}),' = "{legend}, {segmentValue}."']}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Users can customize this description using the xAxisCalloutData, yAxisCalloutData and callOutAccessibilityData props."}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Bar label "}),": The bar labels are limited to the absolute-scale variant of the multi-stacked bar chart. It is already accessible to screen readers, but the content doesn\u2019t convey complete information. The following attributes specify a different accessible name for the bar label."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"role"}),' = "img"']}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"aria-label"}),' = "Total: {barTotalValue}"']}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"testing",children:"Testing"}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Test coverage report",src:n(1968).Z+"",width:"3679",height:"1505"})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.a,{href:"/fluentui-charting-contrib/docs/Test%20Plans/StackedBarChart/ComponentTests",children:"StackedBarChart test plan"})}),"\n",(0,s.jsx)(t.h2,{id:"variants",children:"Variants"}),"\n",(0,s.jsx)(t.p,{children:"Here are the props available for customizing the stacked bar chart:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"data"}),": Use this prop to provide a series of bar data, including colors and values, to populate the chart."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"width"}),": Use this prop to set the width of the chart. If not provided, the chart will occupy the total available width."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"barHeight"}),": Use this prop to set the height of the bars in the chart. If not provided, a default bar height of 12px is used."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"hideDenominator"}),": Use this prop to hide the denominator of the chart data when it is displayed as a fraction/ratio. In the case of the multi-stacked bar chart, it takes an array of booleans with length equal to the number of bars in the chart, where each element determines whether to hide the denominator for the corresponding bar."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"benchmarkData"})," (Stacked): Use this prop to show a benchmark indicator/triangle above the bar."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"targetData"})," (Stacked): Use this prop to show a target indicator/triangle above the bar."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"hideNumberDisplay"})," (Stacked): Use this prop to hide the chart data from above the bar."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"ignoreFixStyle"})," (Stacked): By default, the chart data with a length of 1 is displayed as a number, and a length of 2 is displayed as a fraction/ratio. Use this prop to ignore the default display pattern and hide the chart data, irrespective of its length."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"hideRatio"})," (Multi-Stacked): This prop takes an array of booleans with length equal to the number of bars in the chart, where each element determines whether to hide the chart data for the corresponding bar."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"variant"})," (Multi-Stacked): Select the presentation style of the multi-stacked bar chart from the following options:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.em,{children:"MultiStackedBarChartVariant.PartToWhole"})," (default): In this variant, each bar represents a part or segment of a whole. It is excellent for showing how each category or segment contributes to the total or whole."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.em,{children:"MultiStackedBarChartVariant.AbsoluteScale"}),": In this variant, each bar's length is directly proportional to its absolute value or quantity. It is useful for comparing magnitudes across different categories."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"hideLabels"})," (Multi-Stacked): Use this prop to hide bar labels when using the AbsoluteScale variant."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["For more details, see ",(0,s.jsx)(t.a,{href:"https://developer.microsoft.com/en-us/fluentui#/controls/web/horizontalbarchart/stackedbarchart",children:"Fluent UI - Controls - React - HorizontalBarChart - Stacked"})," and ",(0,s.jsx)(t.a,{href:"https://developer.microsoft.com/en-us/fluentui#/controls/web/horizontalbarchart/multistackedbarchart",children:"Fluent UI - Controls - React - HorizontalBarChart - Multi Stacked"})]}),"\n",(0,s.jsx)(t.h2,{id:"theming",children:"Theming"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The styles file contains a function called getStyles, which returns styles for different areas or subcomponents of the chart based on the props passed to it. The base component is wrapped with the styled HOC, which passes the theme (set by the user) and the concatenated styles (obtained from the styling function and any additional styles provided by the user) as props to the base component. Within the base component, the styles are applied to corresponding elements after converting them into class names. This conversion is done by passing theme and other style props as arguments to the function returned by the classNamesFunction utility. To learn more about component styling, refer ",(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/wiki/Component-Styling",children:"this"}),"."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"debugging",children:"Debugging"}),"\n",(0,s.jsx)(t.h2,{id:"error-scenarios",children:"Error scenarios"}),"\n",(0,s.jsx)(t.h2,{id:"localization-aspects",children:"Localization aspects"}),"\n",(0,s.jsx)(t.p,{children:"Currently, the chart supports localization only for the chart data texts and the callout content."}),"\n",(0,s.jsx)(t.h2,{id:"some-notable-prs-and-their-brief-description",children:"Some notable PRs and their brief description"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/28414",children:"Focus indicator bug in bar charts by yush-singla \xb7 Pull Request #28414 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/27580",children:"Disable focus on non-interactive elements by krkshitij \xb7 Pull Request #27580 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/26082",children:"Add new variant to horizontal bar chart by krkshitij \xb7 Pull Request #26082 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/24563",children:"Fix legends selection bugs by krkshitij \xb7 Pull Request #24563 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/24835",children:"Set minimum width of 1% for multi stacked horizontal bar chart by AtishayMsft \xb7 Pull Request #24835 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/24631",children:"Fix min width of bars as 1% for horizontal bar charts by AtishayMsft \xb7 Pull Request #24631 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/21750",children:"Fix charting callout not hoverable using mouse and callout flickering by AtishayMsft \xb7 Pull Request #21750 \xb7 microsoft/fluentui (github.com)"})}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"future-improvements",children:"Future improvements"}),"\n",(0,s.jsx)(t.h2,{id:"rendering-details",children:"Rendering details"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"When no data is provided by the user, an empty div is rendered in place of the chart."}),"\n",(0,s.jsx)(t.li,{children:"By default, chart data with a length of 1 is displayed as a number, and data with a length of 2 is displayed as a fraction/ratio above the bar. However, in the absolute-scale variant of the multi-stacked bar chart, the sum of the values of all highlighted bar segments is displayed as a number beside the bar."}),"\n",(0,s.jsx)(t.li,{children:"Changes in layout direction do not affect the stacking order of the bars but rather the text anchor. Therefore, the stacking order of the bars is reversed by adjusting the x attribute according to the layout direction, making it easier for the respective users to read the chart."}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"interactions",children:"Interactions"}),"\n",(0,s.jsx)(t.p,{children:"The chart is wrapped with a FocusZone component to allow focus on its interactive subcomponents. The following subcomponents are accessible using the keyboard:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Bar segment "})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"data-is-focusable"}),": True if the hideTooltip prop is falsy."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onFocus"}),": Shows a callout near the element containing the segment details."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onBlur"}),": Does nothing."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Chart title "})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"data-is-focusable"}),": True if the text content overflows and is truncated."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onFocus"}),": Shows a tooltip with complete content."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onBlur"}),": Hides the tooltip if it is visible."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Legend "})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"data-is-focusable"}),": Depends on the allowFocusOnLegends prop, which is true by default."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onFocus"}),": Highlights the corresponding bar segment."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onBlur"}),": Unhighlights the corresponding bar segment."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Users can interact with the following subcomponents using the mouse:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Bar segment "})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onMouseOver"}),": Shows a callout near the element containing the segment details."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onMouseMove"}),": Shows the callout if it is not already visible."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onMouseLeave"}),": Does nothing."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Chart title "})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onMouseEnter"}),": Shows a tooltip with complete content if the text content overflows and is truncated."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onMouseLeave"}),": Hides the tooltip if it is visible."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Root
"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onMouseLeave"}),": Hides the callout if it is visible."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Legend
"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onMouseOver"}),": Highlights the corresponding bar segment."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onMouseOut"}),": Unhighlights the corresponding bar segment."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"onClick"}),": Highlights the corresponding bar segment if the legend is not already selected, otherwise unhighlights it."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"known-issues",children:"Known issues"}),"\n",(0,s.jsx)(t.h2,{id:"design-figma",children:"Design figma"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://www.figma.com/file/WOoCs0CmNYZhYl9xXeCGpi/Data-viz-(Archive)?type=design&node-id=21153-107763&mode=design&t=Ubd0AoDYFIsZ770q-4",children:"Horizontal stacked bar chart \u2013 Figma"})}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"learnings",children:"Learnings"}),"\n",(0,s.jsx)(t.h2,{id:"extensions",children:"Extensions"})]})}function d(e={}){const{wrapper:t}={...(0,i.a)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},1968:(e,t,n)=>{n.d(t,{Z:()=>s});const s=n.p+"assets/images/stackedbarchart-test-coverage-60e746591e727d9b5a4aeadf84c995d5.png"},1151:(e,t,n)=>{n.d(t,{Z:()=>o,a:()=>a});var s=n(7294);const i={},r=s.createContext(i);function a(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/544aba92.70e03cf8.js b/assets/js/544aba92.70e03cf8.js
deleted file mode 100644
index f3f80ab15f..0000000000
--- a/assets/js/544aba92.70e03cf8.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[774],{1264:(e,a,t)=>{t.r(a),t.d(a,{assets:()=>c,contentTitle:()=>s,default:()=>d,frontMatter:()=>n,metadata:()=>o,toc:()=>h});var i=t(5893),r=t(1151);const n={},s="Contributor guide: Area Chart",o={id:"Charting-Concepts/AreaChart",title:"Contributor guide: Area Chart",description:"Areachartpic1.png",source:"@site/../../docs/Charting-Concepts/AreaChart.md",sourceDirName:"Charting-Concepts",slug:"/Charting-Concepts/AreaChart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/AreaChart",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Detailed Implementation Steps",permalink:"/fluentui-charting-contrib/docs/Detailed Implementation Steps"},next:{title:"Contributor guide: Donut Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/DonutChart"}},c={},h=[{value:"Use cases:",id:"use-cases",level:2},{value:"Fluent Area chart also provide support for the scenarios where we need",id:"fluent-area-chart-also-provide-support-for-the-scenarios-where-we-need",level:3},{value:"Stacked Area Chart",id:"stacked-area-chart",level:3},{value:"Custom Accessibility",id:"custom-accessibility",level:3},{value:"Hover Options:",id:"hover-options",level:3},{value:"Dev Design Details",id:"dev-design-details",level:2},{value:"1.Area Chart",id:"1area-chart",level:3},{value:"2.Cartesian chart",id:"2cartesian-chart",level:3},{value:"3.ChartHover Card:",id:"3charthover-card",level:3},{value:"4.Legends:",id:"4legends",level:3},{value:"Mathematical/Geometrical concepts",id:"mathematicalgeometrical-concepts",level:2},{value:"D3-Line",id:"d3-line",level:3},{value:"D3-Area",id:"d3-area",level:3},{value:"Performance",id:"performance",level:2},{value:"Accessibility",id:"accessibility",level:2},{value:"Testingareachart4.png",id:"testingareachart4png",level:2},{value:"Variants",id:"variants",level:2},{value:"Stacked area chart:",id:"stacked-area-chart-1",level:3},{value:"Custom accessibility:",id:"custom-accessibility-1",level:3},{value:"Area chart with large dataset:",id:"area-chart-with-large-dataset",level:3},{value:"Theming",id:"theming",level:2},{value:"Debugging",id:"debugging",level:2},{value:"Error scenarios",id:"error-scenarios",level:2},{value:"The stacked area chart cannot be loaded if the x-values are not consistent across all the charts within the stack.",id:"the-stacked-area-chart-cannot-be-loaded-if-the-x-values-are-not-consistent-across-all-the-charts-within-the-stack",level:3},{value:"The chart is in a loading state because of one or more reasons below.",id:"the-chart-is-in-a-loading-state-because-of-one-or-more-reasons-below",level:3},{value:"Errors in other components:",id:"errors-in-other-components",level:3},{value:"Localization aspects",id:"localization-aspects",level:2},{value:"Date Axis localization: The axes support 2 ways of localization.",id:"date-axis-localization-the-axes-support-2-ways-of-localization",level:3},{value:"Some notable PRs and their brief description",id:"some-notable-prs-and-their-brief-description",level:2},{value:"Future improvements",id:"future-improvements",level:2},{value:"Rendering details",id:"rendering-details",level:2},{value:"Chart Hover Card -> Cartesian Chart -> Legend -> Area chart.",id:"chart-hover-card---cartesian-chart---legend---area-chart",level:3},{value:"Interactions",id:"interactions",level:2},{value:"Extension",id:"extension",level:2}];function l(e){const a={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,r.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(a.h1,{id:"contributor-guide-area-chart",children:"Contributor guide: Area Chart"}),"\n",(0,i.jsx)(a.p,{children:(0,i.jsx)(a.img,{alt:"Areachartpic1.png",src:t(7039).Z+"",width:"1440",height:"784"})}),"\n",(0,i.jsx)(a.p,{children:"Area charts are graphical representations of data that display quantitative data points connected by lines and filled with colors to create a visual representation of trends and patterns. The area between the line and the x-axis is filled, which helps in emphasizing the cumulative total or the overall magnitude of the data."}),"\n",(0,i.jsx)(a.h2,{id:"use-cases",children:"Use cases:"}),"\n",(0,i.jsx)(a.p,{children:"Area charts are used for various use cases which involve Trend Analysis, Cumulative Data, Comparing Multiple Series , Part-to-Whole Relationships , Distribution Comparison Forecasting etc."}),"\n",(0,i.jsx)(a.h3,{id:"fluent-area-chart-also-provide-support-for-the-scenarios-where-we-need",children:"Fluent Area chart also provide support for the scenarios where we need"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsxs)(a.li,{children:["\n",(0,i.jsx)(a.h3,{id:"stacked-area-chart",children:"Stacked Area Chart"}),"\n","In stacked area chart, two or more data series are stacked vertically. It helps in easy comparison across different dimensions."]}),"\n",(0,i.jsxs)(a.li,{children:["\n",(0,i.jsx)(a.h3,{id:"custom-accessibility",children:"Custom Accessibility"}),"\n","Area chart provides a bunch of props to enable custom accessibility messages.UsexAxisCalloutAccessibilityData and callOutAccessibilityData to configure x axis and y axis accessibility messages respectively"]}),"\n",(0,i.jsxs)(a.li,{children:["\n",(0,i.jsx)(a.h3,{id:"hover-options",children:"Hover Options:"}),"\n","Area chart also provide different interactive options like ChartHoverCard on hovering over some data in chart. You can customize the content of the Hover card on the basis of the requirement.\n",(0,i.jsx)(a.img,{alt:"areachartpic2.png",src:t(8476).Z+"",width:"1400",height:"740"})]}),"\n"]}),"\n",(0,i.jsx)(a.h2,{id:"dev-design-details",children:"Dev Design Details"}),"\n",(0,i.jsx)(a.p,{children:(0,i.jsx)(a.img,{alt:"Areachart3.png",src:t(826).Z+"",width:"1196",height:"860"})}),"\n",(0,i.jsx)(a.h3,{id:"1area-chart",children:"1.Area Chart"}),"\n",(0,i.jsx)(a.p,{children:"This is the main component which is responsible for invoking/using other components. This is the component which is responsible for creating area and managing user interactions with itself , Legends and Cartesian Chart."}),"\n",(0,i.jsx)(a.h3,{id:"2cartesian-chart",children:"2.Cartesian chart"}),"\n",(0,i.jsx)(a.p,{children:"This is component which is responsible for creating the X and Y Axis and the ticks for Axis. All the calculation for domain/range is done in cartesian chart. This component can be accessed through area chart. This is also manages the ChartHoverCard component ."}),"\n",(0,i.jsx)(a.h3,{id:"3charthover-card",children:"3.ChartHover Card:"}),"\n",(0,i.jsx)(a.p,{children:"ChartHoverCard is a utility in the Fluent UI web library that provides a tooltip-like experience for charts. It is a React component that can be used to display additional information about data points on a chart when the user hovers over them."}),"\n",(0,i.jsx)(a.h3,{id:"4legends",children:"4.Legends:"}),"\n",(0,i.jsx)(a.p,{children:"In the Fluent UI React charting library, a legend contains a list of the variables appearing in the chart and an example of their appearance. This information allows the data from each variable to be identified in the chart. This component is populated in Area chart component."}),"\n",(0,i.jsx)(a.h2,{id:"mathematicalgeometrical-concepts",children:"Mathematical/Geometrical concepts"}),"\n",(0,i.jsxs)(a.p,{children:["Area Chart are created using ",(0,i.jsx)(a.a,{href:"https://github.com/d3/d3-shape#readme",children:"d3-shape"}),". The main API used from this library to create line between 2 points is ",(0,i.jsx)(a.a,{href:"https://github.com/d3/d3-shape#lines",children:"d3-line"})," and ",(0,i.jsx)(a.a,{href:"https://github.com/d3/d3-shape#areas",children:"d3-area"}),"."]}),"\n",(0,i.jsx)(a.h3,{id:"d3-line",children:"D3-Line"}),"\n",(0,i.jsxs)(a.p,{children:["Line Generator are generated using a\u202f",(0,i.jsx)(a.a,{href:"https://en.wikipedia.org/wiki/Spline_(mathematics)",children:"spline"})," or ",(0,i.jsx)(a.a,{href:"https://en.wikipedia.org/wiki/Polygonal_chain",children:"polyline"})," , as in a area chart. While\u202flines \u202fare defined as a sequence of two-dimensional [x,\u202fy] points, and ",(0,i.jsx)(a.a,{href:"https://github.com/d3/d3-shape#areas",children:"areas"})," similarly defined by a topline and a baseline, there remains the task of transforming this discrete representation into a continuous shape:\u202fi.e., how to interpolate between the points. A variety of curves are provided for this purpose. The curve used to draw these lines are ",(0,i.jsx)(a.a,{href:"https://github.com/d3/d3-shape#curveLinear",children:"curveLinear"})," ."]}),"\n",(0,i.jsx)(a.h3,{id:"d3-area",children:"D3-Area"}),"\n",(0,i.jsx)(a.p,{children:"The area generator produces an area, as in an area chart. An area is defined by two bounding lines, either splines or polylines. Typically, the two lines share the same x-values (x0 = x1), differing only in y-value (y0 and y1); most commonly, y0 is defined as a constant representing zero. The first line (the topline) is defined by x1 and y1 and is rendered first; the second line (the baseline) is defined by x0 and y0 and is rendered second, with the points in reverse order. With a curveLinear curve, this produces a clockwise polygon."}),"\n",(0,i.jsx)(a.h2,{id:"performance",children:"Performance"}),"\n",(0,i.jsx)(a.p,{children:"The performance aspect of a area chart refers to how efficiently and effectively it conveys information to the viewer. Here are some key considerations regarding the performance of a area chart:"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"Data Visualization Efficiency"}),"\n",(0,i.jsx)(a.li,{children:"Clarity and Simplicity"}),"\n",(0,i.jsx)(a.li,{children:"Responsiveness"}),"\n",(0,i.jsx)(a.li,{children:"Handling Large Datasets"}),"\n",(0,i.jsx)(a.li,{children:"Interactive Features"}),"\n"]}),"\n",(0,i.jsx)(a.p,{children:"We use Lighthouse tool for measuring the performance of our charts. We have multiple scenarios against which we measure the performance score for area chart:"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"1 chart with 30k Points"}),"\n",(0,i.jsx)(a.li,{children:"6 charts,1 series with 100 data points each"}),"\n",(0,i.jsx)(a.li,{children:"18 charts,1 series 5 data points each\nLast two scenarios have 90+ LH score. We are currently working on improving the performance of the area with heavy data set (30 k Data points)."}),"\n"]}),"\n",(0,i.jsx)(a.h2,{id:"accessibility",children:"Accessibility"}),"\n",(0,i.jsx)(a.p,{children:"Following subcomponents are accessible using a screen reader:"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsxs)(a.li,{children:["Chart ",(0,i.jsx)(a.code,{children:""}),"The role is set as presentation, and the aria-label attribute is set as a string to describe its contents. This is readable by screen reader if user has given chartTitle prop"]}),"\n",(0,i.jsxs)(a.li,{children:["Points accessibility is managed by ",(0,i.jsx)(a.code,{children:""})," tags with role=\u201dimg\u201d whose accessibility is managed by aria-label property ."]}),"\n",(0,i.jsx)(a.li,{children:"Area chart provides a bunch of props to enable custom accessibility messages.Use xAxisCalloutAccessibilityData and callOutAccessibilityData to configure x axis and y axis accessibility messages respectively."}),"\n"]}),"\n",(0,i.jsxs)(a.h2,{id:"testingareachart4png",children:["Testing",(0,i.jsx)(a.img,{alt:"areachart4.png",src:t(7541).Z+"",width:"1264",height:"422"})]}),"\n",(0,i.jsx)(a.h2,{id:"variants",children:"Variants"}),"\n",(0,i.jsxs)(a.p,{children:["Different variants of area charts are available starting from the basic area chart to stacked area charts, styled area chart, area chart with custom accessibility, Area chart with large data set, area chart with data change functionality. For more details visit DemoSite ",(0,i.jsx)(a.a,{href:"https://fluentuipr.z22.web.core.windows.net/heads/master/react-charting/demo/index.html#/examples/areachart",children:"Fluent UI React Charting Examples - Area Chart (windows.net)"})]}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsxs)(a.li,{children:["\n",(0,i.jsx)(a.h3,{id:"stacked-area-chart-1",children:"Stacked area chart:"}),"\n","In stacked area chart, two or more data series are stacked vertically. It helps in easy comparison across different dimensions. The callout on hover for stacked chart displays multiple values from the stack. The callout can be customized to show single values or stacked values. Refer to the propsonRenderCalloutPerDataPoint and onRenderCalloutPerStack using which custom content for the callout can be defined."]}),"\n",(0,i.jsxs)(a.li,{children:["\n",(0,i.jsx)(a.h3,{id:"custom-accessibility-1",children:"Custom accessibility:"}),"\n","Area chart provides a bunch of props to enable custom accessibility messages.UsexAxisCalloutAccessibilityDataand callOutAccessibilityData to configure x axis and y axis accessibility messages respectively."]}),"\n",(0,i.jsxs)(a.li,{children:["\n",(0,i.jsx)(a.h3,{id:"area-chart-with-large-dataset",children:"Area chart with large dataset:"}),"\n","We provide support for smoth rendering of large data area chart."]}),"\n"]}),"\n",(0,i.jsx)(a.h2,{id:"theming",children:"Theming"}),"\n",(0,i.jsx)(a.p,{children:"The getStyles function defined in the styles file returns styles for different areas (or subcomponents) of the chart based on the props passed to it. The base component is wrapped with the styled HOC, which passes the theme (set by the user) and the concatenated styles (derived from the styling function and any additional styles provided by the user) as props to the base component. Within the base component, the styles are named as the class name. The conversion is done by passing theme and other style props as arguments to the function returned by the classNamesFunction utility. Learn more about component styling here.\nThe color prop for a segment is optional. If the color prop is not defined, a color is selected from the qualitative palette using the getNextColor utility. On the other hand, if the color prop is defined, the getColorFromToken utility is used to determine the appropriate CSS color. If the value of the color prop is a theme-specific color token from the DataVizPalette, the utility will return the corresponding CSS color. Otherwise, if the color prop is already a valid CSS color, it will be returned as is."}),"\n",(0,i.jsx)(a.h2,{id:"debugging",children:"Debugging"}),"\n",(0,i.jsx)(a.p,{children:"Our Test Suites are exhaustive to test each and every features provided with Area Charts, for debugging any particular feature these can be used respectively .Few of these tests also verify the technical aspect of rendering like there is a test suite \u201cRender calling with respective to props\u201d available in area chart test which verifies that the render is called 2 times.\nFurthermore, the fundamental debugging techniques can also be applied to Area charts. These techniques encompass:"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"Employing logging mechanisms"}),"\n",(0,i.jsx)(a.li,{children:"Utilizing the browser debugger"}),"\n",(0,i.jsx)(a.li,{children:"Leveraging browser extensions"}),"\n"]}),"\n",(0,i.jsx)(a.h2,{id:"error-scenarios",children:"Error scenarios"}),"\n",(0,i.jsx)(a.h3,{id:"the-stacked-area-chart-cannot-be-loaded-if-the-x-values-are-not-consistent-across-all-the-charts-within-the-stack",children:"The stacked area chart cannot be loaded if the x-values are not consistent across all the charts within the stack."}),"\n",(0,i.jsx)(a.p,{children:"The chart cannot be loaded because of one or more reasons:"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"Empty data passed such that chart does not have visual to show."}),"\n",(0,i.jsx)(a.li,{children:"One of the datapoint passed to the chart is corrupted. The corrupted datapoint can be for a continuous chart like line or area, or a discrete chart like bar chart, donut chart."}),"\n",(0,i.jsx)(a.li,{children:"The type of data passed to the chart is not supported."}),"\n",(0,i.jsx)(a.li,{children:"The user has not provided the required property."}),"\n"]}),"\n",(0,i.jsx)(a.h3,{id:"the-chart-is-in-a-loading-state-because-of-one-or-more-reasons-below",children:"The chart is in a loading state because of one or more reasons below."}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"The chart data is too heavy."}),"\n",(0,i.jsx)(a.li,{children:"Chart is waiting for data from a webservice."}),"\n"]}),"\n",(0,i.jsx)(a.h3,{id:"errors-in-other-components",children:"Errors in other components:"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"Empty/invalid data passed to hover callout."}),"\n",(0,i.jsx)(a.li,{children:"There is a large variation in data in one datapoint compared to others causing the graphs to become extremely skewed and non-interactable."}),"\n",(0,i.jsx)(a.li,{children:"Title for legends is not defined or is corrupted."}),"\n",(0,i.jsx)(a.li,{children:"There is more than point on y axis for the same point in x axis."}),"\n"]}),"\n",(0,i.jsx)(a.h2,{id:"localization-aspects",children:"Localization aspects"}),"\n",(0,i.jsx)(a.h3,{id:"date-axis-localization-the-axes-support-2-ways-of-localization",children:"Date Axis localization: The axes support 2 ways of localization."}),"\n",(0,i.jsxs)(a.ol,{children:["\n",(0,i.jsxs)(a.li,{children:["\n",(0,i.jsx)(a.p,{children:"Javascript provided inbuilt localization for numeric and date axis. Specify the culture and dateLocalizeOptions for date axis to define target localization. Refer theJavascript localization guidefor usage."}),"\n"]}),"\n",(0,i.jsxs)(a.li,{children:["\n",(0,i.jsx)(a.p,{children:"Custom locale definition: The consumer of the library can specify a custom locale definition as supported by d3 like this:\nThe date axis will use the date range and the multiformat specified in the definition to determine the correct labels to show in the ticks. For example - If the date range is in days then the axis will show hourly ticks. If the date range spans across months then the a xis will show months in tick labels and so on. Specify the custom locale definition in the timeFormatLocale prop. Refer to the Custom Locale Date Axis example in line chart for sample usage."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(a.h2,{id:"some-notable-prs-and-their-brief-description",children:"Some notable PRs and their brief description"}),"\n",(0,i.jsxs)(a.p,{children:[(0,i.jsx)(a.a,{href:"https://github.com/microsoft/fluentui/pull/26869",children:"Add color palette for data visualization by krkshitij \xb7 Pull Request #26869 \xb7 microsoft/fluentui (github.com)"})," -Color is optional for the data series in AreaChart and LineChart. If the color is absent, it will be picked automatically from the default color palette. New DataVizPalette provides users with theme-specific color tokens"]}),"\n",(0,i.jsxs)(a.p,{children:[(0,i.jsx)(a.a,{href:"https://github.com/microsoft/fluentui/pull/27721",children:"[2 of N] Changes for Making first render cycle faster and fixing test cases by ankityadav4 \xb7 Pull Request #27721 \xb7 microsoft/fluentui (github.com)"})," -Improving first render cycle of cartesian chart"]}),"\n",(0,i.jsxs)(a.p,{children:[(0,i.jsx)(a.a,{href:"https://github.com/microsoft/fluentui/pull/27234",children:"Make area chart keyboard accessible by krkshitij \xb7 Pull Request #27234 \xb7 microsoft/fluentui (github.com)"})," -Data points in AreaChart are accessible using keyboard"]}),"\n",(0,i.jsxs)(a.p,{children:[(0,i.jsx)(a.a,{href:"https://github.com/microsoft/fluentui/pull/27857",children:"[3 of N] Changes for lazy load for hover card and legends by ankityadav4 \xb7 Pull Request #27857 \xb7 microsoft/fluentui (github.com)"})," \u2013 Lazy loading for hover cards in cartesian charts."]}),"\n",(0,i.jsx)(a.h2,{id:"future-improvements",children:"Future improvements"}),"\n",(0,i.jsx)(a.p,{children:"We are working on Performance Improvements for area chart for large dataset scenario(30k data points)."}),"\n",(0,i.jsx)(a.h2,{id:"rendering-details",children:"Rendering details"}),"\n",(0,i.jsx)(a.p,{children:"Area Chart is a react class Component, which uses different states for managing user interaction. The various other components that are used and their relationship are shown here.The rendering order is reverse of the diagram that means the order of rendering of the components is."}),"\n",(0,i.jsx)(a.h3,{id:"chart-hover-card---cartesian-chart---legend---area-chart",children:"Chart Hover Card -> Cartesian Chart -> Legend -> Area chart."}),"\n",(0,i.jsx)(a.p,{children:"Every state change of user interaction causes different components to re-render. Example if a user hover onto the Legends then the components that will be re-rendered are Legends and then Area chart. However, if the user hovers onto a data point then the components that are re-rendered are Chart Hover Card then Cartesian Chart and then the Area Chart."}),"\n",(0,i.jsx)(a.h2,{id:"interactions",children:"Interactions"}),"\n",(0,i.jsxs)(a.p,{children:["There are various interactions that a user experiences in Area Chart which are\n",(0,i.jsx)(a.strong,{children:"1. Hover on Legends\n2. Hover on Data Points"}),"\nHovering on the legend highlights only that legend and area related to that legend.\nHovering on Data Points renders a card which highlights the nearest points and displays the value of x and all the y on it."]}),"\n",(0,i.jsx)(a.h2,{id:"extension",children:"Extension"}),"\n",(0,i.jsxs)(a.p,{children:["While working on area chart if you are exploring or adding any new things , so if you are planning to contribute or fix something related to creation of line, interaction with the chart and data related things you should start exploring ",(0,i.jsx)(a.a,{href:"https://github.com/microsoft/fluentui/tree/master/packages/react-charting/src/components/AreaChart",children:"fluentui/packages/react-charting/src/components/AreaChart at master \xb7 microsoft/fluentui (github.com)"}),"\nIf anything is related axis creation, domain range issues then one should start exploring cartesian chart code:\n",(0,i.jsx)(a.a,{href:"https://github.com/microsoft/fluentui/tree/master/packages/react-charting/src/components/CommonComponents",children:"fluentui/packages/react-charting/src/components/CommonComponents at master \xb7 microsoft/fluentui \xb7 GitHub"})]})]})}function d(e={}){const{wrapper:a}={...(0,r.a)(),...e.components};return a?(0,i.jsx)(a,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},7039:(e,a,t)=>{t.d(a,{Z:()=>i});const i=t.p+"assets/images/Areachartpic1-b4935c2435221321169a237a02618ca9.png"},8476:(e,a,t)=>{t.d(a,{Z:()=>i});const i=t.p+"assets/images/Areachartpic2-aa303ec052eb09134b5806a63b6a0451.png"},826:(e,a,t)=>{t.d(a,{Z:()=>i});const i=t.p+"assets/images/Areachartpic3-f759d8bae28dcf41be165b6f447bb7be.png"},7541:(e,a,t)=>{t.d(a,{Z:()=>i});const i=t.p+"assets/images/Areachartpic4-a7f762ab0ea882fd9482d5f59c74b208.png"},1151:(e,a,t)=>{t.d(a,{Z:()=>o,a:()=>s});var i=t(7294);const r={},n=i.createContext(r);function s(e){const a=i.useContext(n);return i.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function o(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(n.Provider,{value:a},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/544aba92.973bfd97.js b/assets/js/544aba92.973bfd97.js
new file mode 100644
index 0000000000..6733522234
--- /dev/null
+++ b/assets/js/544aba92.973bfd97.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[774],{1264:(e,a,t)=>{t.r(a),t.d(a,{assets:()=>c,contentTitle:()=>s,default:()=>d,frontMatter:()=>n,metadata:()=>o,toc:()=>h});var i=t(5893),r=t(1151);const n={},s="Area Chart",o={id:"Charting-Concepts/AreaChart",title:"Area Chart",description:"Areachartpic1.png",source:"@site/../../docs/Charting-Concepts/AreaChart.md",sourceDirName:"Charting-Concepts",slug:"/Charting-Concepts/AreaChart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/AreaChart",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Contributor Guide",permalink:"/fluentui-charting-contrib/docs/Contributor Guide"},next:{title:"Donut Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/DonutChart"}},c={},h=[{value:"Use cases:",id:"use-cases",level:2},{value:"Fluent Area chart also provide support for the scenarios where we need",id:"fluent-area-chart-also-provide-support-for-the-scenarios-where-we-need",level:3},{value:"Stacked Area Chart",id:"stacked-area-chart",level:3},{value:"Custom Accessibility",id:"custom-accessibility",level:3},{value:"Hover Options:",id:"hover-options",level:3},{value:"Dev Design Details",id:"dev-design-details",level:2},{value:"1.Area Chart",id:"1area-chart",level:3},{value:"2.Cartesian chart",id:"2cartesian-chart",level:3},{value:"3.ChartHover Card:",id:"3charthover-card",level:3},{value:"4.Legends:",id:"4legends",level:3},{value:"Mathematical/Geometrical concepts",id:"mathematicalgeometrical-concepts",level:2},{value:"D3-Line",id:"d3-line",level:3},{value:"D3-Area",id:"d3-area",level:3},{value:"Performance",id:"performance",level:2},{value:"Accessibility",id:"accessibility",level:2},{value:"Testingareachart4.png",id:"testingareachart4png",level:2},{value:"Variants",id:"variants",level:2},{value:"Stacked area chart:",id:"stacked-area-chart-1",level:3},{value:"Custom accessibility:",id:"custom-accessibility-1",level:3},{value:"Area chart with large dataset:",id:"area-chart-with-large-dataset",level:3},{value:"Theming",id:"theming",level:2},{value:"Debugging",id:"debugging",level:2},{value:"Error scenarios",id:"error-scenarios",level:2},{value:"The stacked area chart cannot be loaded if the x-values are not consistent across all the charts within the stack.",id:"the-stacked-area-chart-cannot-be-loaded-if-the-x-values-are-not-consistent-across-all-the-charts-within-the-stack",level:3},{value:"The chart is in a loading state because of one or more reasons below.",id:"the-chart-is-in-a-loading-state-because-of-one-or-more-reasons-below",level:3},{value:"Errors in other components:",id:"errors-in-other-components",level:3},{value:"Localization aspects",id:"localization-aspects",level:2},{value:"Date Axis localization: The axes support 2 ways of localization.",id:"date-axis-localization-the-axes-support-2-ways-of-localization",level:3},{value:"Some notable PRs and their brief description",id:"some-notable-prs-and-their-brief-description",level:2},{value:"Future improvements",id:"future-improvements",level:2},{value:"Rendering details",id:"rendering-details",level:2},{value:"Chart Hover Card -> Cartesian Chart -> Legend -> Area chart.",id:"chart-hover-card---cartesian-chart---legend---area-chart",level:3},{value:"Interactions",id:"interactions",level:2},{value:"Extension",id:"extension",level:2}];function l(e){const a={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,r.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(a.h1,{id:"area-chart",children:"Area Chart"}),"\n",(0,i.jsx)(a.p,{children:(0,i.jsx)(a.img,{alt:"Areachartpic1.png",src:t(7039).Z+"",width:"1440",height:"784"})}),"\n",(0,i.jsx)(a.p,{children:"Area charts are graphical representations of data that display quantitative data points connected by lines and filled with colors to create a visual representation of trends and patterns. The area between the line and the x-axis is filled, which helps in emphasizing the cumulative total or the overall magnitude of the data."}),"\n",(0,i.jsx)(a.h2,{id:"use-cases",children:"Use cases:"}),"\n",(0,i.jsx)(a.p,{children:"Area charts are used for various use cases which involve Trend Analysis, Cumulative Data, Comparing Multiple Series , Part-to-Whole Relationships , Distribution Comparison Forecasting etc."}),"\n",(0,i.jsx)(a.h3,{id:"fluent-area-chart-also-provide-support-for-the-scenarios-where-we-need",children:"Fluent Area chart also provide support for the scenarios where we need"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsxs)(a.li,{children:["\n",(0,i.jsx)(a.h3,{id:"stacked-area-chart",children:"Stacked Area Chart"}),"\n","In stacked area chart, two or more data series are stacked vertically. It helps in easy comparison across different dimensions."]}),"\n",(0,i.jsxs)(a.li,{children:["\n",(0,i.jsx)(a.h3,{id:"custom-accessibility",children:"Custom Accessibility"}),"\n","Area chart provides a bunch of props to enable custom accessibility messages.UsexAxisCalloutAccessibilityData and callOutAccessibilityData to configure x axis and y axis accessibility messages respectively"]}),"\n",(0,i.jsxs)(a.li,{children:["\n",(0,i.jsx)(a.h3,{id:"hover-options",children:"Hover Options:"}),"\n","Area chart also provide different interactive options like ChartHoverCard on hovering over some data in chart. You can customize the content of the Hover card on the basis of the requirement.\n",(0,i.jsx)(a.img,{alt:"areachartpic2.png",src:t(8476).Z+"",width:"1400",height:"740"})]}),"\n"]}),"\n",(0,i.jsx)(a.h2,{id:"dev-design-details",children:"Dev Design Details"}),"\n",(0,i.jsx)(a.p,{children:(0,i.jsx)(a.img,{alt:"Areachart3.png",src:t(826).Z+"",width:"1196",height:"860"})}),"\n",(0,i.jsx)(a.h3,{id:"1area-chart",children:"1.Area Chart"}),"\n",(0,i.jsx)(a.p,{children:"This is the main component which is responsible for invoking/using other components. This is the component which is responsible for creating area and managing user interactions with itself , Legends and Cartesian Chart."}),"\n",(0,i.jsx)(a.h3,{id:"2cartesian-chart",children:"2.Cartesian chart"}),"\n",(0,i.jsx)(a.p,{children:"This is component which is responsible for creating the X and Y Axis and the ticks for Axis. All the calculation for domain/range is done in cartesian chart. This component can be accessed through area chart. This is also manages the ChartHoverCard component ."}),"\n",(0,i.jsx)(a.h3,{id:"3charthover-card",children:"3.ChartHover Card:"}),"\n",(0,i.jsx)(a.p,{children:"ChartHoverCard is a utility in the Fluent UI web library that provides a tooltip-like experience for charts. It is a React component that can be used to display additional information about data points on a chart when the user hovers over them."}),"\n",(0,i.jsx)(a.h3,{id:"4legends",children:"4.Legends:"}),"\n",(0,i.jsx)(a.p,{children:"In the Fluent UI React charting library, a legend contains a list of the variables appearing in the chart and an example of their appearance. This information allows the data from each variable to be identified in the chart. This component is populated in Area chart component."}),"\n",(0,i.jsx)(a.h2,{id:"mathematicalgeometrical-concepts",children:"Mathematical/Geometrical concepts"}),"\n",(0,i.jsxs)(a.p,{children:["Area Chart are created using ",(0,i.jsx)(a.a,{href:"https://github.com/d3/d3-shape#readme",children:"d3-shape"}),". The main API used from this library to create line between 2 points is ",(0,i.jsx)(a.a,{href:"https://github.com/d3/d3-shape#lines",children:"d3-line"})," and ",(0,i.jsx)(a.a,{href:"https://github.com/d3/d3-shape#areas",children:"d3-area"}),"."]}),"\n",(0,i.jsx)(a.h3,{id:"d3-line",children:"D3-Line"}),"\n",(0,i.jsxs)(a.p,{children:["Line Generator are generated using a\u202f",(0,i.jsx)(a.a,{href:"https://en.wikipedia.org/wiki/Spline_(mathematics)",children:"spline"})," or ",(0,i.jsx)(a.a,{href:"https://en.wikipedia.org/wiki/Polygonal_chain",children:"polyline"})," , as in a area chart. While\u202flines \u202fare defined as a sequence of two-dimensional [x,\u202fy] points, and ",(0,i.jsx)(a.a,{href:"https://github.com/d3/d3-shape#areas",children:"areas"})," similarly defined by a topline and a baseline, there remains the task of transforming this discrete representation into a continuous shape:\u202fi.e., how to interpolate between the points. A variety of curves are provided for this purpose. The curve used to draw these lines are ",(0,i.jsx)(a.a,{href:"https://github.com/d3/d3-shape#curveLinear",children:"curveLinear"})," ."]}),"\n",(0,i.jsx)(a.h3,{id:"d3-area",children:"D3-Area"}),"\n",(0,i.jsx)(a.p,{children:"The area generator produces an area, as in an area chart. An area is defined by two bounding lines, either splines or polylines. Typically, the two lines share the same x-values (x0 = x1), differing only in y-value (y0 and y1); most commonly, y0 is defined as a constant representing zero. The first line (the topline) is defined by x1 and y1 and is rendered first; the second line (the baseline) is defined by x0 and y0 and is rendered second, with the points in reverse order. With a curveLinear curve, this produces a clockwise polygon."}),"\n",(0,i.jsx)(a.h2,{id:"performance",children:"Performance"}),"\n",(0,i.jsx)(a.p,{children:"The performance aspect of a area chart refers to how efficiently and effectively it conveys information to the viewer. Here are some key considerations regarding the performance of a area chart:"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"Data Visualization Efficiency"}),"\n",(0,i.jsx)(a.li,{children:"Clarity and Simplicity"}),"\n",(0,i.jsx)(a.li,{children:"Responsiveness"}),"\n",(0,i.jsx)(a.li,{children:"Handling Large Datasets"}),"\n",(0,i.jsx)(a.li,{children:"Interactive Features"}),"\n"]}),"\n",(0,i.jsx)(a.p,{children:"We use Lighthouse tool for measuring the performance of our charts. We have multiple scenarios against which we measure the performance score for area chart:"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"1 chart with 30k Points"}),"\n",(0,i.jsx)(a.li,{children:"6 charts,1 series with 100 data points each"}),"\n",(0,i.jsx)(a.li,{children:"18 charts,1 series 5 data points each\nLast two scenarios have 90+ LH score. We are currently working on improving the performance of the area with heavy data set (30 k Data points)."}),"\n"]}),"\n",(0,i.jsx)(a.h2,{id:"accessibility",children:"Accessibility"}),"\n",(0,i.jsx)(a.p,{children:"Following subcomponents are accessible using a screen reader:"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsxs)(a.li,{children:["Chart ",(0,i.jsx)(a.code,{children:""}),"The role is set as presentation, and the aria-label attribute is set as a string to describe its contents. This is readable by screen reader if user has given chartTitle prop"]}),"\n",(0,i.jsxs)(a.li,{children:["Points accessibility is managed by ",(0,i.jsx)(a.code,{children:""})," tags with role=\u201dimg\u201d whose accessibility is managed by aria-label property ."]}),"\n",(0,i.jsx)(a.li,{children:"Area chart provides a bunch of props to enable custom accessibility messages.Use xAxisCalloutAccessibilityData and callOutAccessibilityData to configure x axis and y axis accessibility messages respectively."}),"\n"]}),"\n",(0,i.jsxs)(a.h2,{id:"testingareachart4png",children:["Testing",(0,i.jsx)(a.img,{alt:"areachart4.png",src:t(7541).Z+"",width:"1264",height:"422"})]}),"\n",(0,i.jsx)(a.h2,{id:"variants",children:"Variants"}),"\n",(0,i.jsxs)(a.p,{children:["Different variants of area charts are available starting from the basic area chart to stacked area charts, styled area chart, area chart with custom accessibility, Area chart with large data set, area chart with data change functionality. For more details visit DemoSite ",(0,i.jsx)(a.a,{href:"https://fluentuipr.z22.web.core.windows.net/heads/master/react-charting/demo/index.html#/examples/areachart",children:"Fluent UI React Charting Examples - Area Chart (windows.net)"})]}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsxs)(a.li,{children:["\n",(0,i.jsx)(a.h3,{id:"stacked-area-chart-1",children:"Stacked area chart:"}),"\n","In stacked area chart, two or more data series are stacked vertically. It helps in easy comparison across different dimensions. The callout on hover for stacked chart displays multiple values from the stack. The callout can be customized to show single values or stacked values. Refer to the propsonRenderCalloutPerDataPoint and onRenderCalloutPerStack using which custom content for the callout can be defined."]}),"\n",(0,i.jsxs)(a.li,{children:["\n",(0,i.jsx)(a.h3,{id:"custom-accessibility-1",children:"Custom accessibility:"}),"\n","Area chart provides a bunch of props to enable custom accessibility messages.UsexAxisCalloutAccessibilityDataand callOutAccessibilityData to configure x axis and y axis accessibility messages respectively."]}),"\n",(0,i.jsxs)(a.li,{children:["\n",(0,i.jsx)(a.h3,{id:"area-chart-with-large-dataset",children:"Area chart with large dataset:"}),"\n","We provide support for smoth rendering of large data area chart."]}),"\n"]}),"\n",(0,i.jsx)(a.h2,{id:"theming",children:"Theming"}),"\n",(0,i.jsx)(a.p,{children:"The getStyles function defined in the styles file returns styles for different areas (or subcomponents) of the chart based on the props passed to it. The base component is wrapped with the styled HOC, which passes the theme (set by the user) and the concatenated styles (derived from the styling function and any additional styles provided by the user) as props to the base component. Within the base component, the styles are named as the class name. The conversion is done by passing theme and other style props as arguments to the function returned by the classNamesFunction utility. Learn more about component styling here.\nThe color prop for a segment is optional. If the color prop is not defined, a color is selected from the qualitative palette using the getNextColor utility. On the other hand, if the color prop is defined, the getColorFromToken utility is used to determine the appropriate CSS color. If the value of the color prop is a theme-specific color token from the DataVizPalette, the utility will return the corresponding CSS color. Otherwise, if the color prop is already a valid CSS color, it will be returned as is."}),"\n",(0,i.jsx)(a.h2,{id:"debugging",children:"Debugging"}),"\n",(0,i.jsx)(a.p,{children:"Our Test Suites are exhaustive to test each and every features provided with Area Charts, for debugging any particular feature these can be used respectively .Few of these tests also verify the technical aspect of rendering like there is a test suite \u201cRender calling with respective to props\u201d available in area chart test which verifies that the render is called 2 times.\nFurthermore, the fundamental debugging techniques can also be applied to Area charts. These techniques encompass:"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"Employing logging mechanisms"}),"\n",(0,i.jsx)(a.li,{children:"Utilizing the browser debugger"}),"\n",(0,i.jsx)(a.li,{children:"Leveraging browser extensions"}),"\n"]}),"\n",(0,i.jsx)(a.h2,{id:"error-scenarios",children:"Error scenarios"}),"\n",(0,i.jsx)(a.h3,{id:"the-stacked-area-chart-cannot-be-loaded-if-the-x-values-are-not-consistent-across-all-the-charts-within-the-stack",children:"The stacked area chart cannot be loaded if the x-values are not consistent across all the charts within the stack."}),"\n",(0,i.jsx)(a.p,{children:"The chart cannot be loaded because of one or more reasons:"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"Empty data passed such that chart does not have visual to show."}),"\n",(0,i.jsx)(a.li,{children:"One of the datapoint passed to the chart is corrupted. The corrupted datapoint can be for a continuous chart like line or area, or a discrete chart like bar chart, donut chart."}),"\n",(0,i.jsx)(a.li,{children:"The type of data passed to the chart is not supported."}),"\n",(0,i.jsx)(a.li,{children:"The user has not provided the required property."}),"\n"]}),"\n",(0,i.jsx)(a.h3,{id:"the-chart-is-in-a-loading-state-because-of-one-or-more-reasons-below",children:"The chart is in a loading state because of one or more reasons below."}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"The chart data is too heavy."}),"\n",(0,i.jsx)(a.li,{children:"Chart is waiting for data from a webservice."}),"\n"]}),"\n",(0,i.jsx)(a.h3,{id:"errors-in-other-components",children:"Errors in other components:"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"Empty/invalid data passed to hover callout."}),"\n",(0,i.jsx)(a.li,{children:"There is a large variation in data in one datapoint compared to others causing the graphs to become extremely skewed and non-interactable."}),"\n",(0,i.jsx)(a.li,{children:"Title for legends is not defined or is corrupted."}),"\n",(0,i.jsx)(a.li,{children:"There is more than point on y axis for the same point in x axis."}),"\n"]}),"\n",(0,i.jsx)(a.h2,{id:"localization-aspects",children:"Localization aspects"}),"\n",(0,i.jsx)(a.h3,{id:"date-axis-localization-the-axes-support-2-ways-of-localization",children:"Date Axis localization: The axes support 2 ways of localization."}),"\n",(0,i.jsxs)(a.ol,{children:["\n",(0,i.jsxs)(a.li,{children:["\n",(0,i.jsx)(a.p,{children:"Javascript provided inbuilt localization for numeric and date axis. Specify the culture and dateLocalizeOptions for date axis to define target localization. Refer theJavascript localization guidefor usage."}),"\n"]}),"\n",(0,i.jsxs)(a.li,{children:["\n",(0,i.jsx)(a.p,{children:"Custom locale definition: The consumer of the library can specify a custom locale definition as supported by d3 like this:\nThe date axis will use the date range and the multiformat specified in the definition to determine the correct labels to show in the ticks. For example - If the date range is in days then the axis will show hourly ticks. If the date range spans across months then the a xis will show months in tick labels and so on. Specify the custom locale definition in the timeFormatLocale prop. Refer to the Custom Locale Date Axis example in line chart for sample usage."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(a.h2,{id:"some-notable-prs-and-their-brief-description",children:"Some notable PRs and their brief description"}),"\n",(0,i.jsxs)(a.p,{children:[(0,i.jsx)(a.a,{href:"https://github.com/microsoft/fluentui/pull/26869",children:"Add color palette for data visualization by krkshitij \xb7 Pull Request #26869 \xb7 microsoft/fluentui (github.com)"})," -Color is optional for the data series in AreaChart and LineChart. If the color is absent, it will be picked automatically from the default color palette. New DataVizPalette provides users with theme-specific color tokens"]}),"\n",(0,i.jsxs)(a.p,{children:[(0,i.jsx)(a.a,{href:"https://github.com/microsoft/fluentui/pull/27721",children:"[2 of N] Changes for Making first render cycle faster and fixing test cases by ankityadav4 \xb7 Pull Request #27721 \xb7 microsoft/fluentui (github.com)"})," -Improving first render cycle of cartesian chart"]}),"\n",(0,i.jsxs)(a.p,{children:[(0,i.jsx)(a.a,{href:"https://github.com/microsoft/fluentui/pull/27234",children:"Make area chart keyboard accessible by krkshitij \xb7 Pull Request #27234 \xb7 microsoft/fluentui (github.com)"})," -Data points in AreaChart are accessible using keyboard"]}),"\n",(0,i.jsxs)(a.p,{children:[(0,i.jsx)(a.a,{href:"https://github.com/microsoft/fluentui/pull/27857",children:"[3 of N] Changes for lazy load for hover card and legends by ankityadav4 \xb7 Pull Request #27857 \xb7 microsoft/fluentui (github.com)"})," \u2013 Lazy loading for hover cards in cartesian charts."]}),"\n",(0,i.jsx)(a.h2,{id:"future-improvements",children:"Future improvements"}),"\n",(0,i.jsx)(a.p,{children:"We are working on Performance Improvements for area chart for large dataset scenario(30k data points)."}),"\n",(0,i.jsx)(a.h2,{id:"rendering-details",children:"Rendering details"}),"\n",(0,i.jsx)(a.p,{children:"Area Chart is a react class Component, which uses different states for managing user interaction. The various other components that are used and their relationship are shown here.The rendering order is reverse of the diagram that means the order of rendering of the components is."}),"\n",(0,i.jsx)(a.h3,{id:"chart-hover-card---cartesian-chart---legend---area-chart",children:"Chart Hover Card -> Cartesian Chart -> Legend -> Area chart."}),"\n",(0,i.jsx)(a.p,{children:"Every state change of user interaction causes different components to re-render. Example if a user hover onto the Legends then the components that will be re-rendered are Legends and then Area chart. However, if the user hovers onto a data point then the components that are re-rendered are Chart Hover Card then Cartesian Chart and then the Area Chart."}),"\n",(0,i.jsx)(a.h2,{id:"interactions",children:"Interactions"}),"\n",(0,i.jsxs)(a.p,{children:["There are various interactions that a user experiences in Area Chart which are\n",(0,i.jsx)(a.strong,{children:"1. Hover on Legends\n2. Hover on Data Points"}),"\nHovering on the legend highlights only that legend and area related to that legend.\nHovering on Data Points renders a card which highlights the nearest points and displays the value of x and all the y on it."]}),"\n",(0,i.jsx)(a.h2,{id:"extension",children:"Extension"}),"\n",(0,i.jsxs)(a.p,{children:["While working on area chart if you are exploring or adding any new things , so if you are planning to contribute or fix something related to creation of line, interaction with the chart and data related things you should start exploring ",(0,i.jsx)(a.a,{href:"https://github.com/microsoft/fluentui/tree/master/packages/react-charting/src/components/AreaChart",children:"fluentui/packages/react-charting/src/components/AreaChart at master \xb7 microsoft/fluentui (github.com)"}),"\nIf anything is related axis creation, domain range issues then one should start exploring cartesian chart code:\n",(0,i.jsx)(a.a,{href:"https://github.com/microsoft/fluentui/tree/master/packages/react-charting/src/components/CommonComponents",children:"fluentui/packages/react-charting/src/components/CommonComponents at master \xb7 microsoft/fluentui \xb7 GitHub"})]})]})}function d(e={}){const{wrapper:a}={...(0,r.a)(),...e.components};return a?(0,i.jsx)(a,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},7039:(e,a,t)=>{t.d(a,{Z:()=>i});const i=t.p+"assets/images/Areachartpic1-b4935c2435221321169a237a02618ca9.png"},8476:(e,a,t)=>{t.d(a,{Z:()=>i});const i=t.p+"assets/images/Areachartpic2-aa303ec052eb09134b5806a63b6a0451.png"},826:(e,a,t)=>{t.d(a,{Z:()=>i});const i=t.p+"assets/images/Areachartpic3-f759d8bae28dcf41be165b6f447bb7be.png"},7541:(e,a,t)=>{t.d(a,{Z:()=>i});const i=t.p+"assets/images/Areachartpic4-a7f762ab0ea882fd9482d5f59c74b208.png"},1151:(e,a,t)=>{t.d(a,{Z:()=>o,a:()=>s});var i=t(7294);const r={},n=i.createContext(r);function s(e){const a=i.useContext(n);return i.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function o(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(n.Provider,{value:a},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/62692344.29aaf915.js b/assets/js/62692344.29aaf915.js
new file mode 100644
index 0000000000..528eff03f2
--- /dev/null
+++ b/assets/js/62692344.29aaf915.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[9330],{4520:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>h,contentTitle:()=>r,default:()=>d,frontMatter:()=>s,metadata:()=>o,toc:()=>l});var i=t(5893),a=t(1151);const s={},r="Line Chart",o={id:"Charting-Concepts/LineChart",title:"Line Chart",description:"Line charts are a versatile type of graph used to visualize data trends over time. They are commonly used in various fields and industries for different purposes.",source:"@site/../../docs/Charting-Concepts/LineChart.md",sourceDirName:"Charting-Concepts",slug:"/Charting-Concepts/LineChart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/LineChart",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Horizontal Bar Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/HorizontalBarChart"},next:{title:"Sankey Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/SankeyChart"}},h={},l=[{value:"Use cases:",id:"use-cases",level:2},{value:"Fluent Line chart also provide support for the scenarios where we need",id:"fluent-line-chart-also-provide-support-for-the-scenarios-where-we-need",level:3},{value:"Gaps",id:"gaps",level:3},{value:"Event annotations",id:"event-annotations",level:3},{value:"Lines with large dataset",id:"lines-with-large-dataset",level:3},{value:"Dev Design details",id:"dev-design-details",level:2},{value:"1. Line Chart",id:"1-line-chart",level:3},{value:"2. Cartesian chart",id:"2-cartesian-chart",level:3},{value:"3. ChartHover Card",id:"3-charthover-card",level:3},{value:"4 .Legends",id:"4-legends",level:3},{value:"5.Line border",id:"5line-border",level:3},{value:"Mathematical/Geometrical concepts",id:"mathematicalgeometrical-concepts",level:2},{value:"D3-Line",id:"d3-line",level:3},{value:"Performance",id:"performance",level:2},{value:"Accessibility",id:"accessibility",level:2},{value:"Testing",id:"testing",level:2},{value:"Variants",id:"variants",level:2},{value:"Event annotations",id:"event-annotations-1",level:3},{value:"Gaps",id:"gaps-1",level:3},{value:"Lines with large dataset",id:"lines-with-large-dataset-1",level:3},{value:"Theming",id:"theming",level:2},{value:"Debugging",id:"debugging",level:2},{value:"Error scenarios",id:"error-scenarios",level:2},{value:"The chart cannot be loaded because of one or more reasons:\u202f",id:"the-chart-cannot-be-loaded-because-of-one-or-more-reasons",level:3},{value:"The chart is in a loading state because of one or more reasons below.\u202f",id:"the-chart-is-in-a-loading-state-because-of-one-or-more-reasons-below",level:3},{value:"Extremely high density:\u202f",id:"extremely-high-density",level:3},{value:"Errors in other components:\u202f",id:"errors-in-other-components",level:3},{value:"Localization aspects",id:"localization-aspects",level:2},{value:"Date Axis localization: The axes support 2 ways of localization.",id:"date-axis-localization-the-axes-support-2-ways-of-localization",level:3}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,a.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"line-chart",children:"Line Chart"}),"\n",(0,i.jsx)(n.p,{children:"Line charts are a versatile type of graph used to visualize data trends over time. They are commonly used in various fields and industries for different purposes."}),"\n",(0,i.jsx)(n.h2,{id:"use-cases",children:"Use cases:"}),"\n",(0,i.jsx)(n.p,{children:"Line charts are used for various use cases which involve Trend Analysis, Performance Monitoring , Comparisions , Forecasting , Monitoring Changes , Communicating Data etc."}),"\n",(0,i.jsx)(n.h3,{id:"fluent-line-chart-also-provide-support-for-the-scenarios-where-we-need",children:"Fluent Line chart also provide support for the scenarios where we need"}),"\n",(0,i.jsx)(n.h3,{id:"gaps",children:"Gaps"}),"\n",(0,i.jsx)(n.p,{children:"A line chart can have gaps/breaks in between. This is to represent missing data. The gaps can also be replaced with dashed or dotted lines for specific scenarios, say to represent low confidence predictions for a time series forecast graph."}),"\n",(0,i.jsx)(n.h3,{id:"event-annotations",children:"Event annotations"}),"\n",(0,i.jsx)(n.p,{children:"Event annotations are used to highlight events and annotate them using messages."}),"\n",(0,i.jsx)(n.h3,{id:"lines-with-large-dataset",children:"Lines with large dataset"}),"\n",(0,i.jsx)(n.p,{children:"We use a path based rendering technique to show datasets with large number of points (greater than 1k)."}),"\n",(0,i.jsx)(n.h2,{id:"dev-design-details",children:"Dev Design details"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"LineChartContrib.png",src:t(7633).Z+"",width:"1150",height:"826"})}),"\n",(0,i.jsx)(n.p,{children:"Fig A: Representing Charting Lib Components Relationships and Functionality."}),"\n",(0,i.jsx)(n.p,{children:"Line chart comprises of other charting components as shown above, these are:"}),"\n",(0,i.jsx)(n.h3,{id:"1-line-chart",children:"1. Line Chart"}),"\n",(0,i.jsx)(n.p,{children:"This is the main component which is responsible for invoking/using other components. This is the component which is responsible for creating lines , event annotations, gaps and managing user interactions with itself , Legends and Cartesian Chart."}),"\n",(0,i.jsx)(n.h3,{id:"2-cartesian-chart",children:"2. Cartesian chart"}),"\n",(0,i.jsx)(n.p,{children:"This is component which is responsible for creating the X and Y Axis and the ticks for Axis. All the calculation for domain/range is done in cartesian chart. This component can be accessed through line chart. This is also manages the ChartHoverCard component ."}),"\n",(0,i.jsx)(n.h3,{id:"3-charthover-card",children:"3. ChartHover Card"}),"\n",(0,i.jsx)(n.p,{children:"ChartHoverCard is a utility in the Fluent UI web library that provides a tooltip-like experience for charts. It is a React component that can be used to display additional information about data points on a chart when the user hovers over them."}),"\n",(0,i.jsx)(n.h3,{id:"4-legends",children:"4 .Legends"}),"\n",(0,i.jsx)(n.p,{children:"In the Fluent UI React charting library, a legend contains a list of the variables appearing in the chart and an example of their appearance.\u202fThis information allows the data from each variable to be identified in the chart. This component is populated in Line chart component."}),"\n",(0,i.jsx)(n.h3,{id:"5line-border",children:"5.Line border"}),"\n",(0,i.jsx)(n.p,{children:"Each line in the chart can contain a 2 px border for better highlighting of the line when there are multiple items in the chart. The border will have color of the background theme. Lines will be highlighted in order of their appearance in legends. Line border is a highly suggested style that you should apply to make multiple lines more distinguishable from each other. Use lineBorderWidth prop present insidelineOptions to enable it."}),"\n",(0,i.jsx)(n.h2,{id:"mathematicalgeometrical-concepts",children:"Mathematical/Geometrical concepts"}),"\n",(0,i.jsxs)(n.p,{children:["Line Chart are created using ",(0,i.jsx)(n.a,{href:"https://github.com/d3/d3-shape#readme",children:"d3-shape"})," . The main API used from this library to create line between 2 points is ",(0,i.jsx)(n.a,{href:"https://github.com/d3/d3-shape#lines",children:"d3-line"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://github.com/d3/d3-shape#lines",children:"d3-line"})," is used only when the property optimizeLargeData is enabled , we use the spline and interpolation to generate a continuous line, when the dataset is huge(>10k points)."]}),"\n",(0,i.jsxs)(n.p,{children:["In case of a smaller dataset, line chart builds the lines using the ",(0,i.jsx)(n.a,{href:"https://www.w3schools.com/graphics/svg_line.asp",children:"SVG line"})," element. In such cases, the chart renders a line segment connecting each adjacent pair of coordinates."]}),"\n",(0,i.jsx)(n.h3,{id:"d3-line",children:"D3-Line"}),"\n",(0,i.jsxs)(n.p,{children:["Line Generator are generated using a\u202f",(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Spline_(mathematics)",children:"spline"}),"\u202for\u202f",(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Polygonal_chain",children:"polyline"}),", as in a line chart. Lines also appear in many other visualization types, such as the links in\u202f",(0,i.jsx)(n.a,{href:"https://observablehq.com/@d3/hierarchical-edge-bundling",children:"hierarchical edge bundling"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["While\u202f",(0,i.jsx)(n.a,{href:"https://github.com/d3/d3-shape#lines",children:"lines"}),"\u202fare defined as a sequence of two-dimensional [x,\u202fy] points, and\u202f",(0,i.jsx)(n.a,{href:"https://github.com/d3/d3-shape#areas",children:"areas"}),"\u202fare similarly defined by a topline and a baseline, there remains the task of transforming this discrete representation into a continuous shape:\u202fi.e., how to interpolate between the points. A variety of curves are provided for this purpose. The curve used to draw these lines are ",(0,i.jsx)(n.a,{href:"https://github.com/d3/d3-shape#curveLinear",children:"curveLinear"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"performance",children:"Performance"}),"\n",(0,i.jsx)(n.p,{children:"The performance aspect of a line chart refers to how efficiently and effectively it conveys information to the viewer. Here are some key considerations regarding the performance of a line chart:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Data Visualization Efficiency"}),"\n",(0,i.jsx)(n.li,{children:"Clarity and Simplicity"}),"\n",(0,i.jsx)(n.li,{children:"Responsiveness"}),"\n",(0,i.jsx)(n.li,{children:"Handling Large Datasets"}),"\n",(0,i.jsx)(n.li,{children:"Interactive Features"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"We use Lighthouse tool for measuring the performance of our charts. We have multiple scenarios against which we measure the performance score for line chart:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"1 chart with 30k Points"}),"\n",(0,i.jsx)(n.li,{children:"6 charts,1 series with 100 data points each"}),"\n",(0,i.jsx)(n.li,{children:"18 charts,1 series 5 data points each"}),"\n",(0,i.jsx)(n.li,{children:"1 chart ,1 series with 1000 data points each"}),"\n",(0,i.jsx)(n.li,{children:"50 charts, 1 Series with 10 data points each"}),"\n",(0,i.jsx)(n.li,{children:"1 chart, 2 series with 500 data points each"}),"\n",(0,i.jsx)(n.li,{children:"10 charts ,1 series with 1000 data points each"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Most of above scenarios have 90+ Lighthouse score. If we talk about the 30k data point has Lighthouse score close to 85. We are efficient in terms of the performance of the line chart."}),"\n",(0,i.jsx)(n.p,{children:"We have 2 rendering methods for the line chart. one of the method is optimized for large datasets and is controlled by the optimizeLargeData property. Enable this rendering method by setting the\u202foptimizeLargeData\u202fprop to\u202ftrue this will help in improving the performance for your large data set."}),"\n",(0,i.jsx)(n.h2,{id:"accessibility",children:"Accessibility"}),"\n",(0,i.jsx)(n.p,{children:"Following subcomponents are accessible using a screen reader:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Chart ",(0,i.jsx)(n.code,{children:""}),"The role is set as presentation, and the aria-label attribute is set as a string to describe its contents. This is readable by screen reader if user has given chartTitle prop"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["eventAnnotation accessibility is managed by EventAnnotation sub componnets which internally uses ",(0,i.jsx)(n.code,{children:""})," hence the labels provided in IEvenetAnnotaionProps will be read by screen reader."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Points accessibility is managed by ",(0,i.jsx)(n.code,{children:""})," tags with role=\u201dimg\u201d whose accessibility is managed by aria-label property ."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Line chart provides a bunch of props to enable custom accessibility messages. UsexAxisCalloutAccessibilityData and callOutAccessibilityData to configure x axis and y axis accessibility messages respectively."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"testing",children:"Testing"}),"\n",(0,i.jsx)(n.h2,{id:"variants",children:"Variants"}),"\n",(0,i.jsxs)(n.p,{children:["Different variants of line charts are available starting from the basic line chart to multiple line charts, line chart with event, line chart with custom accessibility, Line chart with large data set, line chart with gaps and custom date axis locale. For more details visit DemoSite ",(0,i.jsx)(n.a,{href:"https://fluentuipr.z22.web.core.windows.net/heads/master/react-charting/demo/index.html#/examples/linechart",children:"Fluent UI React Charting Examples - Line Chart (windows.net)"})]}),"\n",(0,i.jsx)(n.p,{children:"Below are details for using the above variants:"}),"\n",(0,i.jsx)(n.h3,{id:"event-annotations-1",children:"Event annotations"}),"\n",(0,i.jsx)(n.p,{children:"Event annotations are used to highlight events and annotate them using messages.. Events can be added by using eventAnnotationProps prop. Each event contains adate, event message and event details callout callbackonRenderCard"}),"\n",(0,i.jsx)(n.h3,{id:"gaps-1",children:"Gaps"}),"\n",(0,i.jsx)(n.p,{children:"A line chart can have gaps/breaks in between. Gaps can be added by using gaps prop. A gap is denoted bystartIndex andendIndex datapoints in the line. A line will be drawn uptil the startIndex and skipped forendIndex - startIndex number of datapoints. A line can have as many gaps as possible."}),"\n",(0,i.jsx)(n.h3,{id:"lines-with-large-dataset-1",children:"Lines with large dataset"}),"\n",(0,i.jsx)(n.p,{children:"We use a path based rendering technique to show datasets with large number of points (greater than 1k). Using this technique datasets with over 10k points can be rendered easily. Enable this rendering method by setting the optimizeLargeData prop to true."}),"\n",(0,i.jsx)(n.h2,{id:"theming",children:"Theming"}),"\n",(0,i.jsx)(n.p,{children:"The getStyles function defined in the styles file returns styles for different areas (or subcomponents) of the chart based on the props passed to it. The base component is wrapped with the styled HOC, which passes the theme (set by the user) and the concatenated styles (derived from the styling function and any additional styles provided by the user) as props to the base component. Within the base component, the styles are named as the class name. The conversion is done by passing theme and other style props as arguments to the function returned by the classNamesFunction utility. Learn more about component styling here."}),"\n",(0,i.jsx)(n.p,{children:"The color prop for a segment is optional. If the color prop is not defined, a color is selected from the qualitative palette using the getNextColor utility. On the other hand, if the color prop is defined, the getColorFromToken utility is used to determine the appropriate CSS color. If the value of the color prop is a theme-specific color token from the DataVizPalette, the utility will return the corresponding CSS color. Otherwise, if the color prop is already a valid CSS color, it will be returned as is."}),"\n",(0,i.jsx)(n.h2,{id:"debugging",children:"Debugging"}),"\n",(0,i.jsx)(n.p,{children:"Our Test Suites are exhaustive to test each and every features provided with Line Charts, for debugging any particular feature these can be used respectively ."}),"\n",(0,i.jsx)(n.p,{children:"Few of these tests also verify the technical aspect of rendering like there is a test suite \u201cRender calling with respective to props\u201d available in line chart test which verifies that the render is called 2 times."}),"\n",(0,i.jsx)(n.h2,{id:"error-scenarios",children:"Error scenarios"}),"\n",(0,i.jsx)(n.h3,{id:"the-chart-cannot-be-loaded-because-of-one-or-more-reasons",children:"The chart cannot be loaded because of one or more reasons:\u202f"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Empty data passed such that chart does not have visual to show.\u202f"}),"\n",(0,i.jsx)(n.li,{children:"One of the datapoint passed to the chart is corrupted. The corrupted datapoint can be for a continuous chart like line or area, or a discrete chart like bar chart, donut chart.\u202f"}),"\n",(0,i.jsx)(n.li,{children:"The type of data passed to the chart is not supported.\u202f"}),"\n",(0,i.jsx)(n.li,{children:"The user has not provided the required property.\u202f"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"the-chart-is-in-a-loading-state-because-of-one-or-more-reasons-below",children:"The chart is in a loading state because of one or more reasons below.\u202f"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The chart data is too heavy.\u202f"}),"\n",(0,i.jsx)(n.li,{children:"Chart is waiting for data from a webservice.\u202f"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"extremely-high-density",children:"Extremely high density:\u202f"}),"\n",(0,i.jsx)(n.p,{children:"The number of lines in a line chart is more considering the height and width of the canvas provided."}),"\n",(0,i.jsx)(n.h3,{id:"errors-in-other-components",children:"Errors in other components:\u202f"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Empty/invalid data passed to hover callout.\u202f"}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"There is a large variation in data in one datapoint compared to others causing the graphs to become extremely skewed and non-interactable.\u202f"}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Title for legends is not defined or is corrupted.\u202f"}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"There is more than point on y axis for the same point in x axis.\u202f"}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"localization-aspects",children:"Localization aspects"}),"\n",(0,i.jsx)(n.h3,{id:"date-axis-localization-the-axes-support-2-ways-of-localization",children:"Date Axis localization: The axes support 2 ways of localization."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Javascript provided inbuilt localization for numeric and date axis. Specify the culture and dateLocalizeOptions for date axis to define target localization. Refer theJavascript localization guidefor usage."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Custom locale definition: The consumer of the library can specify a custom locale definition as supported by d3 like this:\nThe date axis will use the date range and the multiformat specified in the definition to determine the correct labels to show in the ticks. For example - If the date range is in days then the axis will show hourly ticks. If the date range spans across months then the a xis will show months in tick labels and so on. Specify the custom locale definition in the timeFormatLocale prop. Refer to the Custom Locale Date Axis example in line chart for sample usage."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"##Some notable PRs and their brief description"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/pull/24050",children:"Fix line chart rendering logic for bigger datasets having lines with more than 1000 datapoints by AtishayMsft \xb7 Pull Request #24050 \xb7 microsoft/fluentui (github.com)"})," With this PR, We have enabled a path based rendering when there are larger number of datapoints.For lines with points greater than 1000, we render a single path for all the points leveraging d3 line functionality."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/pull/26869",children:"Add color palette for data visualization by krkshitij \xb7 Pull Request #26869 \xb7 microsoft/fluentui (github.com)"}),"Color is optional for the data series in AreaChart and LineChart. If the color is absent, it will be picked automatically from the default color palette.New DataVizPalette provides users with theme-specific color tokens"]}),"\n",(0,i.jsx)(n.p,{children:"##Future improvements"}),"\n",(0,i.jsx)(n.p,{children:"We are working on Performance Improvements for line chart. Link to our performance roadmap for charting library :"}),"\n",(0,i.jsx)(n.p,{children:"##Rendering details"}),"\n",(0,i.jsx)(n.p,{children:"Line Chart is a react class Component, which uses different states for managing user interaction. The various other components that are used and their relationship are shown here."}),"\n",(0,i.jsx)(n.p,{children:"The rendering order is reverse of the diagram that means the order of rendering of the components is."}),"\n",(0,i.jsx)(n.p,{children:"###Chart Hover Card -> Cartesian Chart -> Legend -> Line chart."}),"\n",(0,i.jsx)(n.p,{children:"Every state change of user interaction causes different components to re-render. Example if a user hover onto the Legends then the components that will be re-rendered are Legends and then Line chart. However, if the user hovers onto a data point then the components that are re-rendered are Chart Hover Card then Cartesian Chart and then the Line Chart."}),"\n",(0,i.jsx)(n.p,{children:"##Interactions"}),"\n",(0,i.jsx)(n.p,{children:"There are various interactions that a user experiences in Line Chart which are"}),"\n",(0,i.jsx)(n.p,{children:"###1. Hover on Legends\n###2. Hover on Data Points"}),"\n",(0,i.jsx)(n.p,{children:"Hovering on the legend highlights only that legend and line/data point related to that legend."}),"\n",(0,i.jsx)(n.p,{children:"Hovering on Data Points renders a card which highlights the nearest points and displays the value of x and all the y on it."}),"\n",(0,i.jsx)(n.p,{children:"These interactions are managed by the below states -"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:" // This array contains data of selected legends for points\n selectedLegendPoints: LineChartDataWithIndex[];\n // This array contains data of selected legends for color bars\n selectedColorBarLegend: IColorFillBarsProps[];\n // This is a boolean value which is set to true\n // when at least one legend is selected\n isSelectedLegend: boolean;\n // This value will be used as customized callout props - point callout.\n dataPointCalloutProps?: ICustomizedCalloutData;\n // This value will be used as Customized callout props - For stack callout.\n stackCalloutProps?: ICustomizedCalloutData;\n // active or hovered point\n activePoint?: string;\n // x-axis callout accessibility data\n xAxisCalloutAccessibilityData?: IAccessibilityProps;\n\n nearestCircleToHighlight: ILineChartDataPoint | null;\n\n activeLine: number | null;\n"})}),"\n",(0,i.jsx)(n.p,{children:"##Known issues"}),"\n",(0,i.jsx)(n.p,{children:"##Design figma"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"https://www.figma.com/file/WOoCs0CmNYZhYl9xXeCGpi/Data-viz-(Archive)?type=design&node-id=1911-32621&mode=design&t=JWqPtVKYrHi6Jgwa-0",children:"Data viz (Archive) \u2013 Figma"})}),"\n",(0,i.jsx)(n.p,{children:"##Learnings"}),"\n",(0,i.jsxs)(n.p,{children:["We have enhanced the performance of the chart using ",(0,i.jsx)(n.code,{children:""})," instead of using the points to construct the path. Please refer the \u201cMathematical/Geometrical concepts\u201d section for more details."]}),"\n",(0,i.jsx)(n.p,{children:"##Extension"}),"\n",(0,i.jsxs)(n.p,{children:["While working on line chart if you are exploring or adding any new things , so if you are planning to contribute or fix something related to creation of line, interaction with the chart and data related things you should start exploring ",(0,i.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/tree/master/packages/react-charting/src/components/LineChart",children:"https://github.com/microsoft/fluentui/tree/master/packages/react-charting/src/components/LineChart"})]}),"\n",(0,i.jsxs)(n.p,{children:["If anything is related axis creation, domain range issues then one should start exploring cartesian chart code:\n",(0,i.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/tree/master/packages/react-charting/src/components/CommonComponents",children:"fluentui/packages/react-charting/src/components/CommonComponents at master \xb7 microsoft/fluentui \xb7 GitHub "})]})]})}function d(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},7633:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/LineChartPic1-d015e9f3c68c5901a3452c678f9acfa4.png"},1151:(e,n,t)=>{t.d(n,{Z:()=>o,a:()=>r});var i=t(7294);const a={},s=i.createContext(a);function r(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/62692344.d438a31c.js b/assets/js/62692344.d438a31c.js
deleted file mode 100644
index e1e91cebf9..0000000000
--- a/assets/js/62692344.d438a31c.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[9330],{4520:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>h,contentTitle:()=>r,default:()=>d,frontMatter:()=>s,metadata:()=>o,toc:()=>l});var i=t(5893),a=t(1151);const s={},r="Contributor guide: Line Chart",o={id:"Charting-Concepts/LineChart",title:"Contributor guide: Line Chart",description:"Line charts are a versatile type of graph used to visualize data trends over time. They are commonly used in various fields and industries for different purposes.",source:"@site/../../docs/Charting-Concepts/LineChart.md",sourceDirName:"Charting-Concepts",slug:"/Charting-Concepts/LineChart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/LineChart",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Contributor guide: Horizontal Bar Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/HorizontalBarChart"},next:{title:"Contributor Guide: Sankey Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/SankeyChart"}},h={},l=[{value:"Use cases:",id:"use-cases",level:2},{value:"Fluent Line chart also provide support for the scenarios where we need",id:"fluent-line-chart-also-provide-support-for-the-scenarios-where-we-need",level:3},{value:"Gaps",id:"gaps",level:3},{value:"Event annotations",id:"event-annotations",level:3},{value:"Lines with large dataset",id:"lines-with-large-dataset",level:3},{value:"Dev Design details",id:"dev-design-details",level:2},{value:"1. Line Chart",id:"1-line-chart",level:3},{value:"2. Cartesian chart",id:"2-cartesian-chart",level:3},{value:"3. ChartHover Card",id:"3-charthover-card",level:3},{value:"4 .Legends",id:"4-legends",level:3},{value:"5.Line border",id:"5line-border",level:3},{value:"Mathematical/Geometrical concepts",id:"mathematicalgeometrical-concepts",level:2},{value:"D3-Line",id:"d3-line",level:3},{value:"Performance",id:"performance",level:2},{value:"Accessibility",id:"accessibility",level:2},{value:"Testing",id:"testing",level:2},{value:"Variants",id:"variants",level:2},{value:"Event annotations",id:"event-annotations-1",level:3},{value:"Gaps",id:"gaps-1",level:3},{value:"Lines with large dataset",id:"lines-with-large-dataset-1",level:3},{value:"Theming",id:"theming",level:2},{value:"Debugging",id:"debugging",level:2},{value:"Error scenarios",id:"error-scenarios",level:2},{value:"The chart cannot be loaded because of one or more reasons:\u202f",id:"the-chart-cannot-be-loaded-because-of-one-or-more-reasons",level:3},{value:"The chart is in a loading state because of one or more reasons below.\u202f",id:"the-chart-is-in-a-loading-state-because-of-one-or-more-reasons-below",level:3},{value:"Extremely high density:\u202f",id:"extremely-high-density",level:3},{value:"Errors in other components:\u202f",id:"errors-in-other-components",level:3},{value:"Localization aspects",id:"localization-aspects",level:2},{value:"Date Axis localization: The axes support 2 ways of localization.",id:"date-axis-localization-the-axes-support-2-ways-of-localization",level:3}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,a.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"contributor-guide-line-chart",children:"Contributor guide: Line Chart"}),"\n",(0,i.jsx)(n.p,{children:"Line charts are a versatile type of graph used to visualize data trends over time. They are commonly used in various fields and industries for different purposes."}),"\n",(0,i.jsx)(n.h2,{id:"use-cases",children:"Use cases:"}),"\n",(0,i.jsx)(n.p,{children:"Line charts are used for various use cases which involve Trend Analysis, Performance Monitoring , Comparisions , Forecasting , Monitoring Changes , Communicating Data etc."}),"\n",(0,i.jsx)(n.h3,{id:"fluent-line-chart-also-provide-support-for-the-scenarios-where-we-need",children:"Fluent Line chart also provide support for the scenarios where we need"}),"\n",(0,i.jsx)(n.h3,{id:"gaps",children:"Gaps"}),"\n",(0,i.jsx)(n.p,{children:"A line chart can have gaps/breaks in between. This is to represent missing data. The gaps can also be replaced with dashed or dotted lines for specific scenarios, say to represent low confidence predictions for a time series forecast graph."}),"\n",(0,i.jsx)(n.h3,{id:"event-annotations",children:"Event annotations"}),"\n",(0,i.jsx)(n.p,{children:"Event annotations are used to highlight events and annotate them using messages."}),"\n",(0,i.jsx)(n.h3,{id:"lines-with-large-dataset",children:"Lines with large dataset"}),"\n",(0,i.jsx)(n.p,{children:"We use a path based rendering technique to show datasets with large number of points (greater than 1k)."}),"\n",(0,i.jsx)(n.h2,{id:"dev-design-details",children:"Dev Design details"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"LineChartContrib.png",src:t(7633).Z+"",width:"1150",height:"826"})}),"\n",(0,i.jsx)(n.p,{children:"Fig A: Representing Charting Lib Components Relationships and Functionality."}),"\n",(0,i.jsx)(n.p,{children:"Line chart comprises of other charting components as shown above, these are:"}),"\n",(0,i.jsx)(n.h3,{id:"1-line-chart",children:"1. Line Chart"}),"\n",(0,i.jsx)(n.p,{children:"This is the main component which is responsible for invoking/using other components. This is the component which is responsible for creating lines , event annotations, gaps and managing user interactions with itself , Legends and Cartesian Chart."}),"\n",(0,i.jsx)(n.h3,{id:"2-cartesian-chart",children:"2. Cartesian chart"}),"\n",(0,i.jsx)(n.p,{children:"This is component which is responsible for creating the X and Y Axis and the ticks for Axis. All the calculation for domain/range is done in cartesian chart. This component can be accessed through line chart. This is also manages the ChartHoverCard component ."}),"\n",(0,i.jsx)(n.h3,{id:"3-charthover-card",children:"3. ChartHover Card"}),"\n",(0,i.jsx)(n.p,{children:"ChartHoverCard is a utility in the Fluent UI web library that provides a tooltip-like experience for charts. It is a React component that can be used to display additional information about data points on a chart when the user hovers over them."}),"\n",(0,i.jsx)(n.h3,{id:"4-legends",children:"4 .Legends"}),"\n",(0,i.jsx)(n.p,{children:"In the Fluent UI React charting library, a legend contains a list of the variables appearing in the chart and an example of their appearance.\u202fThis information allows the data from each variable to be identified in the chart. This component is populated in Line chart component."}),"\n",(0,i.jsx)(n.h3,{id:"5line-border",children:"5.Line border"}),"\n",(0,i.jsx)(n.p,{children:"Each line in the chart can contain a 2 px border for better highlighting of the line when there are multiple items in the chart. The border will have color of the background theme. Lines will be highlighted in order of their appearance in legends. Line border is a highly suggested style that you should apply to make multiple lines more distinguishable from each other. Use lineBorderWidth prop present insidelineOptions to enable it."}),"\n",(0,i.jsx)(n.h2,{id:"mathematicalgeometrical-concepts",children:"Mathematical/Geometrical concepts"}),"\n",(0,i.jsxs)(n.p,{children:["Line Chart are created using ",(0,i.jsx)(n.a,{href:"https://github.com/d3/d3-shape#readme",children:"d3-shape"})," . The main API used from this library to create line between 2 points is ",(0,i.jsx)(n.a,{href:"https://github.com/d3/d3-shape#lines",children:"d3-line"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://github.com/d3/d3-shape#lines",children:"d3-line"})," is used only when the property optimizeLargeData is enabled , we use the spline and interpolation to generate a continuous line, when the dataset is huge(>10k points)."]}),"\n",(0,i.jsxs)(n.p,{children:["In case of a smaller dataset, line chart builds the lines using the ",(0,i.jsx)(n.a,{href:"https://www.w3schools.com/graphics/svg_line.asp",children:"SVG line"})," element. In such cases, the chart renders a line segment connecting each adjacent pair of coordinates."]}),"\n",(0,i.jsx)(n.h3,{id:"d3-line",children:"D3-Line"}),"\n",(0,i.jsxs)(n.p,{children:["Line Generator are generated using a\u202f",(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Spline_(mathematics)",children:"spline"}),"\u202for\u202f",(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Polygonal_chain",children:"polyline"}),", as in a line chart. Lines also appear in many other visualization types, such as the links in\u202f",(0,i.jsx)(n.a,{href:"https://observablehq.com/@d3/hierarchical-edge-bundling",children:"hierarchical edge bundling"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["While\u202f",(0,i.jsx)(n.a,{href:"https://github.com/d3/d3-shape#lines",children:"lines"}),"\u202fare defined as a sequence of two-dimensional [x,\u202fy] points, and\u202f",(0,i.jsx)(n.a,{href:"https://github.com/d3/d3-shape#areas",children:"areas"}),"\u202fare similarly defined by a topline and a baseline, there remains the task of transforming this discrete representation into a continuous shape:\u202fi.e., how to interpolate between the points. A variety of curves are provided for this purpose. The curve used to draw these lines are ",(0,i.jsx)(n.a,{href:"https://github.com/d3/d3-shape#curveLinear",children:"curveLinear"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"performance",children:"Performance"}),"\n",(0,i.jsx)(n.p,{children:"The performance aspect of a line chart refers to how efficiently and effectively it conveys information to the viewer. Here are some key considerations regarding the performance of a line chart:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Data Visualization Efficiency"}),"\n",(0,i.jsx)(n.li,{children:"Clarity and Simplicity"}),"\n",(0,i.jsx)(n.li,{children:"Responsiveness"}),"\n",(0,i.jsx)(n.li,{children:"Handling Large Datasets"}),"\n",(0,i.jsx)(n.li,{children:"Interactive Features"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"We use Lighthouse tool for measuring the performance of our charts. We have multiple scenarios against which we measure the performance score for line chart:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"1 chart with 30k Points"}),"\n",(0,i.jsx)(n.li,{children:"6 charts,1 series with 100 data points each"}),"\n",(0,i.jsx)(n.li,{children:"18 charts,1 series 5 data points each"}),"\n",(0,i.jsx)(n.li,{children:"1 chart ,1 series with 1000 data points each"}),"\n",(0,i.jsx)(n.li,{children:"50 charts, 1 Series with 10 data points each"}),"\n",(0,i.jsx)(n.li,{children:"1 chart, 2 series with 500 data points each"}),"\n",(0,i.jsx)(n.li,{children:"10 charts ,1 series with 1000 data points each"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Most of above scenarios have 90+ Lighthouse score. If we talk about the 30k data point has Lighthouse score close to 85. We are efficient in terms of the performance of the line chart."}),"\n",(0,i.jsx)(n.p,{children:"We have 2 rendering methods for the line chart. one of the method is optimized for large datasets and is controlled by the optimizeLargeData property. Enable this rendering method by setting the\u202foptimizeLargeData\u202fprop to\u202ftrue this will help in improving the performance for your large data set."}),"\n",(0,i.jsx)(n.h2,{id:"accessibility",children:"Accessibility"}),"\n",(0,i.jsx)(n.p,{children:"Following subcomponents are accessible using a screen reader:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Chart ",(0,i.jsx)(n.code,{children:""}),"The role is set as presentation, and the aria-label attribute is set as a string to describe its contents. This is readable by screen reader if user has given chartTitle prop"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["eventAnnotation accessibility is managed by EventAnnotation sub componnets which internally uses ",(0,i.jsx)(n.code,{children:""})," hence the labels provided in IEvenetAnnotaionProps will be read by screen reader."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Points accessibility is managed by ",(0,i.jsx)(n.code,{children:""})," tags with role=\u201dimg\u201d whose accessibility is managed by aria-label property ."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Line chart provides a bunch of props to enable custom accessibility messages. UsexAxisCalloutAccessibilityData and callOutAccessibilityData to configure x axis and y axis accessibility messages respectively."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"testing",children:"Testing"}),"\n",(0,i.jsx)(n.h2,{id:"variants",children:"Variants"}),"\n",(0,i.jsxs)(n.p,{children:["Different variants of line charts are available starting from the basic line chart to multiple line charts, line chart with event, line chart with custom accessibility, Line chart with large data set, line chart with gaps and custom date axis locale. For more details visit DemoSite ",(0,i.jsx)(n.a,{href:"https://fluentuipr.z22.web.core.windows.net/heads/master/react-charting/demo/index.html#/examples/linechart",children:"Fluent UI React Charting Examples - Line Chart (windows.net)"})]}),"\n",(0,i.jsx)(n.p,{children:"Below are details for using the above variants:"}),"\n",(0,i.jsx)(n.h3,{id:"event-annotations-1",children:"Event annotations"}),"\n",(0,i.jsx)(n.p,{children:"Event annotations are used to highlight events and annotate them using messages.. Events can be added by using eventAnnotationProps prop. Each event contains adate, event message and event details callout callbackonRenderCard"}),"\n",(0,i.jsx)(n.h3,{id:"gaps-1",children:"Gaps"}),"\n",(0,i.jsx)(n.p,{children:"A line chart can have gaps/breaks in between. Gaps can be added by using gaps prop. A gap is denoted bystartIndex andendIndex datapoints in the line. A line will be drawn uptil the startIndex and skipped forendIndex - startIndex number of datapoints. A line can have as many gaps as possible."}),"\n",(0,i.jsx)(n.h3,{id:"lines-with-large-dataset-1",children:"Lines with large dataset"}),"\n",(0,i.jsx)(n.p,{children:"We use a path based rendering technique to show datasets with large number of points (greater than 1k). Using this technique datasets with over 10k points can be rendered easily. Enable this rendering method by setting the optimizeLargeData prop to true."}),"\n",(0,i.jsx)(n.h2,{id:"theming",children:"Theming"}),"\n",(0,i.jsx)(n.p,{children:"The getStyles function defined in the styles file returns styles for different areas (or subcomponents) of the chart based on the props passed to it. The base component is wrapped with the styled HOC, which passes the theme (set by the user) and the concatenated styles (derived from the styling function and any additional styles provided by the user) as props to the base component. Within the base component, the styles are named as the class name. The conversion is done by passing theme and other style props as arguments to the function returned by the classNamesFunction utility. Learn more about component styling here."}),"\n",(0,i.jsx)(n.p,{children:"The color prop for a segment is optional. If the color prop is not defined, a color is selected from the qualitative palette using the getNextColor utility. On the other hand, if the color prop is defined, the getColorFromToken utility is used to determine the appropriate CSS color. If the value of the color prop is a theme-specific color token from the DataVizPalette, the utility will return the corresponding CSS color. Otherwise, if the color prop is already a valid CSS color, it will be returned as is."}),"\n",(0,i.jsx)(n.h2,{id:"debugging",children:"Debugging"}),"\n",(0,i.jsx)(n.p,{children:"Our Test Suites are exhaustive to test each and every features provided with Line Charts, for debugging any particular feature these can be used respectively ."}),"\n",(0,i.jsx)(n.p,{children:"Few of these tests also verify the technical aspect of rendering like there is a test suite \u201cRender calling with respective to props\u201d available in line chart test which verifies that the render is called 2 times."}),"\n",(0,i.jsx)(n.h2,{id:"error-scenarios",children:"Error scenarios"}),"\n",(0,i.jsx)(n.h3,{id:"the-chart-cannot-be-loaded-because-of-one-or-more-reasons",children:"The chart cannot be loaded because of one or more reasons:\u202f"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Empty data passed such that chart does not have visual to show.\u202f"}),"\n",(0,i.jsx)(n.li,{children:"One of the datapoint passed to the chart is corrupted. The corrupted datapoint can be for a continuous chart like line or area, or a discrete chart like bar chart, donut chart.\u202f"}),"\n",(0,i.jsx)(n.li,{children:"The type of data passed to the chart is not supported.\u202f"}),"\n",(0,i.jsx)(n.li,{children:"The user has not provided the required property.\u202f"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"the-chart-is-in-a-loading-state-because-of-one-or-more-reasons-below",children:"The chart is in a loading state because of one or more reasons below.\u202f"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The chart data is too heavy.\u202f"}),"\n",(0,i.jsx)(n.li,{children:"Chart is waiting for data from a webservice.\u202f"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"extremely-high-density",children:"Extremely high density:\u202f"}),"\n",(0,i.jsx)(n.p,{children:"The number of lines in a line chart is more considering the height and width of the canvas provided."}),"\n",(0,i.jsx)(n.h3,{id:"errors-in-other-components",children:"Errors in other components:\u202f"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Empty/invalid data passed to hover callout.\u202f"}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"There is a large variation in data in one datapoint compared to others causing the graphs to become extremely skewed and non-interactable.\u202f"}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Title for legends is not defined or is corrupted.\u202f"}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"There is more than point on y axis for the same point in x axis.\u202f"}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"localization-aspects",children:"Localization aspects"}),"\n",(0,i.jsx)(n.h3,{id:"date-axis-localization-the-axes-support-2-ways-of-localization",children:"Date Axis localization: The axes support 2 ways of localization."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Javascript provided inbuilt localization for numeric and date axis. Specify the culture and dateLocalizeOptions for date axis to define target localization. Refer theJavascript localization guidefor usage."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Custom locale definition: The consumer of the library can specify a custom locale definition as supported by d3 like this:\nThe date axis will use the date range and the multiformat specified in the definition to determine the correct labels to show in the ticks. For example - If the date range is in days then the axis will show hourly ticks. If the date range spans across months then the a xis will show months in tick labels and so on. Specify the custom locale definition in the timeFormatLocale prop. Refer to the Custom Locale Date Axis example in line chart for sample usage."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"##Some notable PRs and their brief description"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/pull/24050",children:"Fix line chart rendering logic for bigger datasets having lines with more than 1000 datapoints by AtishayMsft \xb7 Pull Request #24050 \xb7 microsoft/fluentui (github.com)"})," With this PR, We have enabled a path based rendering when there are larger number of datapoints.For lines with points greater than 1000, we render a single path for all the points leveraging d3 line functionality."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/pull/26869",children:"Add color palette for data visualization by krkshitij \xb7 Pull Request #26869 \xb7 microsoft/fluentui (github.com)"}),"Color is optional for the data series in AreaChart and LineChart. If the color is absent, it will be picked automatically from the default color palette.New DataVizPalette provides users with theme-specific color tokens"]}),"\n",(0,i.jsx)(n.p,{children:"##Future improvements"}),"\n",(0,i.jsx)(n.p,{children:"We are working on Performance Improvements for line chart. Link to our performance roadmap for charting library :"}),"\n",(0,i.jsx)(n.p,{children:"##Rendering details"}),"\n",(0,i.jsx)(n.p,{children:"Line Chart is a react class Component, which uses different states for managing user interaction. The various other components that are used and their relationship are shown here."}),"\n",(0,i.jsx)(n.p,{children:"The rendering order is reverse of the diagram that means the order of rendering of the components is."}),"\n",(0,i.jsx)(n.p,{children:"###Chart Hover Card -> Cartesian Chart -> Legend -> Line chart."}),"\n",(0,i.jsx)(n.p,{children:"Every state change of user interaction causes different components to re-render. Example if a user hover onto the Legends then the components that will be re-rendered are Legends and then Line chart. However, if the user hovers onto a data point then the components that are re-rendered are Chart Hover Card then Cartesian Chart and then the Line Chart."}),"\n",(0,i.jsx)(n.p,{children:"##Interactions"}),"\n",(0,i.jsx)(n.p,{children:"There are various interactions that a user experiences in Line Chart which are"}),"\n",(0,i.jsx)(n.p,{children:"###1. Hover on Legends\n###2. Hover on Data Points"}),"\n",(0,i.jsx)(n.p,{children:"Hovering on the legend highlights only that legend and line/data point related to that legend."}),"\n",(0,i.jsx)(n.p,{children:"Hovering on Data Points renders a card which highlights the nearest points and displays the value of x and all the y on it."}),"\n",(0,i.jsx)(n.p,{children:"These interactions are managed by the below states -"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:" // This array contains data of selected legends for points\n selectedLegendPoints: LineChartDataWithIndex[];\n // This array contains data of selected legends for color bars\n selectedColorBarLegend: IColorFillBarsProps[];\n // This is a boolean value which is set to true\n // when at least one legend is selected\n isSelectedLegend: boolean;\n // This value will be used as customized callout props - point callout.\n dataPointCalloutProps?: ICustomizedCalloutData;\n // This value will be used as Customized callout props - For stack callout.\n stackCalloutProps?: ICustomizedCalloutData;\n // active or hovered point\n activePoint?: string;\n // x-axis callout accessibility data\n xAxisCalloutAccessibilityData?: IAccessibilityProps;\n\n nearestCircleToHighlight: ILineChartDataPoint | null;\n\n activeLine: number | null;\n"})}),"\n",(0,i.jsx)(n.p,{children:"##Known issues"}),"\n",(0,i.jsx)(n.p,{children:"##Design figma"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"https://www.figma.com/file/WOoCs0CmNYZhYl9xXeCGpi/Data-viz-(Archive)?type=design&node-id=1911-32621&mode=design&t=JWqPtVKYrHi6Jgwa-0",children:"Data viz (Archive) \u2013 Figma"})}),"\n",(0,i.jsx)(n.p,{children:"##Learnings"}),"\n",(0,i.jsxs)(n.p,{children:["We have enhanced the performance of the chart using ",(0,i.jsx)(n.code,{children:""})," instead of using the points to construct the path. Please refer the \u201cMathematical/Geometrical concepts\u201d section for more details."]}),"\n",(0,i.jsx)(n.p,{children:"##Extension"}),"\n",(0,i.jsxs)(n.p,{children:["While working on line chart if you are exploring or adding any new things , so if you are planning to contribute or fix something related to creation of line, interaction with the chart and data related things you should start exploring ",(0,i.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/tree/master/packages/react-charting/src/components/LineChart",children:"https://github.com/microsoft/fluentui/tree/master/packages/react-charting/src/components/LineChart"})]}),"\n",(0,i.jsxs)(n.p,{children:["If anything is related axis creation, domain range issues then one should start exploring cartesian chart code:\n",(0,i.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/tree/master/packages/react-charting/src/components/CommonComponents",children:"fluentui/packages/react-charting/src/components/CommonComponents at master \xb7 microsoft/fluentui \xb7 GitHub "})]})]})}function d(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},7633:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/LineChartPic1-d015e9f3c68c5901a3452c678f9acfa4.png"},1151:(e,n,t)=>{t.d(n,{Z:()=>o,a:()=>r});var i=t(7294);const a={},s=i.createContext(a);function r(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/712b8a2d.8a52facb.js b/assets/js/712b8a2d.8a52facb.js
new file mode 100644
index 0000000000..554e916880
--- /dev/null
+++ b/assets/js/712b8a2d.8a52facb.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[6863],{4227:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var t=s(5893),i=s(1151);const r={},a="Heatmap Chart",l={id:"Charting-Concepts/HeatMapChart",title:"Heatmap Chart",description:"A heatmap chart is a type of data visualization that represents data values as colors in a grid of rectangles. Each cell's color intensity corresponds to the value it represents, making it easy to spot patterns and variations in the data.",source:"@site/../../docs/Charting-Concepts/HeatMapChart.md",sourceDirName:"Charting-Concepts",slug:"/Charting-Concepts/HeatMapChart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/HeatMapChart",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Grouped Vertical Bar Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/GroupedVerticalBarChart"},next:{title:"Horizontal Bar Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/HorizontalBarChart"}},o={},c=[{value:"Use cases",id:"use-cases",level:2},{value:"Dev Design details",id:"dev-design-details",level:2},{value:"Mathematical/Geometrical concepts",id:"mathematicalgeometrical-concepts",level:2},{value:"Performance",id:"performance",level:2},{value:"Accessibility",id:"accessibility",level:2},{value:"Testing",id:"testing",level:2},{value:"Variants",id:"variants",level:2},{value:"Theming",id:"theming",level:2},{value:"Debugging",id:"debugging",level:2},{value:"Error scenarios",id:"error-scenarios",level:2},{value:"Localization aspects",id:"localization-aspects",level:2},{value:"Some notable PRs and their brief description",id:"some-notable-prs-and-their-brief-description",level:2},{value:"Future improvements",id:"future-improvements",level:2},{value:"Rendering details",id:"rendering-details",level:2},{value:"Interactions",id:"interactions",level:2},{value:"Known issues",id:"known-issues",level:2},{value:"Design figma",id:"design-figma",level:2},{value:"Learnings",id:"learnings",level:2},{value:"Extensions",id:"extensions",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"heatmap-chart",children:"Heatmap Chart"}),"\n",(0,t.jsx)(n.p,{children:"A heatmap chart is a type of data visualization that represents data values as colors in a grid of rectangles. Each cell's color intensity corresponds to the value it represents, making it easy to spot patterns and variations in the data."}),"\n",(0,t.jsx)(n.h2,{id:"use-cases",children:"Use cases"}),"\n",(0,t.jsx)(n.p,{children:"Here are some common use cases for heatmap charts:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Data Analysis: Heatmaps help analyze large datasets by visually identifying trends, outliers, and correlations."}),"\n",(0,t.jsx)(n.li,{children:"User Behavior Tracking: In web analytics, heatmaps can show where users click, move, or spend time on a webpage, helping optimize user experience."}),"\n",(0,t.jsx)(n.li,{children:"Risk Assessment: Heatmaps are used in financial and project management to assess and manage risks by highlighting areas with the highest potential impact."}),"\n",(0,t.jsx)(n.li,{children:"Sports Analysis: In sports, heatmaps show player movement and performance on the field or court, aiding in strategic decision-making."}),"\n",(0,t.jsx)(n.li,{children:"Weather and Climate Analysis: Meteorologists use heatmaps to visualize temperature, precipitation, and other climate-related data."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"dev-design-details",children:"Dev Design details"}),"\n",(0,t.jsx)(n.p,{children:"The heatmap chart comprises the following components and subcomponents:"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"HeatMapChart"}),": This is the main component responsible for rendering and managing subcomponents, such as rectangles and other components. It handles user interactions and provides the overall functionality of the chart."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"CartesianChart"}),": This component is responsible for rendering the x and y axes. Additionally, it wraps the entire chart with a FocusZone component, which allows users to navigate focus between rectangles using arrow keys. It also renders a Callout component with a ChartHoverCard component, which functions as an anchored tip, offering additional information about the rectangle that is currently hovered over or focused without blocking the user."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Legends"}),": Legends are a unique list of strings that identify each group of rectangles in the chart. The Legends component renders a button for each legend, enabling users to highlight the associated rectangles by hovering over or selecting the legend."]}),"\n",(0,t.jsx)(n.h2,{id:"mathematicalgeometrical-concepts",children:"Mathematical/Geometrical concepts"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Numeric x and y values are converted to strings using the ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-format#format",children:"format"})," utility from the ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-format",children:"d3-format"})," library, based on the provided format specifier string. Similarly, date x and y values are converted to human readable strings using the ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-time-format#timeFormat",children:"timeFormat"})," utility from the ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-time-format",children:"d3-time-format"})," library, according to the provided format specifier string. The resulting string values are then passed as domains to CartesianChart for creating string x and y axes."]}),"\n",(0,t.jsxs)(n.li,{children:["A linear scale is created using the ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-scale/linear#scaleLinear",children:"scaleLinear"})," utility from the ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-scale",children:"d3-scale"})," library, which maps rectangle values (continuous input domain) to colors (continuous output range) using the default interpolation. Specifying more than 2 domain and range values produces a piecewise scale."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"performance",children:"Performance"}),"\n",(0,t.jsx)(n.h2,{id:"accessibility",children:"Accessibility"}),"\n",(0,t.jsx)(n.p,{children:"The following subcomponents are accessible using a screen reader:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Rectangle "}),": The following attributes provide an accessible description for the rectangle."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"role"}),' = "img"']}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"aria-label"}),' = "{xCoordinate}, {yCoordinate}. {legend}, {rectangleValue}. {description}."']}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Users can customize this description using the callOutAccessibilityData prop."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"testing",children:"Testing"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Test coverage report",src:s(2491).Z+"",width:"3680",height:"1060"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"/fluentui-charting-contrib/docs/Test%20Plans/HeatMapChart/ComponentTests",children:"HeatMapChart test plan"})}),"\n",(0,t.jsx)(n.h2,{id:"variants",children:"Variants"}),"\n",(0,t.jsx)(n.p,{children:"Here are the props available for customizing the heatmap chart:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"data"})," (required): Use this prop to populate the chart by providing a series of groups, each containing data for a series of rectangles."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"domainValuesForColorScale"})," and ",(0,t.jsx)(n.strong,{children:"rangeValuesForColorScale"})," (required): These props are used to generate a scale that transforms rectangle values into colors. The domainValuesForColorScale prop accepts an array of numbers, and the rangeValuesForColorScale prop accepts an array of CSS color strings. For optimal results, ensure the length of these arrays is the same."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"xAxisDateFormatString"}),": Use this prop to specify a custom string format for formatting date-based x-axis labels. For more information, refer to ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-time-format#locale_format",children:"d3-time-format | D3 by Observable (d3js.org)"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"yAxisDateFormatString"}),": Use this prop to specify a custom string format for formatting date-based y-axis labels. For more information, refer to ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-time-format#locale_format",children:"d3-time-format | D3 by Observable (d3js.org)"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"xAxisNumberFormatString"}),": Use this prop to specify a custom string format for formatting numeric x-axis labels. For more information, refer to ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-format#locale_format",children:"d3-format | D3 by Observable (d3js.org)"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"yAxisNumberFormatString"}),": Use this prop to specify a custom string format for formatting numeric y-axis labels. For more information, refer to ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-format#locale_format",children:"d3-format | D3 by Observable (d3js.org)"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"xAxisStringFormatter"}),": Use this prop to provide a custom function for formatting string-based x-axis labels."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"yAxisStringFormatter"}),": Use this prop to provide a custom function for formatting string-based y-axis labels."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["For more details, see ",(0,t.jsx)(n.a,{href:"https://developer.microsoft.com/en-us/fluentui#/controls/web/heatmapchart",children:"Fluent UI - Controls - React - HeatMapChart"})]}),"\n",(0,t.jsx)(n.h2,{id:"theming",children:"Theming"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The styles file contains a function called getHeatMapChartStyles, which returns styles for different areas or subcomponents of the chart based on the props passed to it. The base component is wrapped with the styled HOC, which passes the theme (set by the user) and the concatenated styles (obtained from the styling function and any additional styles provided by the user) as props to the base component. Within the base component, the styles are applied to corresponding elements after converting them into class names. This conversion is done by passing theme and other style props as arguments to the function returned by the classNamesFunction utility. To learn more about component styling, refer ",(0,t.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/wiki/Component-Styling",children:"this"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"debugging",children:"Debugging"}),"\n",(0,t.jsx)(n.h2,{id:"error-scenarios",children:"Error scenarios"}),"\n",(0,t.jsx)(n.h2,{id:"localization-aspects",children:"Localization aspects"}),"\n",(0,t.jsx)(n.p,{children:"Currently, the chart supports localization only for numeric texts inside rectangles."}),"\n",(0,t.jsx)(n.h2,{id:"some-notable-prs-and-their-brief-description",children:"Some notable PRs and their brief description"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/pull/28321",children:"Fixing re-render issue for all charts when empty by srmukher \xb7 Pull Request #28321 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/pull/25616",children:"Fix wrong narration in browse mode by krkshitij \xb7 Pull Request #25616 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/pull/24563",children:"Fix legends selection bugs by krkshitij \xb7 Pull Request #24563 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/pull/24903",children:"Fix wrong narration when legend selected by krkshitij \xb7 Pull Request #24903 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/pull/21750",children:"Fix charting callout not hoverable using mouse and callout flickering by AtishayMsft \xb7 Pull Request #21750 \xb7 microsoft/fluentui (github.com)"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"future-improvements",children:"Future improvements"}),"\n",(0,t.jsx)(n.h2,{id:"rendering-details",children:"Rendering details"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"When no data is provided by the user, an empty div is rendered in place of the chart."}),"\n",(0,t.jsxs)(n.li,{children:["Currently, a string axis is created regardless of the type of x and y values, which uses the d3 ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-scale/band",children:"scaleBand"})," utility. This utility has a ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-scale/band#band_bandwidth",children:"bandwidth"})," property that is used to determine the width and height of rectangles. The d3 ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-scale/linear",children:"scaleLinear"})," and ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-scale/time",children:"scaleTime"})," utilities, used for number and date axes respectively, don't have such a property."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"interactions",children:"Interactions"}),"\n",(0,t.jsx)(n.p,{children:"The chart is wrapped with a FocusZone component to allow focus on its interactive subcomponents. The following subcomponents are accessible using the keyboard:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Rectangle "})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"data-is-focusable"}),": True."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onFocus"}),": Shows a callout near the element containing the rectangle details."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onBlur"}),": Does nothing."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Legend "})," (Legends)"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"data-is-focusable"}),": Depends on the allowFocusOnLegends prop, which is true by default."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onFocus"}),": Highlights the associated rectangles."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onBlur"}),": Unhighlights the associated rectangles."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Users can interact with the following subcomponents using the mouse:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Rectangle"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:""}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseOver"}),": Shows a callout near the element containing the rectangle details."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseOut"}),": Does nothing."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:""}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onClick"}),": Calls the onClick prop associated with the rectangle if provided."]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Root "})," (CartesianChart)"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseLeave"}),": Hides the callout if it is visible."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Legend
"})," (Legends)"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseOver"}),": Highlights the associated rectangles."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseOut"}),": Unhighlights the associated rectangles."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onClick"}),": Highlights the associated rectangles if the legend is not already selected, otherwise unhighlights them."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"known-issues",children:"Known issues"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/issues/30128",children:"[Bug]: Date axis labels formatted to show only the year are being localized as if they were numbers \xb7 Issue #30128 \xb7 microsoft/fluentui"})}),"\n",(0,t.jsx)(n.li,{children:"Y-axis labels are accessible through assistive technologies, such as screen readers."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"design-figma",children:"Design figma"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.figma.com/file/7ywOrSjGW5DEkNETagzXf2/Heat-map?type=design&t=FUFuc5mzEF4G6hag-6",children:"Heat map - Figma"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"learnings",children:"Learnings"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Long y axis labels get clipped which can be fixed by passing custom left or right margin to the chart. In contrast, horizontal bar chart with axis calculates longest label width and updates the margin with that value to prevent the labels from clipping."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"extensions",children:"Extensions"})]})}function d(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},2491:(e,n,s)=>{s.d(n,{Z:()=>t});const t=s.p+"assets/images/heatmapchart-test-coverage-020d10786fd47cd143a84149f2665adb.png"},1151:(e,n,s)=>{s.d(n,{Z:()=>l,a:()=>a});var t=s(7294);const i={},r=t.createContext(i);function a(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/712b8a2d.b2c49b65.js b/assets/js/712b8a2d.b2c49b65.js
deleted file mode 100644
index 9e0534996e..0000000000
--- a/assets/js/712b8a2d.b2c49b65.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[6863],{4227:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>c});var t=s(5893),i=s(1151);const r={},a="Contributor guide: Heatmap Chart",o={id:"Charting-Concepts/HeatMapChart",title:"Contributor guide: Heatmap Chart",description:"A heatmap chart is a type of data visualization that represents data values as colors in a grid of rectangles. Each cell's color intensity corresponds to the value it represents, making it easy to spot patterns and variations in the data.",source:"@site/../../docs/Charting-Concepts/HeatMapChart.md",sourceDirName:"Charting-Concepts",slug:"/Charting-Concepts/HeatMapChart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/HeatMapChart",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Contributor guide: Grouped Vertical Bar Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/GroupedVerticalBarChart"},next:{title:"Contributor guide: Horizontal Bar Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/HorizontalBarChart"}},l={},c=[{value:"Use cases",id:"use-cases",level:2},{value:"Dev Design details",id:"dev-design-details",level:2},{value:"Mathematical/Geometrical concepts",id:"mathematicalgeometrical-concepts",level:2},{value:"Performance",id:"performance",level:2},{value:"Accessibility",id:"accessibility",level:2},{value:"Testing",id:"testing",level:2},{value:"Variants",id:"variants",level:2},{value:"Theming",id:"theming",level:2},{value:"Debugging",id:"debugging",level:2},{value:"Error scenarios",id:"error-scenarios",level:2},{value:"Localization aspects",id:"localization-aspects",level:2},{value:"Some notable PRs and their brief description",id:"some-notable-prs-and-their-brief-description",level:2},{value:"Future improvements",id:"future-improvements",level:2},{value:"Rendering details",id:"rendering-details",level:2},{value:"Interactions",id:"interactions",level:2},{value:"Known issues",id:"known-issues",level:2},{value:"Design figma",id:"design-figma",level:2},{value:"Learnings",id:"learnings",level:2},{value:"Extensions",id:"extensions",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"contributor-guide-heatmap-chart",children:"Contributor guide: Heatmap Chart"}),"\n",(0,t.jsx)(n.p,{children:"A heatmap chart is a type of data visualization that represents data values as colors in a grid of rectangles. Each cell's color intensity corresponds to the value it represents, making it easy to spot patterns and variations in the data."}),"\n",(0,t.jsx)(n.h2,{id:"use-cases",children:"Use cases"}),"\n",(0,t.jsx)(n.p,{children:"Here are some common use cases for heatmap charts:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Data Analysis: Heatmaps help analyze large datasets by visually identifying trends, outliers, and correlations."}),"\n",(0,t.jsx)(n.li,{children:"User Behavior Tracking: In web analytics, heatmaps can show where users click, move, or spend time on a webpage, helping optimize user experience."}),"\n",(0,t.jsx)(n.li,{children:"Risk Assessment: Heatmaps are used in financial and project management to assess and manage risks by highlighting areas with the highest potential impact."}),"\n",(0,t.jsx)(n.li,{children:"Sports Analysis: In sports, heatmaps show player movement and performance on the field or court, aiding in strategic decision-making."}),"\n",(0,t.jsx)(n.li,{children:"Weather and Climate Analysis: Meteorologists use heatmaps to visualize temperature, precipitation, and other climate-related data."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"dev-design-details",children:"Dev Design details"}),"\n",(0,t.jsx)(n.p,{children:"The heatmap chart comprises the following components and subcomponents:"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"HeatMapChart"}),": This is the main component responsible for rendering and managing subcomponents, such as rectangles and other components. It handles user interactions and provides the overall functionality of the chart."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"CartesianChart"}),": This component is responsible for rendering the x and y axes. Additionally, it wraps the entire chart with a FocusZone component, which allows users to navigate focus between rectangles using arrow keys. It also renders a Callout component with a ChartHoverCard component, which functions as an anchored tip, offering additional information about the rectangle that is currently hovered over or focused without blocking the user."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Legends"}),": Legends are a unique list of strings that identify each group of rectangles in the chart. The Legends component renders a button for each legend, enabling users to highlight the associated rectangles by hovering over or selecting the legend."]}),"\n",(0,t.jsx)(n.h2,{id:"mathematicalgeometrical-concepts",children:"Mathematical/Geometrical concepts"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Numeric x and y values are converted to strings using the ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-format#format",children:"format"})," utility from the ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-format",children:"d3-format"})," library, based on the provided format specifier string. Similarly, date x and y values are converted to human readable strings using the ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-time-format#timeFormat",children:"timeFormat"})," utility from the ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-time-format",children:"d3-time-format"})," library, according to the provided format specifier string. The resulting string values are then passed as domains to CartesianChart for creating string x and y axes."]}),"\n",(0,t.jsxs)(n.li,{children:["A linear scale is created using the ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-scale/linear#scaleLinear",children:"scaleLinear"})," utility from the ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-scale",children:"d3-scale"})," library, which maps rectangle values (continuous input domain) to colors (continuous output range) using the default interpolation. Specifying more than 2 domain and range values produces a piecewise scale."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"performance",children:"Performance"}),"\n",(0,t.jsx)(n.h2,{id:"accessibility",children:"Accessibility"}),"\n",(0,t.jsx)(n.p,{children:"The following subcomponents are accessible using a screen reader:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Rectangle "}),": The following attributes provide an accessible description for the rectangle."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"role"}),' = "img"']}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"aria-label"}),' = "{xCoordinate}, {yCoordinate}. {legend}, {rectangleValue}. {description}."']}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Users can customize this description using the callOutAccessibilityData prop."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"testing",children:"Testing"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Test coverage report",src:s(2491).Z+"",width:"3680",height:"1060"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"/fluentui-charting-contrib/docs/Test%20Plans/HeatMapChart/ComponentTests",children:"HeatMapChart test plan"})}),"\n",(0,t.jsx)(n.h2,{id:"variants",children:"Variants"}),"\n",(0,t.jsx)(n.p,{children:"Here are the props available for customizing the heatmap chart:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"data"})," (required): Use this prop to populate the chart by providing a series of groups, each containing data for a series of rectangles."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"domainValuesForColorScale"})," and ",(0,t.jsx)(n.strong,{children:"rangeValuesForColorScale"})," (required): These props are used to generate a scale that transforms rectangle values into colors. The domainValuesForColorScale prop accepts an array of numbers, and the rangeValuesForColorScale prop accepts an array of CSS color strings. For optimal results, ensure the length of these arrays is the same."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"xAxisDateFormatString"}),": Use this prop to specify a custom string format for formatting date-based x-axis labels. For more information, refer to ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-time-format#locale_format",children:"d3-time-format | D3 by Observable (d3js.org)"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"yAxisDateFormatString"}),": Use this prop to specify a custom string format for formatting date-based y-axis labels. For more information, refer to ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-time-format#locale_format",children:"d3-time-format | D3 by Observable (d3js.org)"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"xAxisNumberFormatString"}),": Use this prop to specify a custom string format for formatting numeric x-axis labels. For more information, refer to ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-format#locale_format",children:"d3-format | D3 by Observable (d3js.org)"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"yAxisNumberFormatString"}),": Use this prop to specify a custom string format for formatting numeric y-axis labels. For more information, refer to ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-format#locale_format",children:"d3-format | D3 by Observable (d3js.org)"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"xAxisStringFormatter"}),": Use this prop to provide a custom function for formatting string-based x-axis labels."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"yAxisStringFormatter"}),": Use this prop to provide a custom function for formatting string-based y-axis labels."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["For more details, see ",(0,t.jsx)(n.a,{href:"https://developer.microsoft.com/en-us/fluentui#/controls/web/heatmapchart",children:"Fluent UI - Controls - React - HeatMapChart"})]}),"\n",(0,t.jsx)(n.h2,{id:"theming",children:"Theming"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The styles file contains a function called getHeatMapChartStyles, which returns styles for different areas or subcomponents of the chart based on the props passed to it. The base component is wrapped with the styled HOC, which passes the theme (set by the user) and the concatenated styles (obtained from the styling function and any additional styles provided by the user) as props to the base component. Within the base component, the styles are applied to corresponding elements after converting them into class names. This conversion is done by passing theme and other style props as arguments to the function returned by the classNamesFunction utility. To learn more about component styling, refer ",(0,t.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/wiki/Component-Styling",children:"this"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"debugging",children:"Debugging"}),"\n",(0,t.jsx)(n.h2,{id:"error-scenarios",children:"Error scenarios"}),"\n",(0,t.jsx)(n.h2,{id:"localization-aspects",children:"Localization aspects"}),"\n",(0,t.jsx)(n.p,{children:"Currently, the chart supports localization only for numeric texts inside rectangles."}),"\n",(0,t.jsx)(n.h2,{id:"some-notable-prs-and-their-brief-description",children:"Some notable PRs and their brief description"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/pull/28321",children:"Fixing re-render issue for all charts when empty by srmukher \xb7 Pull Request #28321 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/pull/25616",children:"Fix wrong narration in browse mode by krkshitij \xb7 Pull Request #25616 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/pull/24563",children:"Fix legends selection bugs by krkshitij \xb7 Pull Request #24563 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/pull/24903",children:"Fix wrong narration when legend selected by krkshitij \xb7 Pull Request #24903 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/pull/21750",children:"Fix charting callout not hoverable using mouse and callout flickering by AtishayMsft \xb7 Pull Request #21750 \xb7 microsoft/fluentui (github.com)"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"future-improvements",children:"Future improvements"}),"\n",(0,t.jsx)(n.h2,{id:"rendering-details",children:"Rendering details"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"When no data is provided by the user, an empty div is rendered in place of the chart."}),"\n",(0,t.jsxs)(n.li,{children:["Currently, a string axis is created regardless of the type of x and y values, which uses the d3 ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-scale/band",children:"scaleBand"})," utility. This utility has a ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-scale/band#band_bandwidth",children:"bandwidth"})," property that is used to determine the width and height of rectangles. The d3 ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-scale/linear",children:"scaleLinear"})," and ",(0,t.jsx)(n.a,{href:"https://d3js.org/d3-scale/time",children:"scaleTime"})," utilities, used for number and date axes respectively, don't have such a property."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"interactions",children:"Interactions"}),"\n",(0,t.jsx)(n.p,{children:"The chart is wrapped with a FocusZone component to allow focus on its interactive subcomponents. The following subcomponents are accessible using the keyboard:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Rectangle "})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"data-is-focusable"}),": True."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onFocus"}),": Shows a callout near the element containing the rectangle details."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onBlur"}),": Does nothing."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Legend "})," (Legends)"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"data-is-focusable"}),": Depends on the allowFocusOnLegends prop, which is true by default."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onFocus"}),": Highlights the associated rectangles."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onBlur"}),": Unhighlights the associated rectangles."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Users can interact with the following subcomponents using the mouse:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Rectangle"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:""}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseOver"}),": Shows a callout near the element containing the rectangle details."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseOut"}),": Does nothing."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:""}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onClick"}),": Calls the onClick prop associated with the rectangle if provided."]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Root "})," (CartesianChart)"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseLeave"}),": Hides the callout if it is visible."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Legend
"})," (Legends)"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseOver"}),": Highlights the associated rectangles."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseOut"}),": Unhighlights the associated rectangles."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onClick"}),": Highlights the associated rectangles if the legend is not already selected, otherwise unhighlights them."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"known-issues",children:"Known issues"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/issues/30128",children:"[Bug]: Date axis labels formatted to show only the year are being localized as if they were numbers \xb7 Issue #30128 \xb7 microsoft/fluentui"})}),"\n",(0,t.jsx)(n.li,{children:"Y-axis labels are accessible through assistive technologies, such as screen readers."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"design-figma",children:"Design figma"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.figma.com/file/7ywOrSjGW5DEkNETagzXf2/Heat-map?type=design&t=FUFuc5mzEF4G6hag-6",children:"Heat map - Figma"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"learnings",children:"Learnings"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Long y axis labels get clipped which can be fixed by passing custom left or right margin to the chart. In contrast, horizontal bar chart with axis calculates longest label width and updates the margin with that value to prevent the labels from clipping."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"extensions",children:"Extensions"})]})}function d(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},2491:(e,n,s)=>{s.d(n,{Z:()=>t});const t=s.p+"assets/images/heatmapchart-test-coverage-020d10786fd47cd143a84149f2665adb.png"},1151:(e,n,s)=>{s.d(n,{Z:()=>o,a:()=>a});var t=s(7294);const i={},r=t.createContext(i);function a(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/7ef89a43.154ed672.js b/assets/js/7ef89a43.154ed672.js
new file mode 100644
index 0000000000..184b2e4ab2
--- /dev/null
+++ b/assets/js/7ef89a43.154ed672.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[8466],{4488:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>o,frontMatter:()=>r,metadata:()=>l,toc:()=>d});var i=t(5893),s=t(1151);const r={},a="Technical details",l={id:"Technical Details",title:"Technical details",description:"Overview",source:"@site/../../docs/Technical Details.md",sourceDirName:".",slug:"/Technical Details",permalink:"/fluentui-charting-contrib/docs/Technical Details",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Vertical Stacked Bar Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/VerticalStackedBarChart"},next:{title:"Detailed Implementation Steps",permalink:"/fluentui-charting-contrib/docs/Detailed Implementation Steps"}},c={},d=[];function h(e){const n={a:"a",code:"code",h1:"h1",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"technical-details",children:"Technical details"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Overview"})}),"\n",(0,i.jsx)(n.p,{children:"This document describes different chart components in detail."}),"\n",(0,i.jsx)(n.p,{children:"This can be used as a guide to use the charts and contribute new functionalities or improvements to the library."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Components"})}),"\n",(0,i.jsx)(n.p,{children:"The charting components are built using following building blocks."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Cartesian Charts."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Charts built using cartesian coordinate system (two axes - x axis perpendicular to y axis) are called cartesian charts. Majority of the chart in the library are cartesian charts. Some charts like horizontal chart, donut chart, sankey and tree charts are non cartesian charts."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Legends."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"A legend contains a list of the variables appearing in the chart and an example of their appearance. This information allows the data from each variable to be identified in the chart."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Hover Callouts."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Whenever the mouse is hovered over a datapoint, a callout is shown representing the details of data for that point. For a stacked chart, the hover callout can represent the data for all the points for the same X coordinate."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Axes."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Our charts currently support cartesian axes. Different charts support different type of axes - numerical axis, date or time series axis, string or categorical axis. Detals about supported axes can be found in readme for each chart."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Axes support for different charts"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Chart"}),(0,i.jsx)(n.th,{children:"Numeric Axis"}),(0,i.jsx)(n.th,{children:"Date Axis"}),(0,i.jsx)(n.th,{children:"String Axis"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Line Chart"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:"No"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Area Chart"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:"No"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Vertical Bar Chart"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:"No"}),(0,i.jsx)(n.td,{children:"Yes"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Vertical Stacked Bar Chart"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:"No"}),(0,i.jsx)(n.td,{children:"Yes"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Grouped Vertical Bar Chart"}),(0,i.jsx)(n.td,{children:"No"}),(0,i.jsx)(n.td,{children:"No"}),(0,i.jsx)(n.td,{children:"Yes"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Heatmap Chart"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:"Yes"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Horizontal Bar Chart"}),(0,i.jsx)(n.td,{children:"--"}),(0,i.jsx)(n.td,{children:"--"}),(0,i.jsx)(n.td,{children:"--"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Donut Chart"}),(0,i.jsx)(n.td,{children:"--"}),(0,i.jsx)(n.td,{children:"--"}),(0,i.jsx)(n.td,{children:"--"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Sankey Chart"}),(0,i.jsx)(n.td,{children:"--"}),(0,i.jsx)(n.td,{children:"--"}),(0,i.jsx)(n.td,{children:"--"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Tree Chart"}),(0,i.jsx)(n.td,{children:"--"}),(0,i.jsx)(n.td,{children:"--"}),(0,i.jsx)(n.td,{children:"--"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Sparkline Chart"}),(0,i.jsx)(n.td,{children:"--"}),(0,i.jsx)(n.td,{children:"--"}),(0,i.jsx)(n.td,{children:"--"})]})]})]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Axis localization\nThe axes support 2 ways of localization."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Javascript provided inbuilt localization for numeric and date axis. Specify the culture and dateLocalizeOptions for date axis to define target localization. Refer the ",(0,i.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString",children:"javascript localization guide"})," for usage."]}),"\n",(0,i.jsxs)(n.li,{children:["Custom locale definition: The consumer of the library can specify a custom locale definition as supported by d3 (like ",(0,i.jsx)(n.a,{href:"https://github.com/d3/d3-time-format/blob/main/locale/en-US.json",children:"this"}),"). The date axis will use the date range and the multiformat specified in the definition to determine the correct format to show in the ticks. For example - If the date range is in days then the axis will show hourly ticks. If the date range spans across months then the axis will show months in tick labels and so on.\nSpecify the custom locale definition in the timeFormatLocale prop.\nRefer to the Custom Locale Date Axis example in line chart for sample usage."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Date axis formatting\nThe date axis can be custom formatted using the customDateTimeFormatter prop."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Event annotations (Available in line charts)."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Data can be annotated using vertical lines representing the events of interest. See ",(0,i.jsx)(n.a,{href:"https://fluentuipr.z22.web.core.windows.net/heads/master/react-charting/demo/index.html#/examples/linechart#Variants",children:"line chart with events"})," for example."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Typography."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Our font classes represent the type ramp for the fluent design language. Each base class sets a default size, weight, and color."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Colors"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["The charts are designed using the accessible color palette defined for the fluent design system.\nRefer ",(0,i.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/blob/master/packages/react-charting/docs/colors.md",children:"this"})," guide for details about charting color palette and its usage."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Themes"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["The library supports light and dark mode out of box. In addition, consumers can define their own themese as detailed ",(0,i.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/wiki/Theming",children:"here"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Accessibility."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Our charts have elaborate accessibility support. The charts are WCAG 2.1 MAS C compliant for accessibility.\nConsumers can define their own aria labels for each point by setting the ",(0,i.jsx)(n.code,{children:"xAxisCalloutAccessibilityData"})," and ",(0,i.jsx)(n.code,{children:"callOutAccessibilityData"})," properties."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"RTL Support"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The charts support RTL languages wherever applicable."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Component Styling"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/wiki/Component-Styling",children:"This article"})," talks about the styling approach followed within charting library."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Details about ticks."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Tick values are applicable only for date axis. Doesn't work for string or numeric axis.\nTickcount works for numeric and date axis. Doesn't work for string (scaleBand) axis."}),"\n"]}),"\n"]}),"\n"]})]})}function o(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>l,a:()=>a});var i=t(7294);const s={},r=i.createContext(s);function a(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/7ef89a43.37a63f5c.js b/assets/js/7ef89a43.37a63f5c.js
deleted file mode 100644
index 26d385d50b..0000000000
--- a/assets/js/7ef89a43.37a63f5c.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[8466],{4488:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>o,frontMatter:()=>r,metadata:()=>l,toc:()=>d});var i=t(5893),s=t(1151);const r={},a="Technical details",l={id:"Technical Details",title:"Technical details",description:"Overview",source:"@site/../../docs/Technical Details.md",sourceDirName:".",slug:"/Technical Details",permalink:"/fluentui-charting-contrib/docs/Technical Details",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Contributor Guide",permalink:"/fluentui-charting-contrib/docs/Contributor Guide"},next:{title:"Detailed Implementation Steps",permalink:"/fluentui-charting-contrib/docs/Detailed Implementation Steps"}},c={},d=[];function h(e){const n={a:"a",code:"code",h1:"h1",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"technical-details",children:"Technical details"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Overview"})}),"\n",(0,i.jsx)(n.p,{children:"This document describes different chart components in detail."}),"\n",(0,i.jsx)(n.p,{children:"This can be used as a guide to use the charts and contribute new functionalities or improvements to the library."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Components"})}),"\n",(0,i.jsx)(n.p,{children:"The charting components are built using following building blocks."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Cartesian Charts."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Charts built using cartesian coordinate system (two axes - x axis perpendicular to y axis) are called cartesian charts. Majority of the chart in the library are cartesian charts. Some charts like horizontal chart, donut chart, sankey and tree charts are non cartesian charts."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Legends."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"A legend contains a list of the variables appearing in the chart and an example of their appearance. This information allows the data from each variable to be identified in the chart."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Hover Callouts."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Whenever the mouse is hovered over a datapoint, a callout is shown representing the details of data for that point. For a stacked chart, the hover callout can represent the data for all the points for the same X coordinate."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Axes."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Our charts currently support cartesian axes. Different charts support different type of axes - numerical axis, date or time series axis, string or categorical axis. Detals about supported axes can be found in readme for each chart."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Axes support for different charts"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Chart"}),(0,i.jsx)(n.th,{children:"Numeric Axis"}),(0,i.jsx)(n.th,{children:"Date Axis"}),(0,i.jsx)(n.th,{children:"String Axis"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Line Chart"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:"No"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Area Chart"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:"No"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Vertical Bar Chart"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:"No"}),(0,i.jsx)(n.td,{children:"Yes"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Vertical Stacked Bar Chart"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:"No"}),(0,i.jsx)(n.td,{children:"Yes"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Grouped Vertical Bar Chart"}),(0,i.jsx)(n.td,{children:"No"}),(0,i.jsx)(n.td,{children:"No"}),(0,i.jsx)(n.td,{children:"Yes"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Heatmap Chart"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:"Yes"}),(0,i.jsx)(n.td,{children:"Yes"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Horizontal Bar Chart"}),(0,i.jsx)(n.td,{children:"--"}),(0,i.jsx)(n.td,{children:"--"}),(0,i.jsx)(n.td,{children:"--"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Donut Chart"}),(0,i.jsx)(n.td,{children:"--"}),(0,i.jsx)(n.td,{children:"--"}),(0,i.jsx)(n.td,{children:"--"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Sankey Chart"}),(0,i.jsx)(n.td,{children:"--"}),(0,i.jsx)(n.td,{children:"--"}),(0,i.jsx)(n.td,{children:"--"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Tree Chart"}),(0,i.jsx)(n.td,{children:"--"}),(0,i.jsx)(n.td,{children:"--"}),(0,i.jsx)(n.td,{children:"--"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Sparkline Chart"}),(0,i.jsx)(n.td,{children:"--"}),(0,i.jsx)(n.td,{children:"--"}),(0,i.jsx)(n.td,{children:"--"})]})]})]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Axis localization\nThe axes support 2 ways of localization."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Javascript provided inbuilt localization for numeric and date axis. Specify the culture and dateLocalizeOptions for date axis to define target localization. Refer the ",(0,i.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString",children:"javascript localization guide"})," for usage."]}),"\n",(0,i.jsxs)(n.li,{children:["Custom locale definition: The consumer of the library can specify a custom locale definition as supported by d3 (like ",(0,i.jsx)(n.a,{href:"https://github.com/d3/d3-time-format/blob/main/locale/en-US.json",children:"this"}),"). The date axis will use the date range and the multiformat specified in the definition to determine the correct format to show in the ticks. For example - If the date range is in days then the axis will show hourly ticks. If the date range spans across months then the axis will show months in tick labels and so on.\nSpecify the custom locale definition in the timeFormatLocale prop.\nRefer to the Custom Locale Date Axis example in line chart for sample usage."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Date axis formatting\nThe date axis can be custom formatted using the customDateTimeFormatter prop."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Event annotations (Available in line charts)."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Data can be annotated using vertical lines representing the events of interest. See ",(0,i.jsx)(n.a,{href:"https://fluentuipr.z22.web.core.windows.net/heads/master/react-charting/demo/index.html#/examples/linechart#Variants",children:"line chart with events"})," for example."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Typography."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Our font classes represent the type ramp for the fluent design language. Each base class sets a default size, weight, and color."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Colors"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["The charts are designed using the accessible color palette defined for the fluent design system.\nRefer ",(0,i.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/blob/master/packages/react-charting/docs/colors.md",children:"this"})," guide for details about charting color palette and its usage."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Themes"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["The library supports light and dark mode out of box. In addition, consumers can define their own themese as detailed ",(0,i.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/wiki/Theming",children:"here"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Accessibility."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Our charts have elaborate accessibility support. The charts are WCAG 2.1 MAS C compliant for accessibility.\nConsumers can define their own aria labels for each point by setting the ",(0,i.jsx)(n.code,{children:"xAxisCalloutAccessibilityData"})," and ",(0,i.jsx)(n.code,{children:"callOutAccessibilityData"})," properties."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"RTL Support"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The charts support RTL languages wherever applicable."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Component Styling"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/wiki/Component-Styling",children:"This article"})," talks about the styling approach followed within charting library."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Details about ticks."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Tick values are applicable only for date axis. Doesn't work for string or numeric axis.\nTickcount works for numeric and date axis. Doesn't work for string (scaleBand) axis."}),"\n"]}),"\n"]}),"\n"]})]})}function o(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>l,a:()=>a});var i=t(7294);const s={},r=i.createContext(s);function a(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/80060540.a76e6a01.js b/assets/js/80060540.a76e6a01.js
deleted file mode 100644
index e7dc15b3af..0000000000
--- a/assets/js/80060540.a76e6a01.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[1321],{9431:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>h});var t=s(5893),i=s(1151);const r={},a="Contributor guide: Gauge Chart",l={id:"Charting-Concepts/GaugeChart",title:"Contributor guide: Gauge Chart",description:"Gauge chart measures the progress of a metric against its target and its primary components are a speedometer and a needle. The speedometer usually consists of color-coded segments progressing value from left to right.",source:"@site/../../docs/Charting-Concepts/GaugeChart.md",sourceDirName:"Charting-Concepts",slug:"/Charting-Concepts/GaugeChart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/GaugeChart",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Contributor guide: Donut Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/DonutChart"},next:{title:"Contributor guide: Grouped Vertical Bar Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/GroupedVerticalBarChart"}},o={},h=[{value:"Use cases",id:"use-cases",level:2},{value:"Dev Design details",id:"dev-design-details",level:2},{value:"Mathematical/Geometrical concepts",id:"mathematicalgeometrical-concepts",level:2},{value:"Performance",id:"performance",level:2},{value:"Accessibility",id:"accessibility",level:2},{value:"Testing",id:"testing",level:2},{value:"Variants",id:"variants",level:2},{value:"Theming",id:"theming",level:2},{value:"Debugging",id:"debugging",level:2},{value:"Error scenarios",id:"error-scenarios",level:2},{value:"Localization aspects",id:"localization-aspects",level:2},{value:"Some notable PRs and their brief description",id:"some-notable-prs-and-their-brief-description",level:2},{value:"Future improvements",id:"future-improvements",level:2},{value:"Rendering details",id:"rendering-details",level:2},{value:"Interactions",id:"interactions",level:2},{value:"Known issues",id:"known-issues",level:2},{value:"Design figma",id:"design-figma",level:2},{value:"Learnings",id:"learnings",level:2},{value:"Extensions",id:"extensions",level:2}];function c(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"contributor-guide-gauge-chart",children:"Contributor guide: Gauge Chart"}),"\n",(0,t.jsx)(n.p,{children:"Gauge chart measures the progress of a metric against its target and its primary components are a speedometer and a needle. The speedometer usually consists of color-coded segments progressing value from left to right."}),"\n",(0,t.jsx)(n.h2,{id:"use-cases",children:"Use cases"}),"\n",(0,t.jsx)(n.p,{children:"Gauge chart offers a quick and intuitive way to evaluate a single value within a specific range and its relation to targets or thresholds. Here are some common use cases for gauge chart:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Performance Monitoring: Track metrics like sales or customer satisfaction against predefined benchmarks."}),"\n",(0,t.jsx)(n.li,{children:"KPI Tracking: Monitor progress towards goals by displaying key performance indicators."}),"\n",(0,t.jsx)(n.li,{children:"Health and Fitness: Display health parameters such as heart rate or steps taken."}),"\n",(0,t.jsx)(n.li,{children:"Survey Feedback: Visualize satisfaction scores or survey feedback."}),"\n",(0,t.jsx)(n.li,{children:"Resource Allocation: Show resource distribution across different categories."}),"\n",(0,t.jsx)(n.li,{children:"Risk Assessment: Assess risk levels or safety ratings."}),"\n",(0,t.jsx)(n.li,{children:"Project Progress: Represent project or task completion percentage."}),"\n",(0,t.jsx)(n.li,{children:"Quality Control: Monitor defect or error rates."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"dev-design-details",children:"Dev Design details"}),"\n",(0,t.jsx)("img",{src:s(6399).Z,alt:"Gauge chart dev design",width:"300"}),"\n",(0,t.jsx)(n.p,{children:"The Gauge chart comprises the following components and subcomponents:"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"GaugeChart"}),": This is the main component responsible for rendering and managing subcomponents such as chart title, limits (min and max values), segments, needle, chart value, sublabel, and other components. It handles user interactions and provides the overall functionality of the chart."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"FocusZone"}),": This component facilitates focus navigation within the Gauge chart. It allows users to navigate between focusable subcomponents, such as segments and the needle, using the arrow and tab keys."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"SVGTooltipText"}),": This component is used to render the chart value and sublabel as SVG text elements with an optional tooltip. The tooltip is triggered when the content overflows and appears when users hover over or focus on the element."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Legends"}),": Legends are a list of strings that identify each segment in the Gauge chart. The Legends component renders a button for each legend, enabling users to highlight the corresponding segment by hovering over or selecting the legend."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Callout"}),": This component functions as an anchored tip, offering additional information about the segment, needle, or chart value that is currently hovered over or focused without blocking the user."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Segments"}),": These are the color-coded intervals that indicate different levels or categories."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Needle"}),": It indicates the current value of the chart within a range."]}),"\n",(0,t.jsx)(n.h2,{id:"mathematicalgeometrical-concepts",children:"Mathematical/Geometrical concepts"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Segments in the chart are generated using the ",(0,t.jsx)(n.a,{href:"https://github.com/d3/d3-shape#arcs",children:"arc"})," utility from the ",(0,t.jsx)(n.a,{href:"https://github.com/d3/d3-shape",children:"d3-shape"})," library. This utility returns an arc generator that produces path data based on specified angle and radius values. The arcs are always centred at coordinates {0, 0}, so a transform is applied to move the arc to a different position."]}),"\n",(0,t.jsx)(n.li,{children:"Here, an angle of 0 radians corresponds to the positive y-axis. The arc is created in a clockwise direction if the signed difference between the start and end angles is positive. The angular span of each segment is determined by the ratio of its individual size to the total size of all segments."}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/d3/d3-shape#arc_padAngle",children:"pad angle"})," is converted to a fixed linear distance separating adjacent arcs, defined as padRadius * padAngle. As per the design doc, the desired distance between adjacent arcs is 2px, referred to as ARC_PADDING. To maintain this distance between the outer boundaries of the arcs, padRadius is kept the same as outerRadius, and padAngle is calculated as ARC_PADDING / padRadius. Note that if the inner radius or angular span is small relative to the pad angle, it may not be possible to maintain parallel edges between adjacent arcs."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"performance",children:"Performance"}),"\n",(0,t.jsx)(n.h2,{id:"accessibility",children:"Accessibility"}),"\n",(0,t.jsx)(n.p,{children:"The following subcomponents are accessible using a screen reader:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Chart "}),": The following attributes provide an accessible name describing the contents of the chart."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"role"}),' = "presentation"']}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"aria-label"}),' = "This is a gauge chart with {numSegments} section represented."']}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Min value "}),": It is already accessible to screen readers, but the content doesn\u2019t convey complete information. The following attributes specify a different accessible name for the min value."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"role"}),' = "img"']}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"aria-label"}),' = "Min value: {minValue}"']}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Max value "}),": It is already accessible to screen readers, but the content doesn\u2019t convey complete information. The following attributes specify a different accessible name for the max value."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"role"}),' = "img"']}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"aria-label"}),' = "Max value: {adjustedMaxValue}"']}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Segments "}),": The following attributes provide an accessible name describing the segment."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"role"}),' = "img"']}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"aria-label"}),' =\n"{segmentLegend}, {segmentStart} - {segmentEnd}" when variant is GaugeChartVariant.MultipleSegments, or\n"{segmentLegend}, {segmentSize} out of {totalSizeOfSegments} or {segmentSizeInPercent}%" when variant is GaugeChartVariant.SingleSegment.']}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Users can provide a custom accessible name or description for a segment using its accessibilityData prop."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Chart value "}),": It is already accessible to screen readers, but the content doesn\u2019t convey complete information. The following attributes specify a different accessible name for the chart value."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"role"}),' = "img"']}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"aria-label"}),' = "Current value: {formattedChartValue}"']}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Sublabel "}),": It is already accessible to screen readers. The following attributes provide an accessible name for the sublabel."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"role"}),' = "img"']}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"aria-label"})," = the sublabel itself"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"testing",children:"Testing"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Test coverage report",src:s(9485).Z+"",width:"1430",height:"456"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"/fluentui-charting-contrib/docs/Test%20Plans/GaugeChart/ComponentTests",children:"GaugeChart test plan"})}),"\n",(0,t.jsx)(n.h2,{id:"variants",children:"Variants"}),"\n",(0,t.jsx)(n.p,{children:"Here are the props available for customizing the gauge chart:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"width"})," and ",(0,t.jsx)(n.strong,{children:"height"}),": These props determine the diameter of the gauge. If not provided, a default diameter of 140px is used."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"chartTitle"}),": Use this prop to render a title above the gauge."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"chartValue"}),": This required prop controls the rotation of the needle. If the chart value is less than the minimum, the needle points to the min value. Similarly, if it exceeds the maximum, the needle points to the max value."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"segments"}),": Use this required prop to divide the gauge into colored sections. The segments can have fixed sizes or vary with the chart value to create a sweeping effect. Negative segment sizes are treated as 0."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"minValue"}),": Use this prop if the minimum value of the gauge is different from 0."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"maxValue"}),": Use this prop to render a placeholder segment when the difference between the max and min values is larger than the total size of the segments. If the difference is smaller, the max value will be adjusted so that the total size of the segments matches the difference."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"sublabel"}),": Use this prop to render additional text below the chart value."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"hideMinMax"}),": Set this prop to true to hide the min and max values of the gauge."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"chartValueFormat"}),": This prop controls how the chart value is displayed. Set it to one of the following options:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"A custom formatter function that returns a string representing the chart value."}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.em,{children:"GaugeValueFormat.Fraction"}),": Renders the chart value as a fraction."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.em,{children:"GaugeValueFormat.Percentage"}),": Renders the chart value as a percentage. This is the default format."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Note: If the min value is non-zero and no formatter function is provided, the chart value will be rendered as a number."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"variant"}),": This prop determines the presentation style of the gauge chart. Set it to one of the following options:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.em,{children:"GaugeChartVariant.SingleSegment"}),": Displays and announces the segment sizes as percentages."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.em,{children:"GaugeChartVariant.MultipleSegments"}),": Displays and announces the segment sizes as ranges. This is the default variant."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["For more details, see ",(0,t.jsx)(n.a,{href:"https://developer.microsoft.com/en-us/fluentui#/controls/web/gaugechart",children:"Fluent UI - Controls - React - GaugeChart"})]}),"\n",(0,t.jsx)(n.h2,{id:"theming",children:"Theming"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The styles file contains a function called getStyles, which returns styles for different areas or subcomponents of the chart based on the props passed to it. The base component is wrapped with the styled HOC, which passes the theme (set by the user) and the concatenated styles (obtained from the styling function and any additional styles provided by the user) as props to the base component. Within the base component, the styles are applied to corresponding elements after converting them into class names. This conversion is done by passing theme and other style props as arguments to the function returned by the classNamesFunction utility. To learn more about component styling, refer ",(0,t.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/wiki/Component-Styling",children:"this"}),"."]}),"\n",(0,t.jsx)(n.li,{children:"For each segment in the chart, the color prop is optional. If the color prop is not defined, a color is selected from the qualitative palette using the getNextColor utility. However, if the color prop is defined, the getColorFromToken utility is used to determine the appropriate CSS color. If the value of the color prop is a theme-specific color token from the DataVizPalette, the utility will return the corresponding CSS color. Otherwise, if the color prop is already a valid CSS color, it will be returned as is."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"debugging",children:"Debugging"}),"\n",(0,t.jsx)(n.h2,{id:"error-scenarios",children:"Error scenarios"}),"\n",(0,t.jsx)(n.h2,{id:"localization-aspects",children:"Localization aspects"}),"\n",(0,t.jsx)(n.p,{children:"Currently, the chart supports localization only for the callout content."}),"\n",(0,t.jsx)(n.h2,{id:"some-notable-prs-and-their-brief-description",children:"Some notable PRs and their brief description"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/pull/27170",children:"Add gauge chart by krkshitij \xb7 Pull Request #27170 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,t.jsx)(n.h2,{id:"future-improvements",children:"Future improvements"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Add min width and height"}),"\n",(0,t.jsx)(n.li,{children:"Show message when chart is empty"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"rendering-details",children:"Rendering details"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The calculation of margins for the Gauge chart takes into account the presence of the chart title, sublabel, and limits (min and max values) to ensure that they do not overlap with the segments. Additionally, there is an extra margin of 16px around the gauge, referred to as GAUGE_MARGIN."}),"\n",(0,t.jsx)(n.li,{children:"Assuming that the legends do not wrap, the legends container is considered to have a fixed height of 24px. This helps calculate the available height for the element."}),"\n",(0,t.jsx)(n.li,{children:"The outer radius of the gauge is calculated based on the width and height props. If these props are not provided, the viewable width and height of the root div when the component mounts are used instead."}),"\n",(0,t.jsx)(n.li,{children:"According to the design doc, the font size of the chart value and the arc width vary depending on the size of the gauge chart. We cannot use CSS media queries in this case because the styles would be conditionally applied based on browser and operating system parameters. Instead, we use the BREAKPOINTS constant to determine the appropriate inner radius of the gauge and the font size of the chart value."}),"\n",(0,t.jsx)(n.li,{children:"If the difference between the max and min values exceeds the total size of all segments, a placeholder segment is rendered with a value equal to the difference. However, if the difference is smaller, the maximum value is adjusted to the correct value."}),"\n",(0,t.jsx)(n.li,{children:"The sweep fraction is calculated using the chart value, min value, and adjusted max value to determine the rotation of the needle."}),"\n",(0,t.jsx)(n.li,{children:"The min and max values are formatted with SI prefixes, as mentioned in the design doc. This formatting ensures that the values do not exceed 6 characters, equivalent to a width of 36px, referred to as LABEL_WIDTH."}),"\n",(0,t.jsx)(n.li,{children:"By default, the focus outline for segments is rectangular in shape. So the default outline is removed, and a custom outline is shown or hidden based on focus and blur events by adjusting the stroke width."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"interactions",children:"Interactions"}),"\n",(0,t.jsx)(n.p,{children:"The chart is wrapped with a FocusZone component to allow focus on its interactive subcomponents. The following subcomponents are accessible using the keyboard:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Segments "})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"data-is-focusable"}),": True"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onFocus"}),": Shows a callout near the element containing the chart value and all segments, along with their respective ranges"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onBlur"}),": Hides the callout if it is visible"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Needle "})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"data-is-focusable"}),": True"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onFocus"}),": Shows a callout near the element containing the chart value and all segments, along with their respective ranges"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onBlur"}),": Hides the callout if it is visible"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Chart value "})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"data-is-focusable"}),": True if the text content overflows the specified width and height"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onFocus"}),": Shows a tooltip with the complete content"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onBlur"}),": Hides the tooltip if it is visible"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Legend "})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"data-is-focusable"}),": Depends on the allowFocusOnLegends prop, which is true by default"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onFocus"}),": Highlights the corresponding segment"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onBlur"}),":\tUnhighlights the corresponding segment"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Users can interact with the following subcomponents using the mouse:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Segments "})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseEnter"}),": Shows a callout near the element containing the chart value and all segments, along with their respective ranges"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseMove"}),": Shows the callout if it is not already visible"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Needle "})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseEnter"}),": Shows a callout near the element containing the chart value and all segments, along with their respective ranges"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseMove"}),": Shows the callout if it is not already visible"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Chart value"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:""}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseEnter"}),": Shows a callout near the element containing the chart value and all segments, along with their respective ranges"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseMove"}),": Shows the callout if it is not already visible"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:""}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseEnter"}),": Shows a tooltip with the complete content if the text content overflows the specified width and height"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseLeave"}),": Hides the tooltip if it is visible"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Sublabel "})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseEnter"}),": Shows a tooltip with the complete content if the text content overflows the specified width and height"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseLeave"}),": Hides the tooltip if it is visible"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Chart "})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseLeave"}),": Hides the callout if it is visible"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Legend "})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseOver"}),": Highlights the corresponding segment"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseOut"}),": Unhighlights the corresponding segment"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onClick"}),": Highlights the corresponding segment if the legend is not already selected, otherwise unhighlights it"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"known-issues",children:"Known issues"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:['The chart is assigned the role of presentation. The "presentation" role and its synonym "none" remove an element\'s implicit ARIA semantics from being exposed to the accessibility tree. For more details, see ',(0,t.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/presentation_role",children:"ARIA: presentation role - Accessibility | MDN"})]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"design-figma",children:"Design figma"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"https://www.figma.com/file/oNWKEgIOCSLElvMZPOVMCq/ARCHIVED-Fluent-Data-Viz-(WIP)?type=design&node-id=2415-274387&mode=design&t=jdEfxXd3aMNuyWuz-4",children:"Gauge chart \u2013 Figma"})}),"\n",(0,t.jsx)(n.h2,{id:"learnings",children:"Learnings"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The needle is expanded from all sides by half the stroke width to maintain consistent dimensions with the design doc. This is necessary because the stroke is always centered on the outline, with half on the inside and half on the outside."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"extensions",children:"Extensions"})]})}function d(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},6399:(e,n,s)=>{s.d(n,{Z:()=>t});const t=s.p+"assets/images/gaugechart-dev-design-35b9551ffa7dc491d20730e4a65e9c2c.png"},9485:(e,n,s)=>{s.d(n,{Z:()=>t});const t=s.p+"assets/images/gaugechart-test-coverage-eb67779e6e7ab65f6e1aebce72af193d.png"},1151:(e,n,s)=>{s.d(n,{Z:()=>l,a:()=>a});var t=s(7294);const i={},r=t.createContext(i);function a(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/80060540.fa6ad726.js b/assets/js/80060540.fa6ad726.js
new file mode 100644
index 0000000000..3cf0f426d8
--- /dev/null
+++ b/assets/js/80060540.fa6ad726.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[1321],{9431:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>h});var t=s(5893),i=s(1151);const r={},a="Gauge Chart",l={id:"Charting-Concepts/GaugeChart",title:"Gauge Chart",description:"Gauge chart measures the progress of a metric against its target and its primary components are a speedometer and a needle. The speedometer usually consists of color-coded segments progressing value from left to right.",source:"@site/../../docs/Charting-Concepts/GaugeChart.md",sourceDirName:"Charting-Concepts",slug:"/Charting-Concepts/GaugeChart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/GaugeChart",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Donut Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/DonutChart"},next:{title:"Grouped Vertical Bar Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/GroupedVerticalBarChart"}},o={},h=[{value:"Use cases",id:"use-cases",level:2},{value:"Dev Design details",id:"dev-design-details",level:2},{value:"Mathematical/Geometrical concepts",id:"mathematicalgeometrical-concepts",level:2},{value:"Performance",id:"performance",level:2},{value:"Accessibility",id:"accessibility",level:2},{value:"Testing",id:"testing",level:2},{value:"Variants",id:"variants",level:2},{value:"Theming",id:"theming",level:2},{value:"Debugging",id:"debugging",level:2},{value:"Error scenarios",id:"error-scenarios",level:2},{value:"Localization aspects",id:"localization-aspects",level:2},{value:"Some notable PRs and their brief description",id:"some-notable-prs-and-their-brief-description",level:2},{value:"Future improvements",id:"future-improvements",level:2},{value:"Rendering details",id:"rendering-details",level:2},{value:"Interactions",id:"interactions",level:2},{value:"Known issues",id:"known-issues",level:2},{value:"Design figma",id:"design-figma",level:2},{value:"Learnings",id:"learnings",level:2},{value:"Extensions",id:"extensions",level:2}];function c(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"gauge-chart",children:"Gauge Chart"}),"\n",(0,t.jsx)(n.p,{children:"Gauge chart measures the progress of a metric against its target and its primary components are a speedometer and a needle. The speedometer usually consists of color-coded segments progressing value from left to right."}),"\n",(0,t.jsx)(n.h2,{id:"use-cases",children:"Use cases"}),"\n",(0,t.jsx)(n.p,{children:"Gauge chart offers a quick and intuitive way to evaluate a single value within a specific range and its relation to targets or thresholds. Here are some common use cases for gauge chart:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Performance Monitoring: Track metrics like sales or customer satisfaction against predefined benchmarks."}),"\n",(0,t.jsx)(n.li,{children:"KPI Tracking: Monitor progress towards goals by displaying key performance indicators."}),"\n",(0,t.jsx)(n.li,{children:"Health and Fitness: Display health parameters such as heart rate or steps taken."}),"\n",(0,t.jsx)(n.li,{children:"Survey Feedback: Visualize satisfaction scores or survey feedback."}),"\n",(0,t.jsx)(n.li,{children:"Resource Allocation: Show resource distribution across different categories."}),"\n",(0,t.jsx)(n.li,{children:"Risk Assessment: Assess risk levels or safety ratings."}),"\n",(0,t.jsx)(n.li,{children:"Project Progress: Represent project or task completion percentage."}),"\n",(0,t.jsx)(n.li,{children:"Quality Control: Monitor defect or error rates."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"dev-design-details",children:"Dev Design details"}),"\n",(0,t.jsx)("img",{src:s(6399).Z,alt:"Gauge chart dev design",width:"300"}),"\n",(0,t.jsx)(n.p,{children:"The Gauge chart comprises the following components and subcomponents:"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"GaugeChart"}),": This is the main component responsible for rendering and managing subcomponents such as chart title, limits (min and max values), segments, needle, chart value, sublabel, and other components. It handles user interactions and provides the overall functionality of the chart."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"FocusZone"}),": This component facilitates focus navigation within the Gauge chart. It allows users to navigate between focusable subcomponents, such as segments and the needle, using the arrow and tab keys."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"SVGTooltipText"}),": This component is used to render the chart value and sublabel as SVG text elements with an optional tooltip. The tooltip is triggered when the content overflows and appears when users hover over or focus on the element."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Legends"}),": Legends are a list of strings that identify each segment in the Gauge chart. The Legends component renders a button for each legend, enabling users to highlight the corresponding segment by hovering over or selecting the legend."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Callout"}),": This component functions as an anchored tip, offering additional information about the segment, needle, or chart value that is currently hovered over or focused without blocking the user."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Segments"}),": These are the color-coded intervals that indicate different levels or categories."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Needle"}),": It indicates the current value of the chart within a range."]}),"\n",(0,t.jsx)(n.h2,{id:"mathematicalgeometrical-concepts",children:"Mathematical/Geometrical concepts"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Segments in the chart are generated using the ",(0,t.jsx)(n.a,{href:"https://github.com/d3/d3-shape#arcs",children:"arc"})," utility from the ",(0,t.jsx)(n.a,{href:"https://github.com/d3/d3-shape",children:"d3-shape"})," library. This utility returns an arc generator that produces path data based on specified angle and radius values. The arcs are always centred at coordinates {0, 0}, so a transform is applied to move the arc to a different position."]}),"\n",(0,t.jsx)(n.li,{children:"Here, an angle of 0 radians corresponds to the positive y-axis. The arc is created in a clockwise direction if the signed difference between the start and end angles is positive. The angular span of each segment is determined by the ratio of its individual size to the total size of all segments."}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/d3/d3-shape#arc_padAngle",children:"pad angle"})," is converted to a fixed linear distance separating adjacent arcs, defined as padRadius * padAngle. As per the design doc, the desired distance between adjacent arcs is 2px, referred to as ARC_PADDING. To maintain this distance between the outer boundaries of the arcs, padRadius is kept the same as outerRadius, and padAngle is calculated as ARC_PADDING / padRadius. Note that if the inner radius or angular span is small relative to the pad angle, it may not be possible to maintain parallel edges between adjacent arcs."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"performance",children:"Performance"}),"\n",(0,t.jsx)(n.h2,{id:"accessibility",children:"Accessibility"}),"\n",(0,t.jsx)(n.p,{children:"The following subcomponents are accessible using a screen reader:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Chart "}),": The following attributes provide an accessible name describing the contents of the chart."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"role"}),' = "presentation"']}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"aria-label"}),' = "This is a gauge chart with {numSegments} section represented."']}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Min value "}),": It is already accessible to screen readers, but the content doesn\u2019t convey complete information. The following attributes specify a different accessible name for the min value."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"role"}),' = "img"']}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"aria-label"}),' = "Min value: {minValue}"']}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Max value "}),": It is already accessible to screen readers, but the content doesn\u2019t convey complete information. The following attributes specify a different accessible name for the max value."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"role"}),' = "img"']}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"aria-label"}),' = "Max value: {adjustedMaxValue}"']}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Segments "}),": The following attributes provide an accessible name describing the segment."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"role"}),' = "img"']}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"aria-label"}),' =\n"{segmentLegend}, {segmentStart} - {segmentEnd}" when variant is GaugeChartVariant.MultipleSegments, or\n"{segmentLegend}, {segmentSize} out of {totalSizeOfSegments} or {segmentSizeInPercent}%" when variant is GaugeChartVariant.SingleSegment.']}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Users can provide a custom accessible name or description for a segment using its accessibilityData prop."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Chart value "}),": It is already accessible to screen readers, but the content doesn\u2019t convey complete information. The following attributes specify a different accessible name for the chart value."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"role"}),' = "img"']}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"aria-label"}),' = "Current value: {formattedChartValue}"']}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Sublabel "}),": It is already accessible to screen readers. The following attributes provide an accessible name for the sublabel."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"role"}),' = "img"']}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"aria-label"})," = the sublabel itself"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"testing",children:"Testing"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Test coverage report",src:s(9485).Z+"",width:"1430",height:"456"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"/fluentui-charting-contrib/docs/Test%20Plans/GaugeChart/ComponentTests",children:"GaugeChart test plan"})}),"\n",(0,t.jsx)(n.h2,{id:"variants",children:"Variants"}),"\n",(0,t.jsx)(n.p,{children:"Here are the props available for customizing the gauge chart:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"width"})," and ",(0,t.jsx)(n.strong,{children:"height"}),": These props determine the diameter of the gauge. If not provided, a default diameter of 140px is used."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"chartTitle"}),": Use this prop to render a title above the gauge."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"chartValue"}),": This required prop controls the rotation of the needle. If the chart value is less than the minimum, the needle points to the min value. Similarly, if it exceeds the maximum, the needle points to the max value."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"segments"}),": Use this required prop to divide the gauge into colored sections. The segments can have fixed sizes or vary with the chart value to create a sweeping effect. Negative segment sizes are treated as 0."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"minValue"}),": Use this prop if the minimum value of the gauge is different from 0."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"maxValue"}),": Use this prop to render a placeholder segment when the difference between the max and min values is larger than the total size of the segments. If the difference is smaller, the max value will be adjusted so that the total size of the segments matches the difference."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"sublabel"}),": Use this prop to render additional text below the chart value."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"hideMinMax"}),": Set this prop to true to hide the min and max values of the gauge."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"chartValueFormat"}),": This prop controls how the chart value is displayed. Set it to one of the following options:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"A custom formatter function that returns a string representing the chart value."}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.em,{children:"GaugeValueFormat.Fraction"}),": Renders the chart value as a fraction."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.em,{children:"GaugeValueFormat.Percentage"}),": Renders the chart value as a percentage. This is the default format."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Note: If the min value is non-zero and no formatter function is provided, the chart value will be rendered as a number."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"variant"}),": This prop determines the presentation style of the gauge chart. Set it to one of the following options:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.em,{children:"GaugeChartVariant.SingleSegment"}),": Displays and announces the segment sizes as percentages."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.em,{children:"GaugeChartVariant.MultipleSegments"}),": Displays and announces the segment sizes as ranges. This is the default variant."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["For more details, see ",(0,t.jsx)(n.a,{href:"https://developer.microsoft.com/en-us/fluentui#/controls/web/gaugechart",children:"Fluent UI - Controls - React - GaugeChart"})]}),"\n",(0,t.jsx)(n.h2,{id:"theming",children:"Theming"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The styles file contains a function called getStyles, which returns styles for different areas or subcomponents of the chart based on the props passed to it. The base component is wrapped with the styled HOC, which passes the theme (set by the user) and the concatenated styles (obtained from the styling function and any additional styles provided by the user) as props to the base component. Within the base component, the styles are applied to corresponding elements after converting them into class names. This conversion is done by passing theme and other style props as arguments to the function returned by the classNamesFunction utility. To learn more about component styling, refer ",(0,t.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/wiki/Component-Styling",children:"this"}),"."]}),"\n",(0,t.jsx)(n.li,{children:"For each segment in the chart, the color prop is optional. If the color prop is not defined, a color is selected from the qualitative palette using the getNextColor utility. However, if the color prop is defined, the getColorFromToken utility is used to determine the appropriate CSS color. If the value of the color prop is a theme-specific color token from the DataVizPalette, the utility will return the corresponding CSS color. Otherwise, if the color prop is already a valid CSS color, it will be returned as is."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"debugging",children:"Debugging"}),"\n",(0,t.jsx)(n.h2,{id:"error-scenarios",children:"Error scenarios"}),"\n",(0,t.jsx)(n.h2,{id:"localization-aspects",children:"Localization aspects"}),"\n",(0,t.jsx)(n.p,{children:"Currently, the chart supports localization only for the callout content."}),"\n",(0,t.jsx)(n.h2,{id:"some-notable-prs-and-their-brief-description",children:"Some notable PRs and their brief description"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/pull/27170",children:"Add gauge chart by krkshitij \xb7 Pull Request #27170 \xb7 microsoft/fluentui (github.com)"})}),"\n",(0,t.jsx)(n.h2,{id:"future-improvements",children:"Future improvements"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Add min width and height"}),"\n",(0,t.jsx)(n.li,{children:"Show message when chart is empty"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"rendering-details",children:"Rendering details"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The calculation of margins for the Gauge chart takes into account the presence of the chart title, sublabel, and limits (min and max values) to ensure that they do not overlap with the segments. Additionally, there is an extra margin of 16px around the gauge, referred to as GAUGE_MARGIN."}),"\n",(0,t.jsx)(n.li,{children:"Assuming that the legends do not wrap, the legends container is considered to have a fixed height of 24px. This helps calculate the available height for the element."}),"\n",(0,t.jsx)(n.li,{children:"The outer radius of the gauge is calculated based on the width and height props. If these props are not provided, the viewable width and height of the root div when the component mounts are used instead."}),"\n",(0,t.jsx)(n.li,{children:"According to the design doc, the font size of the chart value and the arc width vary depending on the size of the gauge chart. We cannot use CSS media queries in this case because the styles would be conditionally applied based on browser and operating system parameters. Instead, we use the BREAKPOINTS constant to determine the appropriate inner radius of the gauge and the font size of the chart value."}),"\n",(0,t.jsx)(n.li,{children:"If the difference between the max and min values exceeds the total size of all segments, a placeholder segment is rendered with a value equal to the difference. However, if the difference is smaller, the maximum value is adjusted to the correct value."}),"\n",(0,t.jsx)(n.li,{children:"The sweep fraction is calculated using the chart value, min value, and adjusted max value to determine the rotation of the needle."}),"\n",(0,t.jsx)(n.li,{children:"The min and max values are formatted with SI prefixes, as mentioned in the design doc. This formatting ensures that the values do not exceed 6 characters, equivalent to a width of 36px, referred to as LABEL_WIDTH."}),"\n",(0,t.jsx)(n.li,{children:"By default, the focus outline for segments is rectangular in shape. So the default outline is removed, and a custom outline is shown or hidden based on focus and blur events by adjusting the stroke width."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"interactions",children:"Interactions"}),"\n",(0,t.jsx)(n.p,{children:"The chart is wrapped with a FocusZone component to allow focus on its interactive subcomponents. The following subcomponents are accessible using the keyboard:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Segments "})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"data-is-focusable"}),": True"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onFocus"}),": Shows a callout near the element containing the chart value and all segments, along with their respective ranges"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onBlur"}),": Hides the callout if it is visible"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Needle "})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"data-is-focusable"}),": True"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onFocus"}),": Shows a callout near the element containing the chart value and all segments, along with their respective ranges"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onBlur"}),": Hides the callout if it is visible"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Chart value "})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"data-is-focusable"}),": True if the text content overflows the specified width and height"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onFocus"}),": Shows a tooltip with the complete content"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onBlur"}),": Hides the tooltip if it is visible"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Legend "})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"data-is-focusable"}),": Depends on the allowFocusOnLegends prop, which is true by default"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onFocus"}),": Highlights the corresponding segment"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onBlur"}),":\tUnhighlights the corresponding segment"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Users can interact with the following subcomponents using the mouse:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Segments "})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseEnter"}),": Shows a callout near the element containing the chart value and all segments, along with their respective ranges"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseMove"}),": Shows the callout if it is not already visible"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Needle "})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseEnter"}),": Shows a callout near the element containing the chart value and all segments, along with their respective ranges"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseMove"}),": Shows the callout if it is not already visible"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Chart value"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:""}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseEnter"}),": Shows a callout near the element containing the chart value and all segments, along with their respective ranges"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseMove"}),": Shows the callout if it is not already visible"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:""}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseEnter"}),": Shows a tooltip with the complete content if the text content overflows the specified width and height"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseLeave"}),": Hides the tooltip if it is visible"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Sublabel "})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseEnter"}),": Shows a tooltip with the complete content if the text content overflows the specified width and height"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseLeave"}),": Hides the tooltip if it is visible"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Chart "})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseLeave"}),": Hides the callout if it is visible"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Legend "})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseOver"}),": Highlights the corresponding segment"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onMouseOut"}),": Unhighlights the corresponding segment"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"onClick"}),": Highlights the corresponding segment if the legend is not already selected, otherwise unhighlights it"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"known-issues",children:"Known issues"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:['The chart is assigned the role of presentation. The "presentation" role and its synonym "none" remove an element\'s implicit ARIA semantics from being exposed to the accessibility tree. For more details, see ',(0,t.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/presentation_role",children:"ARIA: presentation role - Accessibility | MDN"})]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"design-figma",children:"Design figma"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"https://www.figma.com/file/oNWKEgIOCSLElvMZPOVMCq/ARCHIVED-Fluent-Data-Viz-(WIP)?type=design&node-id=2415-274387&mode=design&t=jdEfxXd3aMNuyWuz-4",children:"Gauge chart \u2013 Figma"})}),"\n",(0,t.jsx)(n.h2,{id:"learnings",children:"Learnings"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The needle is expanded from all sides by half the stroke width to maintain consistent dimensions with the design doc. This is necessary because the stroke is always centered on the outline, with half on the inside and half on the outside."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"extensions",children:"Extensions"})]})}function d(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},6399:(e,n,s)=>{s.d(n,{Z:()=>t});const t=s.p+"assets/images/gaugechart-dev-design-35b9551ffa7dc491d20730e4a65e9c2c.png"},9485:(e,n,s)=>{s.d(n,{Z:()=>t});const t=s.p+"assets/images/gaugechart-test-coverage-eb67779e6e7ab65f6e1aebce72af193d.png"},1151:(e,n,s)=>{s.d(n,{Z:()=>l,a:()=>a});var t=s(7294);const i={},r=t.createContext(i);function a(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/918c9c28.442e3710.js b/assets/js/918c9c28.442e3710.js
deleted file mode 100644
index cd8903b4c0..0000000000
--- a/assets/js/918c9c28.442e3710.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[3469],{7270:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>a,toc:()=>c});var i=t(5893),s=t(1151);const r={},o=void 0,a={id:"Detailed Implementation Steps",title:"Detailed Implementation Steps",description:"If you are planning to contribute a major chart, follow the below steps to align the component with fluent charting design, principles, style and standards.",source:"@site/../../docs/Detailed Implementation Steps.md",sourceDirName:".",slug:"/Detailed Implementation Steps",permalink:"/fluentui-charting-contrib/docs/Detailed Implementation Steps",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Technical details",permalink:"/fluentui-charting-contrib/docs/Technical Details"},next:{title:"Contributor guide: Area Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/AreaChart"}},l={},c=[];function h(e){const n={a:"a",em:"em",li:"li",ol:"ol",p:"p",strong:"strong",...(0,s.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"If you are planning to contribute a major chart, follow the below steps to align the component with fluent charting design, principles, style and standards."}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Step 1:"}),"\n",(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.em,{children:"Background research."})}),"\nIs there any existing work that has already happened (either on the dev side or on the design side) or in the backlog. Any planned feature can be found in our roadmap ",(0,i.jsx)(n.a,{href:"https://github.com/orgs/microsoft/projects/792/views/1",children:"here"})," along with high level timelines and current status. Also look for any discussions about the feature in our discord channel.\nIf the ask is net new, setup sometime with the charting team. This will help determine the next steps to proceed with designing the control as per fluent charting framework."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Step 2:"}),"\n",(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.em,{children:"Visual design."})}),"\nThe design figma should cover specification about the following aspects before the control can be implemented."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Anatomy:"})," Describe the components of the chart and how each of them will look."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Possible sizes:"})," The control can be supported in different sizes like S, M, L XL."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Variations:"})," The control can have multiple variations for different use cases."]}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.strong,{children:"Handling large dataset or data labels."})}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Theming:"})," How will the chart look in light mode and dark mode. What about high contrast mode."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Colors:"})," What is the supported color palette by this chart. It should either use the default ",(0,i.jsx)(n.a,{href:"/fluentui-charting-contrib/docs/colors",children:"color palette"})," of react charting or a subset of it."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Interactive behavior:"})," Define how the user can interact with points and other visuals in the chart. For eg: hover card when a user hovers over a chart area, selecting particular legend."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Accessibility:"})," The charting library is currently MAS C compliant. The chart should meet ",(0,i.jsx)(n.a,{href:"/fluentui-charting-contrib/docs/Accessibility",children:"accessibility"})," standards to ensure this grade."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"RTL support:"})," The library supports ",(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Right-to-left_script",children:"RTL"})," scripts. Do we need any special design to support them."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Refer to ",(0,i.jsx)(n.a,{href:"https://www.figma.com/file/oNWKEgIOCSLElvMZPOVMCq/Fluent-Data-Viz-(WIP)?node-id=1776-205538&t=77LXR8DHndlgs3ap-0",children:"this"})," figma to see an example."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Step 3:"}),"\n",(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.em,{children:"Dev Design."})}),"\nOnce the visual design is finalized, prepare a dev design document. You can look at design docs of other charts for reference. [",(0,i.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/blob/master/packages/react-charting/src/components/TreeChart/TreeChart.md",children:"Example"}),"]\nTry to include the following sections in the design document."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"External interfaces"}),"\n",(0,i.jsx)(n.li,{children:"Props"}),"\n",(0,i.jsx)(n.li,{children:"React lifecycle state management."}),"\n",(0,i.jsx)(n.li,{children:"Data structure to store and process the data."}),"\n",(0,i.jsx)(n.li,{children:"Handling large data sets."}),"\n",(0,i.jsx)(n.li,{children:"Rerendering and recomputations on user interactions."}),"\n",(0,i.jsx)(n.li,{children:"Reusable components."}),"\n",(0,i.jsx)(n.li,{children:"Unit testable and component testable pieces."}),"\n",(0,i.jsx)(n.li,{children:"Mapping geometrical logic to visual graph."}),"\n",(0,i.jsx)(n.li,{children:"Limitations."}),"\n",(0,i.jsx)(n.li,{children:"Alternative design considerations."}),"\n",(0,i.jsx)(n.li,{children:"Accessibility considerations"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"These design collaterals will be added to this contributor guide for future references."}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Step 4."}),"\n",(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.em,{children:"POC."})})," - This step will overlap with step 2. This will help understand and align with overall design of fluent charting library.\nThe charting team will be more than happy to participate in design discussions to iterate over step 2 and 3.\nOnce done get a formal review from the charting team and address any feedbacks."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Step 5:"}),"\n",(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.em,{children:"Implementation."})})]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Step 6:"}),"\n",(0,i.jsx)(n.em,{children:(0,i.jsx)(n.strong,{children:"Pilot with a customer as an unstable component."})}),"\nThe rollout starts by piloting with a partner assuming the component to have some bugs.\nThis phase includes fixing these bugs and correcting any external interfaces."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Step 7:"}),"\n",(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.em,{children:"Stable release."})}),"\nOnce the component has been released as stable, it can no longer have any breaking changes before the next major release of the library."]}),"\n",(0,i.jsx)(n.p,{children:"If the proposed changes are bugfixes, minor enhancements or extension then steps 1-4, 5 and 6 can be brief or skipped. But make sure to capture any relevant information in PR description or supporting documents."})]})}function d(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>o});var i=t(7294);const s={},r=i.createContext(s);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/918c9c28.a570135e.js b/assets/js/918c9c28.a570135e.js
new file mode 100644
index 0000000000..e7de952974
--- /dev/null
+++ b/assets/js/918c9c28.a570135e.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[3469],{7270:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>a,toc:()=>c});var i=t(5893),s=t(1151);const r={},o=void 0,a={id:"Detailed Implementation Steps",title:"Detailed Implementation Steps",description:"If you are planning to contribute a major chart, follow the below steps to align the component with fluent charting design, principles, style and standards.",source:"@site/../../docs/Detailed Implementation Steps.md",sourceDirName:".",slug:"/Detailed Implementation Steps",permalink:"/fluentui-charting-contrib/docs/Detailed Implementation Steps",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Technical details",permalink:"/fluentui-charting-contrib/docs/Technical Details"},next:{title:"Debugging",permalink:"/fluentui-charting-contrib/docs/Debugging"}},l={},c=[];function h(e){const n={a:"a",em:"em",li:"li",ol:"ol",p:"p",strong:"strong",...(0,s.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"If you are planning to contribute a major chart, follow the below steps to align the component with fluent charting design, principles, style and standards."}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Step 1:"}),"\n",(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.em,{children:"Background research."})}),"\nIs there any existing work that has already happened (either on the dev side or on the design side) or in the backlog. Any planned feature can be found in our roadmap ",(0,i.jsx)(n.a,{href:"https://github.com/orgs/microsoft/projects/792/views/1",children:"here"})," along with high level timelines and current status. Also look for any discussions about the feature in our discord channel.\nIf the ask is net new, setup sometime with the charting team. This will help determine the next steps to proceed with designing the control as per fluent charting framework."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Step 2:"}),"\n",(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.em,{children:"Visual design."})}),"\nThe design figma should cover specification about the following aspects before the control can be implemented."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Anatomy:"})," Describe the components of the chart and how each of them will look."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Possible sizes:"})," The control can be supported in different sizes like S, M, L XL."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Variations:"})," The control can have multiple variations for different use cases."]}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.strong,{children:"Handling large dataset or data labels."})}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Theming:"})," How will the chart look in light mode and dark mode. What about high contrast mode."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Colors:"})," What is the supported color palette by this chart. It should either use the default ",(0,i.jsx)(n.a,{href:"/fluentui-charting-contrib/docs/colors",children:"color palette"})," of react charting or a subset of it."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Interactive behavior:"})," Define how the user can interact with points and other visuals in the chart. For eg: hover card when a user hovers over a chart area, selecting particular legend."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Accessibility:"})," The charting library is currently MAS C compliant. The chart should meet ",(0,i.jsx)(n.a,{href:"/fluentui-charting-contrib/docs/Accessibility",children:"accessibility"})," standards to ensure this grade."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"RTL support:"})," The library supports ",(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Right-to-left_script",children:"RTL"})," scripts. Do we need any special design to support them."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Refer to ",(0,i.jsx)(n.a,{href:"https://www.figma.com/file/oNWKEgIOCSLElvMZPOVMCq/Fluent-Data-Viz-(WIP)?node-id=1776-205538&t=77LXR8DHndlgs3ap-0",children:"this"})," figma to see an example."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Step 3:"}),"\n",(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.em,{children:"Dev Design."})}),"\nOnce the visual design is finalized, prepare a dev design document. You can look at design docs of other charts for reference. [",(0,i.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/blob/master/packages/react-charting/src/components/TreeChart/TreeChart.md",children:"Example"}),"]\nTry to include the following sections in the design document."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"External interfaces"}),"\n",(0,i.jsx)(n.li,{children:"Props"}),"\n",(0,i.jsx)(n.li,{children:"React lifecycle state management."}),"\n",(0,i.jsx)(n.li,{children:"Data structure to store and process the data."}),"\n",(0,i.jsx)(n.li,{children:"Handling large data sets."}),"\n",(0,i.jsx)(n.li,{children:"Rerendering and recomputations on user interactions."}),"\n",(0,i.jsx)(n.li,{children:"Reusable components."}),"\n",(0,i.jsx)(n.li,{children:"Unit testable and component testable pieces."}),"\n",(0,i.jsx)(n.li,{children:"Mapping geometrical logic to visual graph."}),"\n",(0,i.jsx)(n.li,{children:"Limitations."}),"\n",(0,i.jsx)(n.li,{children:"Alternative design considerations."}),"\n",(0,i.jsx)(n.li,{children:"Accessibility considerations"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"These design collaterals will be added to this contributor guide for future references."}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Step 4."}),"\n",(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.em,{children:"POC."})})," - This step will overlap with step 2. This will help understand and align with overall design of fluent charting library.\nThe charting team will be more than happy to participate in design discussions to iterate over step 2 and 3.\nOnce done get a formal review from the charting team and address any feedbacks."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Step 5:"}),"\n",(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.em,{children:"Implementation."})})]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Step 6:"}),"\n",(0,i.jsx)(n.em,{children:(0,i.jsx)(n.strong,{children:"Pilot with a customer as an unstable component."})}),"\nThe rollout starts by piloting with a partner assuming the component to have some bugs.\nThis phase includes fixing these bugs and correcting any external interfaces."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Step 7:"}),"\n",(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.em,{children:"Stable release."})}),"\nOnce the component has been released as stable, it can no longer have any breaking changes before the next major release of the library."]}),"\n",(0,i.jsx)(n.p,{children:"If the proposed changes are bugfixes, minor enhancements or extension then steps 1-4, 5 and 6 can be brief or skipped. But make sure to capture any relevant information in PR description or supporting documents."})]})}function d(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>o});var i=t(7294);const s={},r=i.createContext(s);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/935f2afb.b83907d5.js b/assets/js/935f2afb.b83907d5.js
new file mode 100644
index 0000000000..c7adf3d9e7
--- /dev/null
+++ b/assets/js/935f2afb.b83907d5.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[53],{1109:t=>{t.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Overview","href":"/fluentui-charting-contrib/docs/Overview","docId":"Overview","unlisted":false},{"type":"category","label":"Changelog","items":[{"type":"link","label":"5.19","href":"/fluentui-charting-contrib/docs/changelogSplits/5.19","docId":"changelogSplits/5.19","unlisted":false},{"type":"link","label":"5.18","href":"/fluentui-charting-contrib/docs/changelogSplits/5.18","docId":"changelogSplits/5.18","unlisted":false},{"type":"link","label":"5.17","href":"/fluentui-charting-contrib/docs/changelogSplits/5.17","docId":"changelogSplits/5.17","unlisted":false},{"type":"link","label":"5.16","href":"/fluentui-charting-contrib/docs/changelogSplits/5.16","docId":"changelogSplits/5.16","unlisted":false},{"type":"link","label":"5.15","href":"/fluentui-charting-contrib/docs/changelogSplits/5.15","docId":"changelogSplits/5.15","unlisted":false},{"type":"link","label":"5.14","href":"/fluentui-charting-contrib/docs/changelogSplits/5.14","docId":"changelogSplits/5.14","unlisted":false},{"type":"link","label":"5.13","href":"/fluentui-charting-contrib/docs/changelogSplits/5.13","docId":"changelogSplits/5.13","unlisted":false},{"type":"link","label":"5.12","href":"/fluentui-charting-contrib/docs/changelogSplits/5.12","docId":"changelogSplits/5.12","unlisted":false},{"type":"link","label":"5.11","href":"/fluentui-charting-contrib/docs/changelogSplits/5.11","docId":"changelogSplits/5.11","unlisted":false},{"type":"link","label":"5.10","href":"/fluentui-charting-contrib/docs/changelogSplits/5.10","docId":"changelogSplits/5.10","unlisted":false},{"type":"link","label":"5.9","href":"/fluentui-charting-contrib/docs/changelogSplits/5.9","docId":"changelogSplits/5.9","unlisted":false},{"type":"link","label":"5.8","href":"/fluentui-charting-contrib/docs/changelogSplits/5.8","docId":"changelogSplits/5.8","unlisted":false},{"type":"link","label":"5.7","href":"/fluentui-charting-contrib/docs/changelogSplits/5.7","docId":"changelogSplits/5.7","unlisted":false},{"type":"link","label":"5.6","href":"/fluentui-charting-contrib/docs/changelogSplits/5.6","docId":"changelogSplits/5.6","unlisted":false},{"type":"link","label":"5.5","href":"/fluentui-charting-contrib/docs/changelogSplits/5.5","docId":"changelogSplits/5.5","unlisted":false},{"type":"link","label":"5.4","href":"/fluentui-charting-contrib/docs/changelogSplits/5.4","docId":"changelogSplits/5.4","unlisted":false},{"type":"link","label":"5.3","href":"/fluentui-charting-contrib/docs/changelogSplits/5.3","docId":"changelogSplits/5.3","unlisted":false},{"type":"link","label":"5.2","href":"/fluentui-charting-contrib/docs/changelogSplits/5.2","docId":"changelogSplits/5.2","unlisted":false},{"type":"link","label":"5.1","href":"/fluentui-charting-contrib/docs/changelogSplits/5.1","docId":"changelogSplits/5.1","unlisted":false},{"type":"link","label":"5.0","href":"/fluentui-charting-contrib/docs/changelogSplits/5.0","docId":"changelogSplits/5.0","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Start Developing","href":"/fluentui-charting-contrib/docs/Start Developing","docId":"Start Developing","unlisted":false},{"type":"category","label":"Contributor Guide","items":[{"type":"link","label":"Area Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/AreaChart","docId":"Charting-Concepts/AreaChart","unlisted":false},{"type":"link","label":"Donut Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/DonutChart","docId":"Charting-Concepts/DonutChart","unlisted":false},{"type":"link","label":"Gauge Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/GaugeChart","docId":"Charting-Concepts/GaugeChart","unlisted":false},{"type":"link","label":"Grouped Vertical Bar Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/GroupedVerticalBarChart","docId":"Charting-Concepts/GroupedVerticalBarChart","unlisted":false},{"type":"link","label":"Heatmap Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/HeatMapChart","docId":"Charting-Concepts/HeatMapChart","unlisted":false},{"type":"link","label":"Horizontal Bar Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/HorizontalBarChart","docId":"Charting-Concepts/HorizontalBarChart","unlisted":false},{"type":"link","label":"Line Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/LineChart","docId":"Charting-Concepts/LineChart","unlisted":false},{"type":"link","label":"Sankey Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/SankeyChart","docId":"Charting-Concepts/SankeyChart","unlisted":false},{"type":"link","label":"Sparkline Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/SparklineChart","docId":"Charting-Concepts/SparklineChart","unlisted":false},{"type":"link","label":"Stacked Bar Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/StackedBarChart","docId":"Charting-Concepts/StackedBarChart","unlisted":false},{"type":"link","label":"Vertical Bar Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/VerticalBarChart","docId":"Charting-Concepts/VerticalBarChart","unlisted":false},{"type":"link","label":"Vertical Stacked Bar Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/VerticalStackedBarChart","docId":"Charting-Concepts/VerticalStackedBarChart","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/fluentui-charting-contrib/docs/Contributor Guide"},{"type":"link","label":"Technical details","href":"/fluentui-charting-contrib/docs/Technical Details","docId":"Technical Details","unlisted":false},{"type":"link","label":"Detailed Implementation Steps","href":"/fluentui-charting-contrib/docs/Detailed Implementation Steps","docId":"Detailed Implementation Steps","unlisted":false},{"type":"link","label":"Debugging","href":"/fluentui-charting-contrib/docs/Debugging","docId":"Debugging","unlisted":false},{"type":"link","label":"Implementation Best Practices","href":"/fluentui-charting-contrib/docs/Implementation Best Practices","docId":"Implementation Best Practices","unlisted":false},{"type":"link","label":"Accessibility","href":"/fluentui-charting-contrib/docs/Accessibility","docId":"Accessibility","unlisted":false},{"type":"link","label":"Colors","href":"/fluentui-charting-contrib/docs/colors","docId":"colors","unlisted":false},{"type":"link","label":"Implementing 2:1 spacing","href":"/fluentui-charting-contrib/docs/implementing-2-to-1-spacing","docId":"implementing-2-to-1-spacing","unlisted":false},{"type":"link","label":"Creating Date Objects For Chart Data","href":"/fluentui-charting-contrib/docs/creating-date-objects-for-chart-data","docId":"creating-date-objects-for-chart-data","unlisted":false},{"type":"link","label":"Testing Strategy","href":"/fluentui-charting-contrib/docs/Testing Strategy","docId":"Testing Strategy","unlisted":false},{"type":"link","label":"Test Coverage Report","href":"/fluentui-charting-contrib/docs/TestCoverage","docId":"TestCoverage","unlisted":false},{"type":"category","label":"Test Plans","items":[{"type":"category","label":"AreaChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"ComponentTests","href":"/fluentui-charting-contrib/docs/Test Plans/AreaChart/ComponentTests","docId":"Test Plans/AreaChart/ComponentTests","unlisted":false}]},{"type":"category","label":"DonutChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"ComponentTests","href":"/fluentui-charting-contrib/docs/Test Plans/DonutChart/ComponentTests","docId":"Test Plans/DonutChart/ComponentTests","unlisted":false}]},{"type":"category","label":"GaugeChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Component testing - Gauge chart test plan","href":"/fluentui-charting-contrib/docs/Test Plans/GaugeChart/ComponentTests","docId":"Test Plans/GaugeChart/ComponentTests","unlisted":false}]},{"type":"category","label":"GroupedVerticalBarChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"ComponentTests","href":"/fluentui-charting-contrib/docs/Test Plans/GroupedVerticalBarChart/ComponentTests","docId":"Test Plans/GroupedVerticalBarChart/ComponentTests","unlisted":false}]},{"type":"category","label":"HeatMapChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Heatmap Chart - Component test plan","href":"/fluentui-charting-contrib/docs/Test Plans/HeatMapChart/ComponentTests","docId":"Test Plans/HeatMapChart/ComponentTests","unlisted":false}]},{"type":"category","label":"HorizontalBarChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"ComponentTests","href":"/fluentui-charting-contrib/docs/Test Plans/HorizontalBarChart/ComponentTests","docId":"Test Plans/HorizontalBarChart/ComponentTests","unlisted":false},{"type":"link","label":"UnitTests","href":"/fluentui-charting-contrib/docs/Test Plans/HorizontalBarChart/UnitTests","docId":"Test Plans/HorizontalBarChart/UnitTests","unlisted":false}]},{"type":"category","label":"HorizontalBarChartWithAxis","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"ComponentTests","href":"/fluentui-charting-contrib/docs/Test Plans/HorizontalBarChartWithAxis/ComponentTests","docId":"Test Plans/HorizontalBarChartWithAxis/ComponentTests","unlisted":false},{"type":"link","label":"UnitTests","href":"/fluentui-charting-contrib/docs/Test Plans/HorizontalBarChartWithAxis/UnitTests","docId":"Test Plans/HorizontalBarChartWithAxis/UnitTests","unlisted":false}]},{"type":"category","label":"LineChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"ComponentTests","href":"/fluentui-charting-contrib/docs/Test Plans/LineChart/ComponentTests","docId":"Test Plans/LineChart/ComponentTests","unlisted":false}]},{"type":"category","label":"MultiStackedBarChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"componentTests","href":"/fluentui-charting-contrib/docs/Test Plans/MultiStackedBarChart/componentTests","docId":"Test Plans/MultiStackedBarChart/componentTests","unlisted":false}]},{"type":"category","label":"SankeyChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"ComponentTests","href":"/fluentui-charting-contrib/docs/Test Plans/SankeyChart/ComponentTests","docId":"Test Plans/SankeyChart/ComponentTests","unlisted":false}]},{"type":"category","label":"StackedBarChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"ComponentTests","href":"/fluentui-charting-contrib/docs/Test Plans/StackedBarChart/ComponentTests","docId":"Test Plans/StackedBarChart/ComponentTests","unlisted":false}]},{"type":"link","label":"TestingGuide","href":"/fluentui-charting-contrib/docs/Test Plans/TestingGuide","docId":"Test Plans/TestingGuide","unlisted":false},{"type":"category","label":"Utilities","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Unit test plan for Donut Chart","href":"/fluentui-charting-contrib/docs/Test Plans/Utilities/UnitTests","docId":"Test Plans/Utilities/UnitTests","unlisted":false}]},{"type":"category","label":"VerticalBarChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"ComponentTests","href":"/fluentui-charting-contrib/docs/Test Plans/VerticalBarChart/ComponentTests","docId":"Test Plans/VerticalBarChart/ComponentTests","unlisted":false}]},{"type":"category","label":"VerticalStackedBarChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"ComponentTests","href":"/fluentui-charting-contrib/docs/Test Plans/VerticalStackedBarChart/ComponentTests","docId":"Test Plans/VerticalStackedBarChart/ComponentTests","unlisted":false}]}],"collapsed":true,"collapsible":true},{"type":"link","label":"Testing Unpublished Library Version","href":"/fluentui-charting-contrib/docs/Testing Unpublished Library Version","docId":"Testing Unpublished Library Version","unlisted":false},{"type":"link","label":"Bundle Size","href":"/fluentui-charting-contrib/docs/BundleSize","docId":"BundleSize","unlisted":false}]},"docs":{"Accessibility":{"id":"Accessibility","title":"Accessibility","description":"The react charting library is accessibility MAS C compliant.","sidebar":"tutorialSidebar"},"BundleSize":{"id":"BundleSize","title":"Bundle Size","description":"This table measures the maximum unpacked size of each chart control. This is measured by the monosize tool.","sidebar":"tutorialSidebar"},"CHANGELOG":{"id":"CHANGELOG","title":"Release Log","description":"This log was last generated on Wed, 10 Jan 2024 0750 GMT and should not be manually modified."},"changelogSplits/5.0":{"id":"changelogSplits/5.0","title":"5.0","description":"5.0.37","sidebar":"tutorialSidebar"},"changelogSplits/5.1":{"id":"changelogSplits/5.1","title":"5.1","description":"5.1.17","sidebar":"tutorialSidebar"},"changelogSplits/5.10":{"id":"changelogSplits/5.10","title":"5.10","description":"5.10.1","sidebar":"tutorialSidebar"},"changelogSplits/5.11":{"id":"changelogSplits/5.11","title":"5.11","description":"5.11.0","sidebar":"tutorialSidebar"},"changelogSplits/5.12":{"id":"changelogSplits/5.12","title":"5.12","description":"5.12.37","sidebar":"tutorialSidebar"},"changelogSplits/5.13":{"id":"changelogSplits/5.13","title":"5.13","description":"5.13.11","sidebar":"tutorialSidebar"},"changelogSplits/5.14":{"id":"changelogSplits/5.14","title":"5.14","description":"5.14.43","sidebar":"tutorialSidebar"},"changelogSplits/5.15":{"id":"changelogSplits/5.15","title":"5.15","description":"5.15.10","sidebar":"tutorialSidebar"},"changelogSplits/5.16":{"id":"changelogSplits/5.16","title":"5.16","description":"5.16.60","sidebar":"tutorialSidebar"},"changelogSplits/5.17":{"id":"changelogSplits/5.17","title":"5.17","description":"5.17.12","sidebar":"tutorialSidebar"},"changelogSplits/5.18":{"id":"changelogSplits/5.18","title":"5.18","description":"5.18.18","sidebar":"tutorialSidebar"},"changelogSplits/5.19":{"id":"changelogSplits/5.19","title":"5.19","description":"5.19.29","sidebar":"tutorialSidebar"},"changelogSplits/5.2":{"id":"changelogSplits/5.2","title":"5.2","description":"5.2.12","sidebar":"tutorialSidebar"},"changelogSplits/5.3":{"id":"changelogSplits/5.3","title":"5.3","description":"5.3.61","sidebar":"tutorialSidebar"},"changelogSplits/5.4":{"id":"changelogSplits/5.4","title":"5.4","description":"5.4.1","sidebar":"tutorialSidebar"},"changelogSplits/5.5":{"id":"changelogSplits/5.5","title":"5.5","description":"5.5.14","sidebar":"tutorialSidebar"},"changelogSplits/5.6":{"id":"changelogSplits/5.6","title":"5.6","description":"5.6.17","sidebar":"tutorialSidebar"},"changelogSplits/5.7":{"id":"changelogSplits/5.7","title":"5.7","description":"5.7.21","sidebar":"tutorialSidebar"},"changelogSplits/5.8":{"id":"changelogSplits/5.8","title":"5.8","description":"5.8.2","sidebar":"tutorialSidebar"},"changelogSplits/5.9":{"id":"changelogSplits/5.9","title":"5.9","description":"5.9.55","sidebar":"tutorialSidebar"},"Charting-Concepts/AreaChart":{"id":"Charting-Concepts/AreaChart","title":"Area Chart","description":"Areachartpic1.png","sidebar":"tutorialSidebar"},"Charting-Concepts/DonutChart":{"id":"Charting-Concepts/DonutChart","title":"Donut Chart","description":"DonutChart1.png","sidebar":"tutorialSidebar"},"Charting-Concepts/GaugeChart":{"id":"Charting-Concepts/GaugeChart","title":"Gauge Chart","description":"Gauge chart measures the progress of a metric against its target and its primary components are a speedometer and a needle. The speedometer usually consists of color-coded segments progressing value from left to right.","sidebar":"tutorialSidebar"},"Charting-Concepts/GroupedVerticalBarChart":{"id":"Charting-Concepts/GroupedVerticalBarChart","title":"Grouped Vertical Bar Chart","description":"GroupedVerticalBarChart1.png","sidebar":"tutorialSidebar"},"Charting-Concepts/HeatMapChart":{"id":"Charting-Concepts/HeatMapChart","title":"Heatmap Chart","description":"A heatmap chart is a type of data visualization that represents data values as colors in a grid of rectangles. Each cell\'s color intensity corresponds to the value it represents, making it easy to spot patterns and variations in the data.","sidebar":"tutorialSidebar"},"Charting-Concepts/HorizontalBarChart":{"id":"Charting-Concepts/HorizontalBarChart","title":"Horizontal Bar Chart","description":"A horizontal bar chart is a chart that presents categorical data with rectangular bars with lengths proportional to the values they represent. This type of chart is particularly useful when the intention is to show comparisons among different categories and the labels for those categories are long.","sidebar":"tutorialSidebar"},"Charting-Concepts/LineChart":{"id":"Charting-Concepts/LineChart","title":"Line Chart","description":"Line charts are a versatile type of graph used to visualize data trends over time. They are commonly used in various fields and industries for different purposes.","sidebar":"tutorialSidebar"},"Charting-Concepts/SankeyChart":{"id":"Charting-Concepts/SankeyChart","title":"Sankey Chart","description":"Sankey charts are a type of data visualization that are particularly useful for showing the flow of resources, energy, or information through a system. They are characterized by their flowing, interconnected arrows that represent the quantity or value of something as it moves from one stage or category to another.","sidebar":"tutorialSidebar"},"Charting-Concepts/SparklineChart":{"id":"Charting-Concepts/SparklineChart","title":"Sparkline Chart","description":"Sparkline1.png","sidebar":"tutorialSidebar"},"Charting-Concepts/StackedBarChart":{"id":"Charting-Concepts/StackedBarChart","title":"Stacked Bar Chart","description":"A stacked bar chart is a type of data visualization that represents data using rectangular bars with lengths proportional to the values they represent. In a stacked bar chart, each bar is divided into segments, and the segments represent different categories or components. The segments are stacked next to each other to show the total value of each bar.","sidebar":"tutorialSidebar"},"Charting-Concepts/VerticalBarChart":{"id":"Charting-Concepts/VerticalBarChart","title":"Vertical Bar Chart","description":"VerticalBarChart1.png","sidebar":"tutorialSidebar"},"Charting-Concepts/VerticalStackedBarChart":{"id":"Charting-Concepts/VerticalStackedBarChart","title":"Vertical Stacked Bar Chart","description":"VerticalStackedBarChart1.png","sidebar":"tutorialSidebar"},"colors":{"id":"colors","title":"Colors","description":"We provide the following 3 ways to specify colors for the data series.","sidebar":"tutorialSidebar"},"Contributor Guide":{"id":"Contributor Guide","title":"Contributor Guide","description":"Fluent charting library is a collection of individual charts like LineChart, AreaChart, Horizontal bar chart, vertical bar chart.","sidebar":"tutorialSidebar"},"creating-date-objects-for-chart-data":{"id":"creating-date-objects-for-chart-data","title":"Creating Date Objects For Chart Data","description":"There are many ways to format a date as a string. The JavaScript specification only specifies one format to be universally supported","sidebar":"tutorialSidebar"},"Debugging":{"id":"Debugging","title":"Debugging","description":"The chart components can be debugged using few techniques.","sidebar":"tutorialSidebar"},"Detailed Implementation Steps":{"id":"Detailed Implementation Steps","title":"Detailed Implementation Steps","description":"If you are planning to contribute a major chart, follow the below steps to align the component with fluent charting design, principles, style and standards.","sidebar":"tutorialSidebar"},"Implementation Best Practices":{"id":"Implementation Best Practices","title":"Implementation Best Practices","description":"Component Props","sidebar":"tutorialSidebar"},"implementing-2-to-1-spacing":{"id":"implementing-2-to-1-spacing","title":"Implementing 2:1 spacing","description":"Discrete Axis","sidebar":"tutorialSidebar"},"Overview":{"id":"Overview","title":"Overview","description":"Fluent UI React (formerly Office UI Fabric React) charts is a set of modern, accessible, interactive, lightweight and highly customizable visualization library representing the Microsoft design system. The charts are used across 100+ projects inside Microsoft including Microsoft 365 and Azure.","sidebar":"tutorialSidebar"},"Start Developing":{"id":"Start Developing","title":"Start Developing","description":"This page will help you get familiar with the react charting controls, how the code and documents are organized.","sidebar":"tutorialSidebar"},"Technical Details":{"id":"Technical Details","title":"Technical details","description":"Overview","sidebar":"tutorialSidebar"},"Test Plans/AreaChart/ComponentTests":{"id":"Test Plans/AreaChart/ComponentTests","title":"ComponentTests","description":"Area Chart \u2013 Component test plan","sidebar":"tutorialSidebar"},"Test Plans/DonutChart/ComponentTests":{"id":"Test Plans/DonutChart/ComponentTests","title":"ComponentTests","description":"Alt text","sidebar":"tutorialSidebar"},"Test Plans/GaugeChart/ComponentTests":{"id":"Test Plans/GaugeChart/ComponentTests","title":"Component testing - Gauge chart test plan","description":"Snapshot testing","sidebar":"tutorialSidebar"},"Test Plans/GroupedVerticalBarChart/ComponentTests":{"id":"Test Plans/GroupedVerticalBarChart/ComponentTests","title":"ComponentTests","description":"Grouped Vertical Bar Chart \u2013 Component test plan","sidebar":"tutorialSidebar"},"Test Plans/HeatMapChart/ComponentTests":{"id":"Test Plans/HeatMapChart/ComponentTests","title":"Heatmap Chart - Component test plan","description":"Snapshot tests","sidebar":"tutorialSidebar"},"Test Plans/HorizontalBarChart/ComponentTests":{"id":"Test Plans/HorizontalBarChart/ComponentTests","title":"ComponentTests","description":"Horizontal Bar Chart \u2013 Component test plan","sidebar":"tutorialSidebar"},"Test Plans/HorizontalBarChart/UnitTests":{"id":"Test Plans/HorizontalBarChart/UnitTests","title":"UnitTests","description":"Unit Test Plan - Horizontal Bar Chart","sidebar":"tutorialSidebar"},"Test Plans/HorizontalBarChartWithAxis/ComponentTests":{"id":"Test Plans/HorizontalBarChartWithAxis/ComponentTests","title":"ComponentTests","description":"Horizontal Bar Chart With Axis \u2013 Component test plan","sidebar":"tutorialSidebar"},"Test Plans/HorizontalBarChartWithAxis/UnitTests":{"id":"Test Plans/HorizontalBarChartWithAxis/UnitTests","title":"UnitTests","description":"Unit Test Plan \u2013 Horizontal Bar Chart with axiss","sidebar":"tutorialSidebar"},"Test Plans/LineChart/ComponentTests":{"id":"Test Plans/LineChart/ComponentTests","title":"ComponentTests","description":"Line Chart \u2013 Component test plan","sidebar":"tutorialSidebar"},"Test Plans/MultiStackedBarChart/componentTests":{"id":"Test Plans/MultiStackedBarChart/componentTests","title":"componentTests","description":"Multi stacked bar Chart \u2013 Component test plan","sidebar":"tutorialSidebar"},"Test Plans/SankeyChart/ComponentTests":{"id":"Test Plans/SankeyChart/ComponentTests","title":"ComponentTests","description":"Sankey Chart \u2013 Component test plan","sidebar":"tutorialSidebar"},"Test Plans/StackedBarChart/ComponentTests":{"id":"Test Plans/StackedBarChart/ComponentTests","title":"ComponentTests","description":"Stacked Bar Chart \u2013 Component test plan","sidebar":"tutorialSidebar"},"Test Plans/TestingGuide":{"id":"Test Plans/TestingGuide","title":"TestingGuide","description":"This document highlights few common testing practices for any new tests that are being added to the charting library.","sidebar":"tutorialSidebar"},"Test Plans/Utilities/UnitTests":{"id":"Test Plans/Utilities/UnitTests","title":"Unit test plan for Donut Chart","description":"This test plan contains the list of unit testable functions which are used as a part of the Donut Chart component.","sidebar":"tutorialSidebar"},"Test Plans/VerticalBarChart/ComponentTests":{"id":"Test Plans/VerticalBarChart/ComponentTests","title":"ComponentTests","description":"Vertical Bar Chart \u2013 Component test plan","sidebar":"tutorialSidebar"},"Test Plans/VerticalStackedBarChart/ComponentTests":{"id":"Test Plans/VerticalStackedBarChart/ComponentTests","title":"ComponentTests","description":"Vertical Stacked Bar Chart \u2013 Component test plan","sidebar":"tutorialSidebar"},"TestCoverage":{"id":"TestCoverage","title":"Test Coverage Report","description":"Latest test coverage reports across OS.","sidebar":"tutorialSidebar"},"Testing Strategy":{"id":"Testing Strategy","title":"Testing Strategy","description":"Details","sidebar":"tutorialSidebar"},"Testing Unpublished Library Version":{"id":"Testing Unpublished Library Version","title":"Testing Unpublished Library Version","description":"You may want to test changes made to the library in an app locally. This becomes useful to validate a fix or root cause an issue occuring only in a specific app or context.","sidebar":"tutorialSidebar"}}}')}}]);
\ No newline at end of file
diff --git a/assets/js/935f2afb.d81b4fa2.js b/assets/js/935f2afb.d81b4fa2.js
deleted file mode 100644
index 96c6fc11e5..0000000000
--- a/assets/js/935f2afb.d81b4fa2.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[53],{1109:t=>{t.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Overview","href":"/fluentui-charting-contrib/docs/Overview","docId":"Overview","unlisted":false},{"type":"category","label":"Changelog","items":[{"type":"link","label":"5.19","href":"/fluentui-charting-contrib/docs/changelogSplits/5.19","docId":"changelogSplits/5.19","unlisted":false},{"type":"link","label":"5.18","href":"/fluentui-charting-contrib/docs/changelogSplits/5.18","docId":"changelogSplits/5.18","unlisted":false},{"type":"link","label":"5.17","href":"/fluentui-charting-contrib/docs/changelogSplits/5.17","docId":"changelogSplits/5.17","unlisted":false},{"type":"link","label":"5.16","href":"/fluentui-charting-contrib/docs/changelogSplits/5.16","docId":"changelogSplits/5.16","unlisted":false},{"type":"link","label":"5.15","href":"/fluentui-charting-contrib/docs/changelogSplits/5.15","docId":"changelogSplits/5.15","unlisted":false},{"type":"link","label":"5.14","href":"/fluentui-charting-contrib/docs/changelogSplits/5.14","docId":"changelogSplits/5.14","unlisted":false},{"type":"link","label":"5.13","href":"/fluentui-charting-contrib/docs/changelogSplits/5.13","docId":"changelogSplits/5.13","unlisted":false},{"type":"link","label":"5.12","href":"/fluentui-charting-contrib/docs/changelogSplits/5.12","docId":"changelogSplits/5.12","unlisted":false},{"type":"link","label":"5.11","href":"/fluentui-charting-contrib/docs/changelogSplits/5.11","docId":"changelogSplits/5.11","unlisted":false},{"type":"link","label":"5.10","href":"/fluentui-charting-contrib/docs/changelogSplits/5.10","docId":"changelogSplits/5.10","unlisted":false},{"type":"link","label":"5.9","href":"/fluentui-charting-contrib/docs/changelogSplits/5.9","docId":"changelogSplits/5.9","unlisted":false},{"type":"link","label":"5.8","href":"/fluentui-charting-contrib/docs/changelogSplits/5.8","docId":"changelogSplits/5.8","unlisted":false},{"type":"link","label":"5.7","href":"/fluentui-charting-contrib/docs/changelogSplits/5.7","docId":"changelogSplits/5.7","unlisted":false},{"type":"link","label":"5.6","href":"/fluentui-charting-contrib/docs/changelogSplits/5.6","docId":"changelogSplits/5.6","unlisted":false},{"type":"link","label":"5.5","href":"/fluentui-charting-contrib/docs/changelogSplits/5.5","docId":"changelogSplits/5.5","unlisted":false},{"type":"link","label":"5.4","href":"/fluentui-charting-contrib/docs/changelogSplits/5.4","docId":"changelogSplits/5.4","unlisted":false},{"type":"link","label":"5.3","href":"/fluentui-charting-contrib/docs/changelogSplits/5.3","docId":"changelogSplits/5.3","unlisted":false},{"type":"link","label":"5.2","href":"/fluentui-charting-contrib/docs/changelogSplits/5.2","docId":"changelogSplits/5.2","unlisted":false},{"type":"link","label":"5.1","href":"/fluentui-charting-contrib/docs/changelogSplits/5.1","docId":"changelogSplits/5.1","unlisted":false},{"type":"link","label":"5.0","href":"/fluentui-charting-contrib/docs/changelogSplits/5.0","docId":"changelogSplits/5.0","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Start Developing","href":"/fluentui-charting-contrib/docs/Start Developing","docId":"Start Developing","unlisted":false},{"type":"link","label":"Contributor Guide","href":"/fluentui-charting-contrib/docs/Contributor Guide","docId":"Contributor Guide","unlisted":false},{"type":"link","label":"Technical details","href":"/fluentui-charting-contrib/docs/Technical Details","docId":"Technical Details","unlisted":false},{"type":"link","label":"Detailed Implementation Steps","href":"/fluentui-charting-contrib/docs/Detailed Implementation Steps","docId":"Detailed Implementation Steps","unlisted":false},{"type":"category","label":"Charting Concepts","items":[{"type":"link","label":"Contributor guide: Area Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/AreaChart","docId":"Charting-Concepts/AreaChart","unlisted":false},{"type":"link","label":"Contributor guide: Donut Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/DonutChart","docId":"Charting-Concepts/DonutChart","unlisted":false},{"type":"link","label":"Contributor guide: Gauge Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/GaugeChart","docId":"Charting-Concepts/GaugeChart","unlisted":false},{"type":"link","label":"Contributor guide: Grouped Vertical Bar Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/GroupedVerticalBarChart","docId":"Charting-Concepts/GroupedVerticalBarChart","unlisted":false},{"type":"link","label":"Contributor guide: Heatmap Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/HeatMapChart","docId":"Charting-Concepts/HeatMapChart","unlisted":false},{"type":"link","label":"Contributor guide: Horizontal Bar Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/HorizontalBarChart","docId":"Charting-Concepts/HorizontalBarChart","unlisted":false},{"type":"link","label":"Contributor guide: Line Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/LineChart","docId":"Charting-Concepts/LineChart","unlisted":false},{"type":"link","label":"Contributor Guide: Sankey Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/SankeyChart","docId":"Charting-Concepts/SankeyChart","unlisted":false},{"type":"link","label":"Contributor guide: Sparkline Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/SparklineChart","docId":"Charting-Concepts/SparklineChart","unlisted":false},{"type":"link","label":"Contributor guide: Stacked Bar Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/StackedBarChart","docId":"Charting-Concepts/StackedBarChart","unlisted":false},{"type":"link","label":"Contributor guide: Vertical Bar Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/VerticalBarChart","docId":"Charting-Concepts/VerticalBarChart","unlisted":false},{"type":"link","label":"Contributor guide: Vertical Stacked Bar Chart","href":"/fluentui-charting-contrib/docs/Charting-Concepts/VerticalStackedBarChart","docId":"Charting-Concepts/VerticalStackedBarChart","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Debugging","href":"/fluentui-charting-contrib/docs/Debugging","docId":"Debugging","unlisted":false},{"type":"link","label":"Implementation Best Practices","href":"/fluentui-charting-contrib/docs/Implementation Best Practices","docId":"Implementation Best Practices","unlisted":false},{"type":"link","label":"Accessibility","href":"/fluentui-charting-contrib/docs/Accessibility","docId":"Accessibility","unlisted":false},{"type":"link","label":"Colors","href":"/fluentui-charting-contrib/docs/colors","docId":"colors","unlisted":false},{"type":"link","label":"Implementing 2:1 spacing","href":"/fluentui-charting-contrib/docs/implementing-2-to-1-spacing","docId":"implementing-2-to-1-spacing","unlisted":false},{"type":"link","label":"Creating Date Objects For Chart Data","href":"/fluentui-charting-contrib/docs/creating-date-objects-for-chart-data","docId":"creating-date-objects-for-chart-data","unlisted":false},{"type":"link","label":"Testing Strategy","href":"/fluentui-charting-contrib/docs/Testing Strategy","docId":"Testing Strategy","unlisted":false},{"type":"link","label":"Test Coverage Report","href":"/fluentui-charting-contrib/docs/TestCoverage","docId":"TestCoverage","unlisted":false},{"type":"category","label":"Test Plans","items":[{"type":"category","label":"AreaChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"ComponentTests","href":"/fluentui-charting-contrib/docs/Test Plans/AreaChart/ComponentTests","docId":"Test Plans/AreaChart/ComponentTests","unlisted":false}]},{"type":"category","label":"DonutChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"ComponentTests","href":"/fluentui-charting-contrib/docs/Test Plans/DonutChart/ComponentTests","docId":"Test Plans/DonutChart/ComponentTests","unlisted":false}]},{"type":"category","label":"GaugeChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Component testing - Gauge chart test plan","href":"/fluentui-charting-contrib/docs/Test Plans/GaugeChart/ComponentTests","docId":"Test Plans/GaugeChart/ComponentTests","unlisted":false}]},{"type":"category","label":"GroupedVerticalBarChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"ComponentTests","href":"/fluentui-charting-contrib/docs/Test Plans/GroupedVerticalBarChart/ComponentTests","docId":"Test Plans/GroupedVerticalBarChart/ComponentTests","unlisted":false}]},{"type":"category","label":"HeatMapChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Heatmap Chart - Component test plan","href":"/fluentui-charting-contrib/docs/Test Plans/HeatMapChart/ComponentTests","docId":"Test Plans/HeatMapChart/ComponentTests","unlisted":false}]},{"type":"category","label":"HorizontalBarChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"ComponentTests","href":"/fluentui-charting-contrib/docs/Test Plans/HorizontalBarChart/ComponentTests","docId":"Test Plans/HorizontalBarChart/ComponentTests","unlisted":false},{"type":"link","label":"UnitTests","href":"/fluentui-charting-contrib/docs/Test Plans/HorizontalBarChart/UnitTests","docId":"Test Plans/HorizontalBarChart/UnitTests","unlisted":false}]},{"type":"category","label":"HorizontalBarChartWithAxis","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"ComponentTests","href":"/fluentui-charting-contrib/docs/Test Plans/HorizontalBarChartWithAxis/ComponentTests","docId":"Test Plans/HorizontalBarChartWithAxis/ComponentTests","unlisted":false},{"type":"link","label":"UnitTests","href":"/fluentui-charting-contrib/docs/Test Plans/HorizontalBarChartWithAxis/UnitTests","docId":"Test Plans/HorizontalBarChartWithAxis/UnitTests","unlisted":false}]},{"type":"category","label":"LineChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"ComponentTests","href":"/fluentui-charting-contrib/docs/Test Plans/LineChart/ComponentTests","docId":"Test Plans/LineChart/ComponentTests","unlisted":false}]},{"type":"category","label":"MultiStackedBarChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"componentTests","href":"/fluentui-charting-contrib/docs/Test Plans/MultiStackedBarChart/componentTests","docId":"Test Plans/MultiStackedBarChart/componentTests","unlisted":false}]},{"type":"category","label":"SankeyChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"ComponentTests","href":"/fluentui-charting-contrib/docs/Test Plans/SankeyChart/ComponentTests","docId":"Test Plans/SankeyChart/ComponentTests","unlisted":false}]},{"type":"category","label":"StackedBarChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"ComponentTests","href":"/fluentui-charting-contrib/docs/Test Plans/StackedBarChart/ComponentTests","docId":"Test Plans/StackedBarChart/ComponentTests","unlisted":false}]},{"type":"link","label":"TestingGuide","href":"/fluentui-charting-contrib/docs/Test Plans/TestingGuide","docId":"Test Plans/TestingGuide","unlisted":false},{"type":"category","label":"Utilities","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Unit test plan for Donut Chart","href":"/fluentui-charting-contrib/docs/Test Plans/Utilities/UnitTests","docId":"Test Plans/Utilities/UnitTests","unlisted":false}]},{"type":"category","label":"VerticalBarChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"ComponentTests","href":"/fluentui-charting-contrib/docs/Test Plans/VerticalBarChart/ComponentTests","docId":"Test Plans/VerticalBarChart/ComponentTests","unlisted":false}]},{"type":"category","label":"VerticalStackedBarChart","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"ComponentTests","href":"/fluentui-charting-contrib/docs/Test Plans/VerticalStackedBarChart/ComponentTests","docId":"Test Plans/VerticalStackedBarChart/ComponentTests","unlisted":false}]}],"collapsed":true,"collapsible":true},{"type":"link","label":"Testing Unpublished Library Version","href":"/fluentui-charting-contrib/docs/Testing Unpublished Library Version","docId":"Testing Unpublished Library Version","unlisted":false},{"type":"link","label":"Bundle Size","href":"/fluentui-charting-contrib/docs/BundleSize","docId":"BundleSize","unlisted":false}]},"docs":{"Accessibility":{"id":"Accessibility","title":"Accessibility","description":"The react charting library is accessibility MAS C compliant.","sidebar":"tutorialSidebar"},"BundleSize":{"id":"BundleSize","title":"Bundle Size","description":"This table measures the maximum unpacked size of each chart control. This is measured by the monosize tool.","sidebar":"tutorialSidebar"},"CHANGELOG":{"id":"CHANGELOG","title":"Release Log","description":"This log was last generated on Wed, 10 Jan 2024 0750 GMT and should not be manually modified."},"changelogSplits/5.0":{"id":"changelogSplits/5.0","title":"5.0","description":"5.0.37","sidebar":"tutorialSidebar"},"changelogSplits/5.1":{"id":"changelogSplits/5.1","title":"5.1","description":"5.1.17","sidebar":"tutorialSidebar"},"changelogSplits/5.10":{"id":"changelogSplits/5.10","title":"5.10","description":"5.10.1","sidebar":"tutorialSidebar"},"changelogSplits/5.11":{"id":"changelogSplits/5.11","title":"5.11","description":"5.11.0","sidebar":"tutorialSidebar"},"changelogSplits/5.12":{"id":"changelogSplits/5.12","title":"5.12","description":"5.12.37","sidebar":"tutorialSidebar"},"changelogSplits/5.13":{"id":"changelogSplits/5.13","title":"5.13","description":"5.13.11","sidebar":"tutorialSidebar"},"changelogSplits/5.14":{"id":"changelogSplits/5.14","title":"5.14","description":"5.14.43","sidebar":"tutorialSidebar"},"changelogSplits/5.15":{"id":"changelogSplits/5.15","title":"5.15","description":"5.15.10","sidebar":"tutorialSidebar"},"changelogSplits/5.16":{"id":"changelogSplits/5.16","title":"5.16","description":"5.16.60","sidebar":"tutorialSidebar"},"changelogSplits/5.17":{"id":"changelogSplits/5.17","title":"5.17","description":"5.17.12","sidebar":"tutorialSidebar"},"changelogSplits/5.18":{"id":"changelogSplits/5.18","title":"5.18","description":"5.18.18","sidebar":"tutorialSidebar"},"changelogSplits/5.19":{"id":"changelogSplits/5.19","title":"5.19","description":"5.19.29","sidebar":"tutorialSidebar"},"changelogSplits/5.2":{"id":"changelogSplits/5.2","title":"5.2","description":"5.2.12","sidebar":"tutorialSidebar"},"changelogSplits/5.3":{"id":"changelogSplits/5.3","title":"5.3","description":"5.3.61","sidebar":"tutorialSidebar"},"changelogSplits/5.4":{"id":"changelogSplits/5.4","title":"5.4","description":"5.4.1","sidebar":"tutorialSidebar"},"changelogSplits/5.5":{"id":"changelogSplits/5.5","title":"5.5","description":"5.5.14","sidebar":"tutorialSidebar"},"changelogSplits/5.6":{"id":"changelogSplits/5.6","title":"5.6","description":"5.6.17","sidebar":"tutorialSidebar"},"changelogSplits/5.7":{"id":"changelogSplits/5.7","title":"5.7","description":"5.7.21","sidebar":"tutorialSidebar"},"changelogSplits/5.8":{"id":"changelogSplits/5.8","title":"5.8","description":"5.8.2","sidebar":"tutorialSidebar"},"changelogSplits/5.9":{"id":"changelogSplits/5.9","title":"5.9","description":"5.9.55","sidebar":"tutorialSidebar"},"Charting-Concepts/AreaChart":{"id":"Charting-Concepts/AreaChart","title":"Contributor guide: Area Chart","description":"Areachartpic1.png","sidebar":"tutorialSidebar"},"Charting-Concepts/DonutChart":{"id":"Charting-Concepts/DonutChart","title":"Contributor guide: Donut Chart","description":"DonutChart1.png","sidebar":"tutorialSidebar"},"Charting-Concepts/GaugeChart":{"id":"Charting-Concepts/GaugeChart","title":"Contributor guide: Gauge Chart","description":"Gauge chart measures the progress of a metric against its target and its primary components are a speedometer and a needle. The speedometer usually consists of color-coded segments progressing value from left to right.","sidebar":"tutorialSidebar"},"Charting-Concepts/GroupedVerticalBarChart":{"id":"Charting-Concepts/GroupedVerticalBarChart","title":"Contributor guide: Grouped Vertical Bar Chart","description":"GroupedVerticalBarChart1.png","sidebar":"tutorialSidebar"},"Charting-Concepts/HeatMapChart":{"id":"Charting-Concepts/HeatMapChart","title":"Contributor guide: Heatmap Chart","description":"A heatmap chart is a type of data visualization that represents data values as colors in a grid of rectangles. Each cell\'s color intensity corresponds to the value it represents, making it easy to spot patterns and variations in the data.","sidebar":"tutorialSidebar"},"Charting-Concepts/HorizontalBarChart":{"id":"Charting-Concepts/HorizontalBarChart","title":"Contributor guide: Horizontal Bar Chart","description":"A horizontal bar chart is a chart that presents categorical data with rectangular bars with lengths proportional to the values they represent. This type of chart is particularly useful when the intention is to show comparisons among different categories and the labels for those categories are long.","sidebar":"tutorialSidebar"},"Charting-Concepts/LineChart":{"id":"Charting-Concepts/LineChart","title":"Contributor guide: Line Chart","description":"Line charts are a versatile type of graph used to visualize data trends over time. They are commonly used in various fields and industries for different purposes.","sidebar":"tutorialSidebar"},"Charting-Concepts/SankeyChart":{"id":"Charting-Concepts/SankeyChart","title":"Contributor Guide: Sankey Chart","description":"Sankey charts are a type of data visualization that are particularly useful for showing the flow of resources, energy, or information through a system. They are characterized by their flowing, interconnected arrows that represent the quantity or value of something as it moves from one stage or category to another.","sidebar":"tutorialSidebar"},"Charting-Concepts/SparklineChart":{"id":"Charting-Concepts/SparklineChart","title":"Contributor guide: Sparkline Chart","description":"Sparkline1.png","sidebar":"tutorialSidebar"},"Charting-Concepts/StackedBarChart":{"id":"Charting-Concepts/StackedBarChart","title":"Contributor guide: Stacked Bar Chart","description":"A stacked bar chart is a type of data visualization that represents data using rectangular bars with lengths proportional to the values they represent. In a stacked bar chart, each bar is divided into segments, and the segments represent different categories or components. The segments are stacked next to each other to show the total value of each bar.","sidebar":"tutorialSidebar"},"Charting-Concepts/VerticalBarChart":{"id":"Charting-Concepts/VerticalBarChart","title":"Contributor guide: Vertical Bar Chart","description":"VerticalBarChart1.png","sidebar":"tutorialSidebar"},"Charting-Concepts/VerticalStackedBarChart":{"id":"Charting-Concepts/VerticalStackedBarChart","title":"Contributor guide: Vertical Stacked Bar Chart","description":"VerticalStackedBarChart1.png","sidebar":"tutorialSidebar"},"colors":{"id":"colors","title":"Colors","description":"We provide the following 3 ways to specify colors for the data series.","sidebar":"tutorialSidebar"},"Contributor Guide":{"id":"Contributor Guide","title":"Contributor Guide","description":"Fluent charting library is a collection of individual charts like LineChart, AreaChart, Horizontal bar chart, vertical bar chart.","sidebar":"tutorialSidebar"},"creating-date-objects-for-chart-data":{"id":"creating-date-objects-for-chart-data","title":"Creating Date Objects For Chart Data","description":"There are many ways to format a date as a string. The JavaScript specification only specifies one format to be universally supported","sidebar":"tutorialSidebar"},"Debugging":{"id":"Debugging","title":"Debugging","description":"The chart components can be debugged using few techniques.","sidebar":"tutorialSidebar"},"Detailed Implementation Steps":{"id":"Detailed Implementation Steps","title":"Detailed Implementation Steps","description":"If you are planning to contribute a major chart, follow the below steps to align the component with fluent charting design, principles, style and standards.","sidebar":"tutorialSidebar"},"Implementation Best Practices":{"id":"Implementation Best Practices","title":"Implementation Best Practices","description":"Component Props","sidebar":"tutorialSidebar"},"implementing-2-to-1-spacing":{"id":"implementing-2-to-1-spacing","title":"Implementing 2:1 spacing","description":"Discrete Axis","sidebar":"tutorialSidebar"},"Overview":{"id":"Overview","title":"Overview","description":"Fluent UI React (formerly Office UI Fabric React) charts is a set of modern, accessible, interactive, lightweight and highly customizable visualization library representing the Microsoft design system. The charts are used across 100+ projects inside Microsoft including Microsoft 365 and Azure.","sidebar":"tutorialSidebar"},"Start Developing":{"id":"Start Developing","title":"Start Developing","description":"This page will help you get familiar with the react charting controls, how the code and documents are organized.","sidebar":"tutorialSidebar"},"Technical Details":{"id":"Technical Details","title":"Technical details","description":"Overview","sidebar":"tutorialSidebar"},"Test Plans/AreaChart/ComponentTests":{"id":"Test Plans/AreaChart/ComponentTests","title":"ComponentTests","description":"Area Chart \u2013 Component test plan","sidebar":"tutorialSidebar"},"Test Plans/DonutChart/ComponentTests":{"id":"Test Plans/DonutChart/ComponentTests","title":"ComponentTests","description":"Alt text","sidebar":"tutorialSidebar"},"Test Plans/GaugeChart/ComponentTests":{"id":"Test Plans/GaugeChart/ComponentTests","title":"Component testing - Gauge chart test plan","description":"Snapshot testing","sidebar":"tutorialSidebar"},"Test Plans/GroupedVerticalBarChart/ComponentTests":{"id":"Test Plans/GroupedVerticalBarChart/ComponentTests","title":"ComponentTests","description":"Grouped Vertical Bar Chart \u2013 Component test plan","sidebar":"tutorialSidebar"},"Test Plans/HeatMapChart/ComponentTests":{"id":"Test Plans/HeatMapChart/ComponentTests","title":"Heatmap Chart - Component test plan","description":"Snapshot tests","sidebar":"tutorialSidebar"},"Test Plans/HorizontalBarChart/ComponentTests":{"id":"Test Plans/HorizontalBarChart/ComponentTests","title":"ComponentTests","description":"Horizontal Bar Chart \u2013 Component test plan","sidebar":"tutorialSidebar"},"Test Plans/HorizontalBarChart/UnitTests":{"id":"Test Plans/HorizontalBarChart/UnitTests","title":"UnitTests","description":"Unit Test Plan - Horizontal Bar Chart","sidebar":"tutorialSidebar"},"Test Plans/HorizontalBarChartWithAxis/ComponentTests":{"id":"Test Plans/HorizontalBarChartWithAxis/ComponentTests","title":"ComponentTests","description":"Horizontal Bar Chart With Axis \u2013 Component test plan","sidebar":"tutorialSidebar"},"Test Plans/HorizontalBarChartWithAxis/UnitTests":{"id":"Test Plans/HorizontalBarChartWithAxis/UnitTests","title":"UnitTests","description":"Unit Test Plan \u2013 Horizontal Bar Chart with axiss","sidebar":"tutorialSidebar"},"Test Plans/LineChart/ComponentTests":{"id":"Test Plans/LineChart/ComponentTests","title":"ComponentTests","description":"Line Chart \u2013 Component test plan","sidebar":"tutorialSidebar"},"Test Plans/MultiStackedBarChart/componentTests":{"id":"Test Plans/MultiStackedBarChart/componentTests","title":"componentTests","description":"Multi stacked bar Chart \u2013 Component test plan","sidebar":"tutorialSidebar"},"Test Plans/SankeyChart/ComponentTests":{"id":"Test Plans/SankeyChart/ComponentTests","title":"ComponentTests","description":"Sankey Chart \u2013 Component test plan","sidebar":"tutorialSidebar"},"Test Plans/StackedBarChart/ComponentTests":{"id":"Test Plans/StackedBarChart/ComponentTests","title":"ComponentTests","description":"Stacked Bar Chart \u2013 Component test plan","sidebar":"tutorialSidebar"},"Test Plans/TestingGuide":{"id":"Test Plans/TestingGuide","title":"TestingGuide","description":"This document highlights few common testing practices for any new tests that are being added to the charting library.","sidebar":"tutorialSidebar"},"Test Plans/Utilities/UnitTests":{"id":"Test Plans/Utilities/UnitTests","title":"Unit test plan for Donut Chart","description":"This test plan contains the list of unit testable functions which are used as a part of the Donut Chart component.","sidebar":"tutorialSidebar"},"Test Plans/VerticalBarChart/ComponentTests":{"id":"Test Plans/VerticalBarChart/ComponentTests","title":"ComponentTests","description":"Vertical Bar Chart \u2013 Component test plan","sidebar":"tutorialSidebar"},"Test Plans/VerticalStackedBarChart/ComponentTests":{"id":"Test Plans/VerticalStackedBarChart/ComponentTests","title":"ComponentTests","description":"Vertical Stacked Bar Chart \u2013 Component test plan","sidebar":"tutorialSidebar"},"TestCoverage":{"id":"TestCoverage","title":"Test Coverage Report","description":"Latest test coverage reports across OS.","sidebar":"tutorialSidebar"},"Testing Strategy":{"id":"Testing Strategy","title":"Testing Strategy","description":"Details","sidebar":"tutorialSidebar"},"Testing Unpublished Library Version":{"id":"Testing Unpublished Library Version","title":"Testing Unpublished Library Version","description":"You may want to test changes made to the library in an app locally. This becomes useful to validate a fix or root cause an issue occuring only in a specific app or context.","sidebar":"tutorialSidebar"}}}')}}]);
\ No newline at end of file
diff --git a/assets/js/b0e8dd6d.14bdb836.js b/assets/js/b0e8dd6d.14bdb836.js
deleted file mode 100644
index 6fccd5ddde..0000000000
--- a/assets/js/b0e8dd6d.14bdb836.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[8673],{6231:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var n=i(5893),s=i(1151);const r={},a=void 0,o={id:"Contributor Guide",title:"Contributor Guide",description:"Fluent charting library is a collection of individual charts like LineChart, AreaChart, Horizontal bar chart, vertical bar chart.",source:"@site/../../docs/Contributor Guide.md",sourceDirName:".",slug:"/Contributor Guide",permalink:"/fluentui-charting-contrib/docs/Contributor Guide",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Start Developing",permalink:"/fluentui-charting-contrib/docs/Start Developing"},next:{title:"Technical details",permalink:"/fluentui-charting-contrib/docs/Technical Details"}},c={},l=[];function d(e){const t={a:"a",em:"em",input:"input",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:"Fluent charting library is a collection of individual charts like LineChart, AreaChart, Horizontal bar chart, vertical bar chart.\nCharting components are built as production-ready, generalized, documented, and reusable components to be used in Microsoft products. This enables us and our partners to easily build great applications without spending a ton of time implementing the same controls over and over.\nEach component is designed to be RTL-friendly, keyboard accessible, screen reader-friendly, themable, and generalized. TypeScript definition files are also included, so if you use TypeScript (which isn't a requirement), you will get compiler validation and using an editor like VS Code, you'll get intellisense. Each component is exported as a named module that can be easily imported in your code, allowing your external bundler to create small bundles that include just what you need."}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Contribution process"}),"\nWe invite members of the community to actively participate in any way - code, documentation, design, publicity, moderation, analytics, explorations, dicussions and more."]}),"\n",(0,n.jsx)(t.p,{children:"Before proceeding into details, we would like to set some contractual guidelines with our contributor community."}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Commitments from the maintaining team"})," ",(0,n.jsx)(t.a,{href:"https://github.com/orgs/microsoft/teams/charting-team",children:"(charting-team)"})]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Responding to queries within a day."}),"\n",(0,n.jsx)(t.li,{children:"Responding to PRs within 2 business days."}),"\n",(0,n.jsx)(t.li,{children:"Publishing day to day design discussions, decisions taken, roadmaps, backlogs and current sprint board."}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Expectations from contributors"}),"\n",(0,n.jsx)(t.strong,{children:"For Issues:"}),"\nFollow the ",(0,n.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/issues/new/choose",children:"issue template"})," to report bugs and feature requests.\nFor internal product requests that can contain confidential information, report issues to our internal ADO ",(0,n.jsx)(t.a,{href:"https://uifabric.visualstudio.com/iss/_workitems/create/User%20Story?templateId=c0a6b2f0-ecaf-4f0e-83a6-a3ea43f30847&ownerId=0c0ad9a8-059c-4697-a4b6-ff1179ca8699",children:"here"}),".\nMake sure to specify the current and expected behavior along with repro steps so that our team can take appropriate action to the request."]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"For Pull Requests:"}),"\n",(0,n.jsx)(t.em,{children:"During planning of the implementation:"})]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Go through the documentation and design decisions for the respective component."}),"\n",(0,n.jsx)(t.li,{children:"Any design and/or behavior changes should be reviewed by the charting core team to validate its consistency, generalization, and visual design alignment with the rest of the charts."}),"\n",(0,n.jsx)(t.li,{children:"If the change is major, the dev design should be reviewed by the charting core team to ensure the changes are aligned to the overall design of the library and does not cause any unexpected behavior."}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.em,{children:"After implementation"})}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Follow [Testing Strategy](Testing Strategy.md) to ensure all the changes are tested and relevant scenarios are automated."}),"\n",(0,n.jsxs)(t.li,{children:["Test for relevant accessibility scenarios. Refer ",(0,n.jsx)(t.a,{href:"/fluentui-charting-contrib/docs/Accessibility",children:"Accessibility Guide"})," for more details."]}),"\n",(0,n.jsx)(t.li,{children:"The contributor needs to provide a 30 day support to fix any bug arising due to their change."}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.strong,{children:"Checklist for a partner feature contribution."})}),"\n",(0,n.jsxs)(t.ul,{className:"contains-task-list",children:["\n",(0,n.jsxs)(t.li,{className:"task-list-item",children:[(0,n.jsx)(t.input,{type:"checkbox",disabled:!0})," ","Clearly mention the usecase and a video of the functionality that you have implemented."]}),"\n",(0,n.jsxs)(t.li,{className:"task-list-item",children:[(0,n.jsx)(t.input,{type:"checkbox",disabled:!0})," ","Test Plan Item created and corresponding test passed."]}),"\n",(0,n.jsxs)(t.li,{className:"task-list-item",children:[(0,n.jsx)(t.input,{type:"checkbox",disabled:!0})," ","Add examples on our demo site for new scenarios."]}),"\n",(0,n.jsxs)(t.li,{className:"task-list-item",children:[(0,n.jsx)(t.input,{type:"checkbox",disabled:!0})," ","Test for keyboard accessibility"]}),"\n",(0,n.jsxs)(t.li,{className:"task-list-item",children:[(0,n.jsx)(t.input,{type:"checkbox",disabled:!0})," ","Test for screen reader accessibility"]}),"\n",(0,n.jsxs)(t.li,{className:"task-list-item",children:[(0,n.jsx)(t.input,{type:"checkbox",disabled:!0})," ","Works with light theme, dark theme and high contrast theme."]}),"\n",(0,n.jsxs)(t.li,{className:"task-list-item",children:[(0,n.jsx)(t.input,{type:"checkbox",disabled:!0})," ","Release notes updated with appropriate details."]}),"\n",(0,n.jsxs)(t.li,{className:"task-list-item",children:[(0,n.jsx)(t.input,{type:"checkbox",disabled:!0})," ","30 day support for user reported or accessibility bugs in your feature area."]}),"\n",(0,n.jsxs)(t.li,{className:"task-list-item",children:[(0,n.jsx)(t.input,{type:"checkbox",disabled:!0})," ","Works with RTL languages"]}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Measuring the impact of your contribution"}),"\nThe charting team is working to define datapoints to measure the usage of different charts and their functionalities. We will soon publish metrics with quantitative impact of your contribution across the organization."]})]})}function u(e={}){const{wrapper:t}={...(0,s.a)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},1151:(e,t,i)=>{i.d(t,{Z:()=>o,a:()=>a});var n=i(7294);const s={},r=n.createContext(s);function a(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/b0e8dd6d.480b3d8a.js b/assets/js/b0e8dd6d.480b3d8a.js
new file mode 100644
index 0000000000..4c18022f76
--- /dev/null
+++ b/assets/js/b0e8dd6d.480b3d8a.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[8673],{6231:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var n=i(5893),s=i(1151);const r={},a=void 0,o={id:"Contributor Guide",title:"Contributor Guide",description:"Fluent charting library is a collection of individual charts like LineChart, AreaChart, Horizontal bar chart, vertical bar chart.",source:"@site/../../docs/Contributor Guide.md",sourceDirName:".",slug:"/Contributor Guide",permalink:"/fluentui-charting-contrib/docs/Contributor Guide",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Start Developing",permalink:"/fluentui-charting-contrib/docs/Start Developing"},next:{title:"Area Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/AreaChart"}},c={},l=[];function d(e){const t={a:"a",em:"em",input:"input",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:"Fluent charting library is a collection of individual charts like LineChart, AreaChart, Horizontal bar chart, vertical bar chart.\nCharting components are built as production-ready, generalized, documented, and reusable components to be used in Microsoft products. This enables us and our partners to easily build great applications without spending a ton of time implementing the same controls over and over.\nEach component is designed to be RTL-friendly, keyboard accessible, screen reader-friendly, themable, and generalized. TypeScript definition files are also included, so if you use TypeScript (which isn't a requirement), you will get compiler validation and using an editor like VS Code, you'll get intellisense. Each component is exported as a named module that can be easily imported in your code, allowing your external bundler to create small bundles that include just what you need."}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Contribution process"}),"\nWe invite members of the community to actively participate in any way - code, documentation, design, publicity, moderation, analytics, explorations, dicussions and more."]}),"\n",(0,n.jsx)(t.p,{children:"Before proceeding into details, we would like to set some contractual guidelines with our contributor community."}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Commitments from the maintaining team"})," ",(0,n.jsx)(t.a,{href:"https://github.com/orgs/microsoft/teams/charting-team",children:"(charting-team)"})]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Responding to queries within a day."}),"\n",(0,n.jsx)(t.li,{children:"Responding to PRs within 2 business days."}),"\n",(0,n.jsx)(t.li,{children:"Publishing day to day design discussions, decisions taken, roadmaps, backlogs and current sprint board."}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Expectations from contributors"}),"\n",(0,n.jsx)(t.strong,{children:"For Issues:"}),"\nFollow the ",(0,n.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/issues/new/choose",children:"issue template"})," to report bugs and feature requests.\nFor internal product requests that can contain confidential information, report issues to our internal ADO ",(0,n.jsx)(t.a,{href:"https://uifabric.visualstudio.com/iss/_workitems/create/User%20Story?templateId=c0a6b2f0-ecaf-4f0e-83a6-a3ea43f30847&ownerId=0c0ad9a8-059c-4697-a4b6-ff1179ca8699",children:"here"}),".\nMake sure to specify the current and expected behavior along with repro steps so that our team can take appropriate action to the request."]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"For Pull Requests:"}),"\n",(0,n.jsx)(t.em,{children:"During planning of the implementation:"})]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Go through the documentation and design decisions for the respective component."}),"\n",(0,n.jsx)(t.li,{children:"Any design and/or behavior changes should be reviewed by the charting core team to validate its consistency, generalization, and visual design alignment with the rest of the charts."}),"\n",(0,n.jsx)(t.li,{children:"If the change is major, the dev design should be reviewed by the charting core team to ensure the changes are aligned to the overall design of the library and does not cause any unexpected behavior."}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.em,{children:"After implementation"})}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Follow [Testing Strategy](Testing Strategy.md) to ensure all the changes are tested and relevant scenarios are automated."}),"\n",(0,n.jsxs)(t.li,{children:["Test for relevant accessibility scenarios. Refer ",(0,n.jsx)(t.a,{href:"/fluentui-charting-contrib/docs/Accessibility",children:"Accessibility Guide"})," for more details."]}),"\n",(0,n.jsx)(t.li,{children:"The contributor needs to provide a 30 day support to fix any bug arising due to their change."}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.strong,{children:"Checklist for a partner feature contribution."})}),"\n",(0,n.jsxs)(t.ul,{className:"contains-task-list",children:["\n",(0,n.jsxs)(t.li,{className:"task-list-item",children:[(0,n.jsx)(t.input,{type:"checkbox",disabled:!0})," ","Clearly mention the usecase and a video of the functionality that you have implemented."]}),"\n",(0,n.jsxs)(t.li,{className:"task-list-item",children:[(0,n.jsx)(t.input,{type:"checkbox",disabled:!0})," ","Test Plan Item created and corresponding test passed."]}),"\n",(0,n.jsxs)(t.li,{className:"task-list-item",children:[(0,n.jsx)(t.input,{type:"checkbox",disabled:!0})," ","Add examples on our demo site for new scenarios."]}),"\n",(0,n.jsxs)(t.li,{className:"task-list-item",children:[(0,n.jsx)(t.input,{type:"checkbox",disabled:!0})," ","Test for keyboard accessibility"]}),"\n",(0,n.jsxs)(t.li,{className:"task-list-item",children:[(0,n.jsx)(t.input,{type:"checkbox",disabled:!0})," ","Test for screen reader accessibility"]}),"\n",(0,n.jsxs)(t.li,{className:"task-list-item",children:[(0,n.jsx)(t.input,{type:"checkbox",disabled:!0})," ","Works with light theme, dark theme and high contrast theme."]}),"\n",(0,n.jsxs)(t.li,{className:"task-list-item",children:[(0,n.jsx)(t.input,{type:"checkbox",disabled:!0})," ","Release notes updated with appropriate details."]}),"\n",(0,n.jsxs)(t.li,{className:"task-list-item",children:[(0,n.jsx)(t.input,{type:"checkbox",disabled:!0})," ","30 day support for user reported or accessibility bugs in your feature area."]}),"\n",(0,n.jsxs)(t.li,{className:"task-list-item",children:[(0,n.jsx)(t.input,{type:"checkbox",disabled:!0})," ","Works with RTL languages"]}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Measuring the impact of your contribution"}),"\nThe charting team is working to define datapoints to measure the usage of different charts and their functionalities. We will soon publish metrics with quantitative impact of your contribution across the organization."]})]})}function u(e={}){const{wrapper:t}={...(0,s.a)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},1151:(e,t,i)=>{i.d(t,{Z:()=>o,a:()=>a});var n=i(7294);const s={},r=n.createContext(s);function a(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/b7f64af1.4fb71bce.js b/assets/js/b7f64af1.4fb71bce.js
new file mode 100644
index 0000000000..0dd40fcacb
--- /dev/null
+++ b/assets/js/b7f64af1.4fb71bce.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[8751],{4622:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>r,default:()=>d,frontMatter:()=>s,metadata:()=>h,toc:()=>l});var a=n(5893),i=n(1151);const s={},r="Vertical Stacked Bar Chart",h={id:"Charting-Concepts/VerticalStackedBarChart",title:"Vertical Stacked Bar Chart",description:"VerticalStackedBarChart1.png",source:"@site/../../docs/Charting-Concepts/VerticalStackedBarChart.md",sourceDirName:"Charting-Concepts",slug:"/Charting-Concepts/VerticalStackedBarChart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/VerticalStackedBarChart",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Vertical Bar Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/VerticalBarChart"},next:{title:"Technical details",permalink:"/fluentui-charting-contrib/docs/Technical Details"}},o={},l=[];function c(e){const t={a:"a",code:"code",em:"em",h1:"h1",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.h1,{id:"vertical-stacked-bar-chart",children:"Vertical Stacked Bar Chart"}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"VerticalStackedBarChart1.png",src:n(4757).Z+"",width:"1207",height:"781"})}),"\n",(0,a.jsx)(t.p,{children:"A vertical stacked bar chart is a type of chart that displays multiple series of data as stacked bars, with each bar representing a category. The bars are stacked on top of each other, with the height of each bar representing the total value of the series at that category."}),"\n",(0,a.jsx)(t.p,{children:"In a vertical stacked bar chart, the x-axis represents the categories, while the y-axis represents the values of the series. Each bar is divided into segments, with each segment representing a different series. The segments are colored differently to differentiate between the series."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"Use cases"}),"\nHere are some common use cases for a vertical stacked bar chart:","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"Comparing the total size of different categories over time"}),"\n",(0,a.jsx)(t.li,{children:"Analyzing the composition of a whole category into subcategories"}),"\n",(0,a.jsx)(t.li,{children:"Identifying trends in the distribution of data over time"}),"\n",(0,a.jsx)(t.li,{children:"Comparing the relative sizes of different categories at a single point in time"}),"\n",(0,a.jsx)(t.li,{children:"Highlighting the contribution of each subcategory to the whole category"}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.strong,{children:"Mathematical/Geometrical concepts"})}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"VerticalStackedBarChart2.png",src:n(3160).Z+"",width:"1128",height:"753"})}),"\n",(0,a.jsx)(t.p,{children:"The major D3 functions that are involved in the creation of Vertical bar charts are:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"d3-scale:"}),"\nThe\xa0d3-scale\xa0module is a part of the d3 library, which is a collection of JavaScript functions that are used for data visualization. The\xa0d3-scale\xa0module provides several functions for creating and manipulating scales, which are used to map data values to visual properties, such as\xa0position, size, and color."]}),"\n",(0,a.jsx)(t.p,{children:"The\xa0d3-scale\xa0module includes several scale types, including linear, logarithmic, power, and time scales. These scales are used to map continuous data values to a continuous range of visual properties. The module also includes ordinal and band scales, which are used to map categorical data values to a discrete range of visual properties."}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"The\xa0d3-scale\xa0module provides several functions for creating and manipulating scales, including\xa0scaleLinear, scaleLog, scalePow, scaleTime, scaleOrdinal, and scaleBand. These functions take one or more arguments that define the domain and range of the scale, as well as any additional properties, such as the number of ticks or the padding between bands."}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Application in Vertical Stacked bar chart:"}),"\nIn the Vertical Stacked Bar Chart, d3-scale is used to create scales for the x and y axes of the chart. The d3-scale library provides a set of functions for creating different types of scales, such as linear, logarithmic, and ordinal scales. Here, the d3-scale library is used to create a linear scale for the y-axis of the chart."]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"d3.scaleLinear()"}),": The\xa0d3ScaleLinear\xa0is a function from the\xa0d3-scale\xa0module that is used to create a linear scale for the y-axis of the chart. The linear scale maps a continuous domain of data values to a continuous range of visual properties, such as position or height. The\xa0d3ScaleLinear\xa0function takes no arguments and returns a new linear scale. The scale can be customized using several methods, including\xa0domain, range, clamp, and nice. The\xa0domain\xa0method sets the domain of the scale, which is the range of data values that the scale maps to the range of visual properties. The\xa0range\xa0method sets the range of the scale, which is the range of visual properties that the scale maps to the domain of data values."]}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Application in Vertical Stacked bar chart:"}),"\nIn Vertical stacked bar chart,\xa0d3.scaleLinear()\xa0is used to create a linear scale for the y-axis of the chart."]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"A linear scale is a mapping function that maps a continuous input domain to a continuous output range. In this case, the input domain is the range of data values to be plotted on the y-axis, and the output range is the range of pixel values available for the y-axis on the chart."}),"\n",(0,a.jsx)(t.li,{children:"The\xa0scaleLinear()\xa0method of the\xa0d3\xa0library returns a new linear scale function. This function can be used to map data values to pixel values on the y-axis of the chart."}),"\n",(0,a.jsx)(t.li,{children:"To create the scale, the\xa0domain()\xa0method is used to set the minimum and maximum values of the data array as the input domain. The\xa0range()\xa0method is used to set the height of the chart minus the top and bottom margins as the output range."}),"\n",(0,a.jsx)(t.li,{children:"The resulting\xa0yScale\xa0function can then be used to map data values to pixel values on the y-axis of the chart."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"d3.scaleBand():"}),"\xa0The\xa0d3ScaleBand\xa0is a function from the\xa0d3-scale\xa0module that is used to create a band scale for the x-axis of the chart. The band scale maps a discrete domain of data values to a discrete range of visual properties, such as\xa0position or width. The\xa0d3ScaleBand\xa0function takes no arguments and returns a new band scale. The scale can be customized using several methods, including\xa0domain, range, padding, and align. The\xa0domain\xa0method sets the domain of the scale, which is the range of data values that the scale maps to the range of visual properties. The\xa0range\xa0method sets the range of the scale, which is the range of visual properties that the scale maps to the domain of data values. The\xa0padding\xa0method sets the padding between the bands of the scale, which determines the width of the bands. The\xa0align\xa0method sets the alignment of the bands within the range of the scale."]}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Application in Vertical Stacked bar chart:"}),"\nIn the vertical stacked bar chart,\xa0d3.scaleBand()\xa0is used to create a band scale for the x-axis of the chart."]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"A band scale is a mapping function that maps a discrete input domain to a continuous output range. In this case, the input domain is an array of discrete values to be plotted on the x-axis, and the output range is the range of pixel values available for the x-axis on the chart."}),"\n",(0,a.jsx)(t.li,{children:"The\xa0scaleBand()\xa0method of the\xa0d3\xa0library returns a new band scale function. This function can be used to map data values to pixel values on the x-axis of the chart."}),"\n",(0,a.jsx)(t.li,{children:"To create the scale, the\xa0domain()\xa0method is used to set the array of discrete values as the input domain. The\xa0range()\xa0method is used to set the width of the chart minus the left and right margins as the output range."}),"\n",(0,a.jsx)(t.li,{children:"The\xa0padding()\xa0method can be used to set the padding between the bands in the scale. The\xa0paddingInner()\xa0and\xa0paddingOuter()\xa0methods can be used to set the inner and outer padding, respectively."}),"\n",(0,a.jsx)(t.li,{children:"The resulting\xa0xScale\xa0function can then be used to map data values to pixel values on the x-axis of the chart."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"d3-selection:"}),"\xa0The\xa0d3-selection\xa0is a module from the d3 library that is used to select and manipulate DOM elements in the chart component. The\xa0d3-selection\xa0module provides several functions for selecting and manipulating DOM elements, including\xa0select, selectAll, append, attr, and style. The select function is used to select a single DOM element that matches a given selector. The\xa0selectAll\xa0function is used to select multiple DOM elements that match a given selector. The\xa0append\xa0function is used to append a new DOM element to a selected element. The\xa0attr\xa0function is used to set or get an attribute of a selected element. The\xa0style\xa0function is used to set or get a style property of a selected element."]}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Application in Vertical Stacked bar chart:"}),"\nIn the Vertical stacked bar chart, d3-selection is used to select and manipulate DOM elements in the chart."]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The\xa0d3-selection\xa0library provides various methods for selecting and manipulating DOM elements, such as\xa0select(), selectAll(), append(), and attr(). In this case, the\xa0d3-selection\xa0library is used to select the\xa0svg\xa0element that holds the chart and to create and manipulate the\xa0rect\xa0elements that represent the bars in the chart."}),"\n",(0,a.jsx)(t.li,{children:"To select the\xa0svg\xa0element, the\xa0d3-selection\xa0library's\xa0select()\xa0method is used. This method takes\xa0SVG\xa0node as an argument and returns a new selection object that represents the selected element. The resulting selection object can then be used to manipulate the selected element."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"d3-array:"}),"\xa0The\xa0d3-array\xa0is a module from the d3 library that is used to manipulate arrays of data in the chart component. The\xa0d3-array\xa0module provides several functions for manipulating arrays of data, including\xa0max, min, extent, sum, and mean. The\xa0max\xa0function is used to find the maximum value in an array of data. The\xa0min\xa0function is used to find the minimum value in an array of data. The\xa0extent\xa0function is used to find the minimum and maximum values in an array of data. The\xa0sum\xa0function is used to find the sum of the values in an array of data. The\xa0mean\xa0function is used to find the mean (average) of the values in an array of data."]}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Application in Vertical Stacked bar chart:"}),"\nIn the Vertical stacked bar chart,\xa0d3-array\xa0is used to calculate the minimum and maximum values of the data array."]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The\xa0d3-array\xa0library provides various methods for working with arrays of data, such as\xa0min(),\xa0max(), and\xa0sum(). In this case, the\xa0d3-array\xa0library is used to calculate the minimum and maximum values of the data array."}),"\n",(0,a.jsx)(t.li,{children:"To calculate the minimum and maximum values of the data array, the\xa0d3-array\xa0library's\xa0min()\xa0and\xa0max()\xa0methods are used. These methods take an array of data as an argument and return the minimum and maximum values of the array, respectively."}),"\n",(0,a.jsx)(t.li,{children:"The resulting minimum and maximum values are then used to set the input domain of the y-axis scale created using the\xa0d3-scale\xa0library."}),"\n",(0,a.jsx)(t.li,{children:"Overall, the\xa0d3-array\xa0library is used to calculate the minimum and maximum values of the data array by using the\xa0min()\xa0and\xa0max()\xa0methods. These values are then used to set the input domain of the y-axis scale created using the\xa0d3-scale\xa0library."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"d3-format:"}),"\xa0The\xa0d3-format\xa0is a module from the d3 library that is used to format numbers and strings in the chart component. The\xa0d3-format\xa0module provides several functions for formatting numbers and strings, including\xa0format, formatPrefix, precisionFixed, and precisionRound."]}),"\n",(0,a.jsx)(t.p,{children:"The\xa0format\xa0function is used to format a number or string using a specified format string. The format string can include placeholders for the value, such as\xa0%\xa0for a percentage or\xa0,\xa0for a comma-separated number. The\xa0formatPrefix\xa0function is used to format a number using a prefix notation that rounds the value to a specified precision and appends a prefix, such as k for thousands or M for millions. The\xa0precisionFixed\xa0function is used to format a number using a fixed number of decimal places. The\xa0precisionRound\xa0function is used to format a number using a variable number of decimal places that is determined by the magnitude of the value."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Application in Vertical Stacked bar chart:"}),"\nIn the Vertical stacked bar chart,\xa0d3-format\xa0is used to format the tick values on the y-axis of the chart."]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The\xa0d3-format\xa0library provides various methods for formatting numbers, such as\xa0format(),\xa0formatPrefix(), and\xa0precisionRound(). In this case, the\xa0d3-format\xa0library is used to format the tick values on the y-axis of the chart."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"To format the tick values, the\xa0d3-format\xa0library's\xa0format()\xa0method is used. This method takes a format string as an argument and returns a new function that can be used to format numbers according to the specified format."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The resulting format function is then used to format the tick values on the y-axis of the chart. The tick values are generated using the\xa0ticks()\xa0method of the y-axis scale created using the\xa0d3-scale\xa0library."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The\xa0tickFormat()\xa0method of the y-axis scale is then used to set the tick format function. This method takes the format function as an argument and sets it as the tick format function for the y-axis scale."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"Overall, the\xa0d3-format\xa0library is used to format the tick values on the y-axis of the chart by using the\xa0format()\xa0method to create a format function and setting this function as the tick format function for the y-axis scale using the\xa0tickFormat()\xa0method."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"d3-axis:"}),"\xa0The\xa0d3-axis\xa0module is a part of the d3 library, which is a collection of JavaScript functions that are used for data visualization. The\xa0d3-axis\xa0module provides several functions for creating and manipulating axes, which are used to display the scales of a chart component."]}),"\n",(0,a.jsx)(t.p,{children:"In data visualization, axes are used to display the scales of a chart component, such as the x-axis and y-axis of a bar chart. Axes provide visual cues to help readers interpret the data values of a chart component, such as the range and domain of the data values."}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"The\xa0d3-axis\xa0module provides several types of axes, including\xa0bottom, top, left, and right axes. Each type of axis has its own set of methods for customizing the axis and displaying the tick values."}),"\n",(0,a.jsx)(t.p,{children:"Overall, the\xa0d3-axis\xa0module is an essential part of data visualization, as it provides a powerful and flexible way to display the scales of a chart component and help readers interpret the data values of the chart."}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Application in Vertical Stacked bar chart:"}),"\nIn the Vertical stacked bar chart,\xa0d3-axis\xa0is used to create and render the x and y axes of the chart."]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The\xa0d3-axis\xa0library provides various methods for creating and rendering axes, such as\xa0axisBottom(),\xa0axisLeft(), and\xa0tickFormat(). In this case, the\xa0d3-axis\xa0library is used to create and render the x and y axes of the chart."}),"\n",(0,a.jsx)(t.li,{children:"To create the x and y axes, the\xa0d3-axis\xa0library's\xa0axisBottom()\xa0and\xa0axisLeft()\xa0methods are used, respectively. These methods take a scale function as an argument and return a new axis function that can be used to render the axis."}),"\n",(0,a.jsx)(t.li,{children:"The resulting x and y axis functions are then used to render the x and y axes of the chart. The\xa0call()\xa0method of the selection object is used to call the axis function and render the axis."}),"\n",(0,a.jsx)(t.li,{children:"The\xa0tickFormat()\xa0method of the y-axis scale is also used to set the tick format function for the y-axis. This method takes the format function created using the\xa0d3-format\xa0library as an argument and sets it as the tick format function for the y-axis."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Overall, the\xa0d3-axis\xa0library is used to create and render the x and y axes of the chart by using the\xa0axisBottom()\xa0and\xa0axisLeft()\xa0methods to create the axis functions and the\xa0call()\xa0method to render the axes. The\xa0tickFormat()\xa0method is also used to set the tick format function for the y-axis."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"Dev Design details"}),"\nFollowing are the major components that contribute towards creating a complete vertical stacked bar chart:","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"Axes:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"_getScales():"}),"\xa0This method is responsible for creating the x and y scales for the chart."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Function arguments:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"containerHeight: a number representing the height of the container in which the chart will be rendered."}),"\n",(0,a.jsx)(t.li,{children:"containerWidth: a number representing the width of the container in which the chart will be rendered."}),"\n",(0,a.jsx)(t.li,{children:"isNumeric: a boolean value indicating whether the x-axis data is numeric or not. If\xa0true, the x-axis data is numeric, otherwise it is not."}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The method takes several arguments, including the container height and width, and a boolean value indicating whether the x-axis is numeric or categorical."}),"\n",(0,a.jsx)(t.li,{children:"The method first calculates the maximum y-value of the chart data and creates a linear scale for the y-axis using the\xa0d3-scale\xa0library's\xa0scaleLinear()\xa0method. The domain of the y-axis scale is set to\xa0[0, yMax], where\xa0yMax\xa0is the maximum y-value of the chart data. The range of the y-axis scale is set to\xa0[0, containerHeight - this.margins.bottom! - this.margins.top!], where\xa0containerHeight\xa0is the height of the chart container and\xa0this.margins.bottom!\xa0and\xa0this.margins.top!\xa0are the bottom and top margins of the chart, respectively."}),"\n",(0,a.jsx)(t.li,{children:"If the x-axis is numeric, the method calculates the minimum and maximum x-values of the chart data using the\xa0d3-array\xa0library's\xa0d3Min()\xa0and\xa0d3Max()\xa0methods. It then creates a linear scale for the x-axis using the\xa0d3-scale\xa0library's\xa0scaleLinear()\xa0method. The domain of the x-axis scale is set to\xa0[xMin, xMax]\xa0or\xa0[xMax, xMin]\xa0if the chart is right-to-left, where\xa0xMin\xa0and\xa0xMax\xa0are the minimum and maximum x-values of the chart data, respectively. The range of the x-axis scale is set to\xa0[this.margins.left! + this._domainMargin, containerWidth - this.margins.right! - this._barWidth - this._domainMargin], where\xa0this.margins.left!\xa0and\xa0this.margins.right!\xa0are the left and right margins of the chart, respectively, and\xa0this._barWidth\xa0and\xa0this._domainMargin\xa0are properties of the chart."}),"\n",(0,a.jsx)(t.li,{children:"If the x-axis is categorical, the method creates a band scale for the x-axis using the\xa0d3-scale\xa0library's\xa0scaleBand()\xa0method. The domain of the x-axis scale is set to the unique x-axis labels of the chart data. The range of the x-axis scale is set to\xa0[this.margins.left! + this._domainMargin, containerWidth - this.margins.right! - this._domainMargin], where\xa0this.margins.left!\xa0and\xa0this.margins.right!\xa0are the left and right margins of the chart, respectively, and\xa0this._domainMargin\xa0is a property of the chart. The\xa0paddingInner()\xa0method is used to set the inner padding of the bars to\xa02 / 3."}),"\n",(0,a.jsx)(t.li,{children:"Finally, the method returns an object with the x and y scales."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Overall, the\xa0_getScales\xa0method is responsible for creating the x and y scales for the chart using the\xa0d3-scale\xa0library's\xa0scaleLinear()\xa0and\xa0scaleBand()\xa0methods. The method calculates the domain and range of the scales based on the chart data and properties of the chart."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"_getDomainMargins():"}),"\xa0This method is responsible for calculating the margins for the x-axis domain based on the width of the chart container and the width of the bars."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Function arguments:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"containerWidth\xa0which is a number representing the width of the container in which the chart is being rendered."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The method takes a single argument,\xa0containerWidth, which is the width of the chart container."}),"\n",(0,a.jsx)(t.li,{children:"The method first checks whether the x-axis is numeric or categorical. If the x-axis is not numeric, the method calculates the total width available to render the bars by subtracting the left and right margins and the minimum domain margin from the container width. It then calculates the required width to render the bars based on the number of x-axis labels and the bar width. If the total width available is greater than or equal to the required width, the method sets the domain margin to half of the difference between the total width available and the required width to center align the chart. If the total width available is less than the required width, the method calculates the maximum possible bar width to maintain a 2:1 spacing between the bars and sets the domain margin to the minimum domain margin."}),"\n",(0,a.jsx)(t.li,{children:"The method then sets the bar width and domain margin properties of the chart based on the calculated values."}),"\n",(0,a.jsx)(t.li,{children:"Finally, the method returns an object with the margins for the x-axis domain, which includes the left and right margins and the domain margin."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Overall, the\xa0_getDomainMargins\xa0method is responsible for calculating the margins for the x-axis domain based on the width of the chart container and the width of the bars. The method calculates the total width available to render the bars, the required width to render the bars, and the maximum possible bar width to maintain a 2:1 spacing between the bars. The method then sets the domain margin and bar width properties of the chart based on the calculated values."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"createNumericXAxis():"}),"\xa0The code above is a function called\xa0createNumericXAxis\xa0in the\xa0utilities.ts\xa0file. This function is responsible for creating a numeric x-axis for a chart component. The function takes two arguments:\xa0xAxisParams\xa0and\xa0chartType.\xa0xAxisParams\xa0is an object that contains several properties, including\xa0domainNRangeValues,\xa0showRoundOffXTickValues,\xa0xAxistickSize,\xa0tickPadding,\xa0xAxisCount, and\xa0xAxisElement.\xa0chartType\xa0is an enumeration that specifies the type of chart component."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Function arguments:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["xAxisParams\xa0of type\xa0IXAxisParams\xa0which is an object containing the following properties:","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"domainNRangeValues\xa0of type\xa0IDomainNRange\xa0which is an object containing the domain and range values for the x-axis."}),"\n",(0,a.jsx)(t.li,{children:"showRoundOffXTickValues\xa0of type\xa0boolean\xa0which is an optional property that determines whether to round off the x-axis tick values."}),"\n",(0,a.jsx)(t.li,{children:"xAxistickSize\xa0of type\xa0number\xa0which is an optional property that determines the size of the x-axis ticks."}),"\n",(0,a.jsx)(t.li,{children:"tickPadding\xa0of type\xa0number\xa0which is an optional property that determines the padding between the x-axis ticks and the x-axis labels."}),"\n",(0,a.jsx)(t.li,{children:"xAxisCount\xa0of type\xa0number\xa0which is an optional property that determines the number of x-axis ticks."}),"\n",(0,a.jsx)(t.li,{children:"xAxisElement\xa0of type\xa0SVGElement | null\xa0which is an optional property that represents the x-axis element."}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.li,{children:"chartType\xa0of type\xa0ChartTypes\xa0which is an enum that represents the type of chart."}),"\n",(0,a.jsx)(t.li,{children:"culture\xa0of type string which is an optional paramter represents the locale into which the numeric x-axis labels will be localized."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The function first extracts the properties of the\xa0xAxisParams\xa0object using destructuring. The\xa0domainNRangeValues\xa0property is an object that contains the start and end values of the domain and range of the x-axis. The\xa0showRoundOffXTickValues\xa0property is a boolean that specifies whether to round off the tick values of the x-axis. The\xa0xAxistickSize\xa0property is a number that specifies the size of the ticks of the x-axis. The\xa0tickPadding\xa0property is a number that specifies the padding between the ticks and the labels of the x-axis. The\xa0xAxisCount\xa0property is a number that specifies the number of ticks of the x-axis. The\xa0xAxisElement\xa0property is a reference to the DOM node that contains the x-axis of the chart."}),"\n",(0,a.jsx)(t.li,{children:"The function then creates a linear scale for the x-axis using the\xa0d3ScaleLinear\xa0function from the\xa0d3-scale\xa0module. The scale is customized using the\xa0domain\xa0and\xa0range\xa0methods, which set the domain and range of the scale, respectively. If the\xa0showRoundOffXTickValues\xa0property is\xa0true, the\xa0nice\xa0method is called on the scale to round off the tick values of the x-axis."}),"\n",(0,a.jsx)(t.li,{children:"The function then creates a bottom axis for the x-axis using the\xa0d3AxisBottom\xa0function from the\xa0d3-axis\xa0module. The axis is customized using the\xa0tickSize,\xa0tickPadding,\xa0ticks, and\xa0tickFormat\xa0methods. The\xa0tickSize\xa0method sets the size of the ticks of the x-axis. The\xa0tickPadding\xa0method sets the padding between the ticks and the labels of the x-axis. The\xa0ticks\xa0method sets the number of ticks of the x-axis. The\xa0tickFormat\xa0method formats the tick values of the x-axis using the\xa0convertToLocaleString\xa0function and the\xa0culture\xa0parameter."}),"\n",(0,a.jsx)(t.li,{children:"If the\xa0xAxisElement\xa0property is not\xa0null, the axis is rendered on the DOM node using the\xa0call\xa0method of the\xa0d3-selection\xa0module. The\xa0selectAll\xa0method is called on the axis to select all the text elements of the x-axis, and the\xa0attr\xa0method is called to set the\xa0aria-hidden\xa0attribute of the text elements to\xa0true."}),"\n",(0,a.jsx)(t.li,{children:"Finally, the function computes the tick values of the x-axis using the\xa0ticks\xa0and\xa0tickFormat\xa0methods of the scale, and returns an object that contains the x-axis scale and the tick values."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Overall, the\xa0createNumericXAxis\xa0function is responsible for creating a numeric x-axis for a chart component. The function creates a linear scale for the x-axis and a bottom axis for the x-axis using the\xa0d3-scale\xa0and\xa0d3-axis\xa0modules, respectively. The function customizes the scale and axis using several methods, including\xa0domain,\xa0range,\xa0tickSize,\xa0tickPadding,\xa0ticks, and\xa0tickFormat. The function also renders the axis on the DOM node and computes the tick values of the x-axis."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"createStringXAxis():"}),"\xa0This function is responsible for creating a string x-axis for a chart component. The function takes four arguments:\xa0xAxisParams,\xa0tickParams,\xa0dataset, and\xa0culture.\xa0xAxisParams\xa0is an object that contains several properties, including\xa0domainNRangeValues,\xa0xAxisCount,\xa0xAxistickSize,\xa0tickPadding,\xa0xAxisPadding,\xa0xAxisInnerPadding, and\xa0xAxisOuterPadding.\xa0tickParams\xa0is an object that contains several properties, including\xa0tickValues\xa0and\xa0tickFormat.\xa0dataset\xa0is an array of strings that contains the values of the x-axis.\xa0culture\xa0is a string that specifies the locale into which the x-axis labels can be localized."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Function Arguments:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"xAxisParams: An object containing the parameters for the x-axis, including the domain and range values, tick size, tick padding, number of ticks, padding for the inner and outer edges of the axis, and the element to render the axis."}),"\n",(0,a.jsx)(t.li,{children:"tickParams: An object containing the parameters for the ticks on the x-axis, including the tick values and tick format."}),"\n",(0,a.jsx)(t.li,{children:"dataset: An array of strings representing the data points for the x-axis."}),"\n",(0,a.jsx)(t.li,{children:"culture: An optional string representing the culture to use for formatting the tick labels on the x-axis. However, the localization works only if the string can be converted to a numeric value. Otherwise, the x-axis labels remain unlocalized."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The function first extracts the properties of the\xa0xAxisParams\xa0object using destructuring. The\xa0domainNRangeValues\xa0property is an object that contains the start and end values of the domain and range of the x-axis. The\xa0xAxisCount\xa0property is a number that specifies the number of ticks of the x-axis. The\xa0xAxistickSize\xa0property is a number that specifies the size of the ticks of the x-axis. The\xa0tickPadding\xa0property is a number that specifies the padding between the ticks and the labels of the x-axis. The\xa0xAxisPadding\xa0property is a number that specifies the padding between the bars of the chart. The\xa0xAxisInnerPadding\xa0property is a number that specifies the inner padding between the bars of the chart. The\xa0xAxisOuterPadding\xa0property is a number that specifies the outer padding between the bars of the chart."}),"\n",(0,a.jsx)(t.li,{children:"The function then creates a band scale for the x-axis using the\xa0d3ScaleBand\xa0function from the\xa0d3-scale\xa0module. The scale is customized using the\xa0domain\xa0and\xa0range\xa0methods, which set the domain and range of the scale, respectively. The\xa0paddingInner\xa0and\xa0paddingOuter\xa0methods are used to set the inner and outer padding between the bars of the chart, respectively."}),"\n",(0,a.jsx)(t.li,{children:"The function then creates a bottom axis for the x-axis using the\xa0d3AxisBottom\xa0function from the\xa0d3-axis\xa0module. The axis is customized using the\xa0tickSize,\xa0tickPadding,\xa0ticks, and\xa0tickFormat\xa0methods. The\xa0tickSize\xa0method sets the size of the ticks of the x-axis. The\xa0tickPadding\xa0method sets the padding between the ticks and the labels of the x-axis. The\xa0ticks\xa0method sets the number of ticks of the x-axis. The\xa0tickFormat\xa0method formats the tick values of the x-axis using the\xa0convertToLocaleString\xa0function and the\xa0culture\xa0parameter."}),"\n",(0,a.jsx)(t.li,{children:"If the\xa0xAxisParams.xAxisElement\xa0property is not\xa0null, the axis is rendered on the DOM node using the\xa0call\xa0method of the\xa0d3-selection\xa0module. The\xa0selectAll\xa0method is called on the axis to select all the text elements of the x-axis, and the\xa0attr\xa0method is called to set the\xa0aria-hidden\xa0attribute of the text elements to\xa0true."}),"\n",(0,a.jsx)(t.li,{children:"Finally, the function computes the tick values of the x-axis using the\xa0tickFormat\xa0method of the axis, and returns an object that contains the x-axis scale and the tick values."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Overall, the\xa0createStringXAxis\xa0function is responsible for creating a string x-axis for a chart component. The function creates a band scale for the x-axis and a bottom axis for the x-axis using the\xa0d3-scale\xa0and\xa0d3-axis\xa0modules, respectively. The function customizes the scale and axis using several methods, including\xa0domain,\xa0range,\xa0paddingInner,\xa0paddingOuter,\xa0tickSize,\xa0tickPadding,\xa0ticks, and\xa0tickFormat. The function also renders the axis on the DOM node and computes the tick values of the x-axis."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"createYAxis():"}),"\xa0In the Vertical bar chart component, the\xa0d3-axis\xa0module is used to create and customize the y-axis of a vertical bar chart. The\xa0createYAxis\xa0function is responsible for creating the y-axis using the\xa0createYAxisForOtherCharts\xa0function. The function takes in several parameters, including\xa0yAxisParams,\xa0isRtl,\xa0axisData, and\xa0useSecondaryYScale. These parameters are used to customize the y-axis, such as setting the tick values, tick format, and tick padding."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Function arguments:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["yAxisParams: An object that contains various parameters related to the y-axis of the chart. It has the following properties:","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"yMinMaxValues: An object that contains the start and end values of the y-axis."}),"\n",(0,a.jsx)(t.li,{children:"yAxisElement: The DOM element that represents the y-axis."}),"\n",(0,a.jsx)(t.li,{children:"yMaxValue: The maximum value of the y-axis."}),"\n",(0,a.jsx)(t.li,{children:"yMinValue: The minimum value of the y-axis."}),"\n",(0,a.jsx)(t.li,{children:"containerHeight: The height of the container that holds the chart."}),"\n",(0,a.jsx)(t.li,{children:"containerWidth: The width of the container that holds the chart."}),"\n",(0,a.jsx)(t.li,{children:"margins: An object that contains the margins of the chart."}),"\n",(0,a.jsx)(t.li,{children:"tickPadding: The padding between the ticks and the axis line."}),"\n",(0,a.jsx)(t.li,{children:"maxOfYVal: The maximum value of the y-axis for area chart and Grouped vertical bar chart."}),"\n",(0,a.jsx)(t.li,{children:"yAxisTickFormat: The format of the y-axis tick labels."}),"\n",(0,a.jsx)(t.li,{children:"yAxisTickCount: The number of ticks on the y-axis."}),"\n",(0,a.jsx)(t.li,{children:"eventAnnotationProps: An object that contains the properties of the event annotation."}),"\n",(0,a.jsx)(t.li,{children:"eventLabelHeight: The height of the event label."}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.li,{children:"isRtl: A boolean value that indicates whether the chart is in right-to-left mode."}),"\n",(0,a.jsx)(t.li,{children:"axisData: An object that contains the data related to the axis of the chart."}),"\n",(0,a.jsx)(t.li,{children:"useSecondaryYScale: A boolean value that indicates whether to use a secondary y-axis scale."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The function first extracts the necessary parameters from the\xa0yAxisParams\xa0object, such as the\xa0yMinMaxValues, yAxisElement, containerHeight, and containerWidth. It then calculates the final maximum and minimum values for the y-axis, based on the\xa0maxOfYVal, yMaxValue, and yMinValue\xa0parameters."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The function then prepares the datapoints for the y-axis using the\xa0prepareDatapoints\xa0function, which calculates the tick values based on the maximum and minimum values of the y-axis. It then creates a linear scale for the y-axis using the\xa0d3ScaleLinear\xa0function from the\xa0d3-scale\xa0library."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The function then creates the y-axis using the\xa0d3AxisLeft\xa0or\xa0d3AxisRight\xa0function from the\xa0d3-axis\xa0library, depending on the\xa0isRtl and useSecondaryYScale\xa0parameters. It sets the tick padding, tick values, and tick size for the y-axis, and formats the tick labels using the\xa0yAxisTickFormat\xa0parameter."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"Finally, the function uses the d3Select function to select the\xa0yAxisElement\xa0and apply the y-axis to it using the call method. It also sets the aria-hidden attribute of the y-axis text elements to true to improve accessibility."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"createStringYAxis():"}),"\xa0In the Vertical bar chart component, the\xa0d3-axis\xa0module is used to create and customize the y-axis of a vertical bar chart. The\xa0createStringYAxis\xa0function is responsible for creating the y-axis that use string values for the y-axis using the\xa0createStringYAxisForOtherCharts\xa0function. The function takes in several parameters, including\xa0yAxisParams, dataPoints, and isRtl. These parameters are used to customize the y-axis, such as setting the tick values, tick format, and tick padding."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Function arguments:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"yAxisParams: An object that contains the parameters for the y-axis, including\xa0containerHeight,\xa0tickPadding,\xa0margins,\xa0yAxisTickFormat,\xa0yAxisElement, and\xa0yAxisPadding."}),"\n",(0,a.jsx)(t.li,{children:"dataPoints: An array of strings that represent the data points for the y-axis."}),"\n",(0,a.jsx)(t.li,{children:"isRtl: A boolean value that indicates whether the chart is in right-to-left mode."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The function first extracts the necessary parameters from the\xa0yAxisParams\xa0object, such as the\xa0containerHeight,\xa0margins,\xa0yAxisTickFormat,\xa0yAxisElement, and\xa0yAxisPadding. It then creates a band scale for the y-axis using the\xa0d3ScaleBand\xa0function from the\xa0d3-scale\xa0library."}),"\n",(0,a.jsx)(t.li,{children:"The band scale is defined using the\xa0dataPoints\xa0array as the domain, and the\xa0containerHeight\xa0and\xa0margins\xa0parameters as the range. The\xa0padding\xa0method is used to set the padding between the bands in the y-axis."}),"\n",(0,a.jsx)(t.li,{children:"The function then creates the y-axis using the\xa0d3AxisLeft\xa0or\xa0d3AxisRight\xa0function from the\xa0d3-axis\xa0library, depending on the\xa0isRtl\xa0parameter. It sets the tick padding, tick values, and tick size for the y-axis, and formats the tick labels using the\xa0yAxisTickFormat\xa0parameter."}),"\n",(0,a.jsx)(t.li,{children:"Finally, the function uses the\xa0d3Select\xa0function to select the\xa0yAxisElement\xa0and apply the y-axis to it using the\xa0call\xa0method. It also selects all the text elements of the y-axis and returns the y-axis scale."}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"Bars:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"_createBar():"}),"\xa0This method is responsible for creating and rendering the bars of the chart."]}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Function arguments:"}),"\nThe\xa0_createBar\xa0function takes four arguments:"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"xBarScale: This is a scaling function that maps the x-axis data points to the corresponding x-axis positions on the chart. The type of this argument is\xa0any, which means that it can be any type of scaling function."}),"\n",(0,a.jsx)(t.li,{children:"yBarScale: This is a scaling function that maps the y-axis data points to the corresponding y-axis positions on the chart. The type of this argument is\xa0NumericScale, which is a custom type defined elsewhere in the code."}),"\n",(0,a.jsx)(t.li,{children:"containerHeight: This is the height of the container element that holds the chart. This is used to calculate the y-axis position of the bars."}),"\n",(0,a.jsx)(t.li,{children:"xElement: This is an SVG element that represents the x-axis of the chart. This is used to calculate the x-axis position of the bars."}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The method takes several arguments, including the x and y scales, the container height and width, and an SVG element for the x-axis. It first checks whether the chart has any line data and whether to focus on the whole stack or not."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The method then iterates over each item in the chart data and calculates the x and y coordinates for each bar using the scales and the bar width. It also calculates the height of each bar based on the data and the y scale. If the bar height is less than the minimum bar height, it sets the height to the minimum bar height."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"For each bar, the method creates a rectangle element using the\xa0rect\xa0SVG element and sets the x, y, width, height, fill, and other properties. It also adds an\xa0onMouseOver,\xa0onMouseMove,\xa0onMouseLeave,\xa0onFocus,\xa0onBlur, and\xa0onClick\xa0event listener for the bar if the legend is selected."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"If the bar has a corner radius and is the last bar in the stack, it creates a path element using the\xa0path\xa0SVG element and sets the\xa0d, fill, and other properties. It also adds an\xa0onMouseOver,\xa0onMouseMove,\xa0onMouseLeave,\xa0onFocus,\xa0onBlur, and\xa0onClick\xa0event listener for the path if the legend is selected."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The method then creates a group element using the\xa0g\xa0SVG element and adds the rectangle and path elements to the group. It also adds an\xa0onMouseOver,\xa0onMouseMove,\xa0onMouseLeave,\xa0onFocus,\xa0onBlur, and\xa0onClick\xa0event listener for the group if the legend is selected."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"Finally, the method returns the bars as a React fragment."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Numeric bars (_createNumericBars()):"}),"\xa0This method is responsible for creating and rendering the numeric bars of the chart."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Function arguments:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"containerHeight\xa0(number): The height of the container in which the chart is rendered."}),"\n",(0,a.jsx)(t.li,{children:"containerWidth\xa0(number): The width of the container in which the chart is rendered."}),"\n",(0,a.jsx)(t.li,{children:"xElement\xa0(SVGElement): The SVG element that represents the x-axis of the chart."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The method takes several arguments, including the container height and width, and an SVG element for the x-axis. It first gets the x and y bar scales using the _getScales method with the numeric parameter set to true."}),"\n",(0,a.jsx)(t.li,{children:"The method then calls the _createBar method with the x and y bar scales, container height, and x-axis element as arguments. The _createBar method is responsible for creating and rendering the bars of the chart."}),"\n",(0,a.jsx)(t.li,{children:"The _createBar method creates a rectangle element for each bar using the rect SVG element and sets the x, y, width, height, fill, and other properties. It also adds event listeners for the bar if the legend is selected."}),"\n",(0,a.jsx)(t.li,{children:"The _createBar method then creates a group element using the g SVG element and adds the rectangle elements to the group. It also adds event listeners for the group if the legend is selected."}),"\n",(0,a.jsx)(t.li,{children:"Finally, the _createBar method returns the bars as a React fragment."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Overall, the _createNumericBars method is responsible for creating and rendering the numeric bars of the chart by calling the _createBar method with the appropriate scales and arguments. The _createBar method is responsible for creating and rendering the bars of the chart using the rect and g SVG elements and adding event listeners for interactivity."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"String bars (_createStringBars()):"}),"\xa0This method is responsible for creating and rendering the string bars of the chart."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Function arguments:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"containerHeight\xa0(number): The height of the container in which the chart is rendered."}),"\n",(0,a.jsx)(t.li,{children:"containerWidth\xa0(number): The width of the container in which the chart is rendered."}),"\n",(0,a.jsx)(t.li,{children:"xElement\xa0(SVGElement): The SVG element that represents the x-axis of the chart."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The method takes several arguments, including the container height and width, and an SVG element for the x-axis. It first gets the x and y bar scales using the _getScales method with the numeric parameter set to false."}),"\n",(0,a.jsx)(t.li,{children:"The method then calls the _createBar method with the x and y bar scales, container height, and x-axis element as arguments. The _createBar method is responsible for creating and rendering the bars of the chart."}),"\n",(0,a.jsx)(t.li,{children:"The _createBar method creates a rectangle element for each bar using the rect SVG element and sets the x, y, width, height, fill, and other properties. It also adds event listeners for the bar if the legend is selected."}),"\n",(0,a.jsx)(t.li,{children:"The _createBar method then creates a group element using the g SVG element and adds the rectangle elements to the group. It also adds event listeners for the group if the legend is selected."}),"\n",(0,a.jsx)(t.li,{children:"Finally, the _createBar method returns the bars as a React fragment."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Overall, the _createStringBars method is responsible for creating and rendering the string bars of the chart by calling the _createBar method with the appropriate scales and arguments. The _createBar method is responsible for creating and rendering the bars of the chart using the rect and g SVG elements and adding event listeners for interactivity."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"Lines:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"_createLines():"}),"\xa0This method is responsible for creating and rendering the lines and dots of the chart."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Function arguments:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"xScale: A\xa0NumericScale\xa0object that represents the scale for the x-axis of the chart."}),"\n",(0,a.jsx)(t.li,{children:"yScale: A\xa0NumericScale\xa0object that represents the scale for the y-axis of the chart."}),"\n",(0,a.jsx)(t.li,{children:"containerHeight: A number that represents the height of the container that holds the chart."}),"\n",(0,a.jsx)(t.li,{children:"containerWidth: A number that represents the width of the container that holds the chart."}),"\n",(0,a.jsx)(t.li,{children:"secondaryYScale: An optional\xa0NumericScale\xa0object that represents the scale for the secondary y-axis of the chart. This argument is only used if the chart has a secondary y-axis."}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The method takes several arguments, including the x and y scales, the container height and width, and an optional secondary y scale. It first checks whether the x-axis is numeric or not and gets the scales using the\xa0_getScales\xa0method."}),"\n",(0,a.jsx)(t.li,{children:"The method then gets the formatted line data using the\xa0_getFormattedLineData\xa0method and iterates over each item in the line object. For each item, it checks whether the legend is highlighted or not and iterates over each point in the line. It calculates the x and y coordinates for each point using the scales and whether to use the secondary y scale or not."}),"\n",(0,a.jsx)(t.li,{children:"If the line border width is greater than zero, it creates a line element for the border of the line using the\xa0line\xa0SVG element. It then creates a line element for the line itself using the same\xa0line\xa0SVG element and adds an\xa0onMouseOver\xa0and\xa0onMouseLeave\xa0event listener if the legend is selected."}),"\n",(0,a.jsx)(t.li,{children:"Finally, it creates a circle element for each point in the line using the\xa0circle\xa0SVG element and adds an\xa0onMouseOver\xa0and\xa0onMouseLeave\xa0event listener if the legend is selected. It sets the radius and visibility of the circle based on the legend and x-axis point."}),"\n",(0,a.jsx)(t.li,{children:"The method returns the border lines, lines, and dots as a React fragment."}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"Legends:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"_getLegendData():"}),"\xa0This method is responsible for creating and rendering the legend of the chart."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Function arguments:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"data: an array of IVerticalStackedChartProps objects, which contain the chart data to be displayed."}),"\n",(0,a.jsx)(t.li,{children:"palette: an object of type IPalette that contains a set of colors to be used for the chart."}),"\n",(0,a.jsx)(t.li,{children:"lineLegends: an array of LineLegends objects, which contain the legend data for any lines that are displayed on the chart."}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The method takes several arguments, including the chart data, the color palette, and an array of line legends. It first checks whether the legend should be hidden or not based on the\xa0hideLegend\xa0prop."}),"\n",(0,a.jsx)(t.li,{children:"The method then iterates over each item in the chart data and creates a legend for each unique legend title and color combination. It generates a random color from the default palette if the point does not have a color. It also checks whether there are any similar legends already created and skips the creation if there are."}),"\n",(0,a.jsx)(t.li,{children:"For each legend, the method creates an object with the legend title, color, and event listeners for click, hover, and mouse out actions. It adds the legend object to an array of actions."}),"\n",(0,a.jsx)(t.li,{children:"If there are any line legends, the method iterates over each item in the line legends and creates a legend object with the title, color, and event listeners. It adds the legend object to an array of line legends."}),"\n",(0,a.jsx)(t.li,{children:"The method then concatenates the arrays of actions and line legends and creates a\xa0Legends\xa0component with the resulting array of legends. It also passes any additional props for the\xa0Legends\xa0component."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Overall, the\xa0_getLegendData\xa0method is responsible for creating and rendering the legend of the chart by iterating over the chart data and line legends and creating legend objects with event listeners. It then passes the resulting array of legends to a\xa0Legends\xa0component for rendering."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"Callouts:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"_renderCallout():"}),"\xa0This method is responsible for rendering the callout for a data point when it is hovered over."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The method takes an optional\xa0IVSChartDataPoint\xa0object as an argument, which contains the data for the hovered data point. If the argument is not provided, the method returns\xa0null."}),"\n",(0,a.jsx)(t.li,{children:"If the argument is provided, the method creates a\xa0ChartHoverCard\xa0component with the\xa0XValue, Legend, YValue, color, and culture\xa0props set to the corresponding values from the\xa0IVSChartDataPoint\xa0object. The\xa0ChartHoverCard\xa0component is responsible for rendering the callout with the data for the hovered data point."}),"\n",(0,a.jsx)(t.li,{children:"Finally, the method returns the\xa0ChartHoverCard\xa0component."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Overall, the\xa0_renderCallout\xa0method is responsible for rendering the callout for a data point when it is hovered over by creating a\xa0ChartHoverCard\xa0component with the data for the hovered data point."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"_getCustomizedCallout():"}),"\xa0This method is responsible for rendering the callout for a data point or stack when it is hovered over."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The method first checks whether the chart has any line data by iterating over the chart data and checking whether each item has a\xa0lineData\xa0property with a length greater than zero. If the chart has any line data, it sets a boolean variable\xa0_isHavingLines\xa0to\xa0true."}),"\n",(0,a.jsx)(t.li,{children:"The method then checks whether the\xa0onRenderCalloutPerStack\xa0prop is defined. If it is defined, the method calls the\xa0onRenderCalloutPerStack\xa0function with the\xa0stackCalloutProps\xa0object as an argument. The\xa0stackCalloutProps\xa0object contains the data for the hovered stack."}),"\n",(0,a.jsx)(t.li,{children:"If the\xa0onRenderCalloutPerStack\xa0prop is not defined, the method checks whether the\xa0onRenderCalloutPerDataPoint\xa0prop is defined and whether the chart has any line data. If the\xa0onRenderCalloutPerDataPoint\xa0prop is defined and the chart does not have any line data, the method calls the\xa0onRenderCalloutPerDataPoint\xa0function with the\xa0dataPointCalloutProps\xa0object and the\xa0_renderCallout\xa0method as arguments. The\xa0dataPointCalloutProps\xa0object contains the data for the hovered data point."}),"\n",(0,a.jsx)(t.li,{children:"If neither the\xa0onRenderCalloutPerStack\xa0nor the\xa0onRenderCalloutPerDataPoint\xa0prop is defined, the method returns\xa0null."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Overall, the\xa0_getCustomizedCallout\xa0method is responsible for rendering the callout for a data point or stack when it is hovered over by calling the appropriate\xa0onRenderCallout\xa0function with the corresponding data. If neither\xa0onRenderCallout\xa0function is defined, the method returns\xa0null."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"Rendering details"}),"\nThe Vertical stacked bar chart uses d3 SVG based rendering, which follows the following render cycles:","\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:"- Invocation cycle: Vertical stacked bar Chart -> Cartesian base chart -> X-axis -> X-axis labels -> Y-axis -> Y-axis labels -> bars, legends, callouts\n- Rendering cycle: Vertical stacked bar chart <- Bars (rect), lines (line), Legends, Callouts <- Axes (d3.axis, d3.scale)\n"})}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Following are the rendering details:"})}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsx)(t.li,{children:"The Vertical stacked bar chart component defines a class component that renders a vertical stacked bar chart. The chart can be either numeric or categorical, depending on the type of data passed in. The chart is rendered using\xa0SVG\xa0elements."}),"\n",(0,a.jsx)(t.li,{children:"The component has several private methods that are used to create the chart. The\xa0_getScales\xa0method is used to create the x and y scales for the chart. The\xa0_createNumericBars\xa0and\xa0_createStringBars\xa0methods are used to create the bars for the chart. The\xa0_getGraphData\xa0method is used to get the data for the chart. The\xa0_getAxisData\xa0method is used to get the data for the y-axis."}),"\n",(0,a.jsx)(t.li,{children:"The component also has several private variables that are used to calculate the margins and bar width for the chart. The\xa0_domainMargin\xa0variable is used to calculate the margin for the x-axis. The\xa0_barWidth\xa0variable is used to calculate the width of the bars in the chart."}),"\n",(0,a.jsx)(t.li,{children:"The component also has several private methods that are used to handle user interactions with the chart. The\xa0_legendHighlighted\xa0method is used to check if a legend is highlighted. The\xa0_noLegendHighlighted\xa0method is used to check if no legend is highlighted. The\xa0_getAriaLabel\xa0method is used to get the aria label for the chart."}),"\n",(0,a.jsx)(t.li,{children:"Finally, the component has a render method that renders the chart using\xa0SVG\xa0elements. The chart is rendered as a series of stacked bars, with each bar representing a category or value. The chart also includes a legend and a callout that displays additional information about the data point when the user hovers over it."}),"\n"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Variants"}),"\nFollowing are the variants of vertical bar chart:\xa0",(0,a.jsx)(t.a,{href:"https://developer.microsoft.com/en-us/fluentui#/controls/web/verticalbarchart/verticalstackedbarchart",children:"Ref8"}),"\xa0"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.em,{children:"Basic Vertical stacked bar Chart"}),": Only basic props are provided."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.em,{children:"Custom Callout"}),": Can show customized callout data."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.em,{children:"Custom Accessibility"}),": Providing custom aria labels."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.em,{children:"Styled"}),": Can show bars with a single callout or a stacked callout."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.em,{children:"Tooltip"}),": Can show tooltip over x-axis ticks."]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Testing"}),"\nThe manual tests for Vertical stacked bar chart has been completed and the component tests are in PR. Following is the improvement in code coverage:\n",(0,a.jsx)(t.img,{alt:"VerticalStackedBarChart3.png",src:n(9845).Z+"",width:"2477",height:"538"})]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["Component Tests:","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["Work item ",(0,a.jsx)(t.a,{href:"https://uifabric.visualstudio.com/iss/_workitems/edit/7439",children:"7439"})]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["Unit Tests:","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["Work item ",(0,a.jsx)(t.a,{href:"https://uifabric.visualstudio.com/iss/_workitems/edit/7440",children:"7440"})]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["Manual Tests:","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["Work item ",(0,a.jsx)(t.a,{href:"https://uifabric.visualstudio.com/iss/_workitems/edit/8602",children:"8602"})]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["Accessibility Tests:","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["Work item ",(0,a.jsx)(t.a,{href:"https://uifabric.visualstudio.com/iss/_workitems/edit/7438",children:"7438"})]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Accessibility"}),"\nFAST pass checks resulted in no error for Vertical stacked bar chart. Link to the ",(0,a.jsx)(t.a,{href:"https://accessibilityinsights.io/docs/web/getstarted/fastpass/",children:"FAST pass tool"}),"\nOur charts have elaborate accessibility support. The charts are WCAG 2.1 MAS C compliant for accessibility.\nConsumers can define their own aria labels for each point by setting the\xa0callOutAccessibilityData\xa0properties."]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Theming"}),'\nThe palette for donut chart is set from the "theme" prop as passed to the component during rendering. Both light and dark themes are supported and users can create there own theme too.\xa0',(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/wiki/Theming",children:"Ref3"}),"\xa0\xa0and\xa0",(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/wiki/How-to-apply-theme-to-Fluent-UI-React-components",children:"Ref4"}),"\xa0\xa0explains theming in detail."]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Debugging"}),"\nThe detailed steps on debugging has been given in\xa0",(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui-charting-contrib/blob/main/docs/Debugging.md",children:"Debugging"}),"."]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Error scenarios"}),"\nThe Vertical stacked bar chart handles the following error scenario:"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"Empty data: If the data passed to the chart component is empty, the chart will not render and a message will be narrated to the user.\xa0_isChartEmpty\xa0functions handles that scenario."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Localization aspects"}),"\nThe component has a\xa0culture\xa0prop, which is used to set the culture for the chart. This prop is used to format the x-axis labels and the callout values based on the specified culture. Currently, vertical bar chart provides localization only for the x-axis ticks if they are numbers."]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Some notable PRs and their brief description"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/12308",children:"Added the vertical stacked bar chart component"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/commit/f986d68c3fad2ff4034ebb86fd4618df11d81221",children:"Vertical stacked bar chart code refactor. Cartesian chart implemented in base file"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/16914",children:"Accessibility: narrator issues fixed in bar charts"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/17571",children:"Accessibility: Callout dismiss on ESC issue solved in all bar charts"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/19072",children:"Accessibility change for Vertical Stacked Bar chart"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/28594",children:"Adding component tests for Vertical Stacked Bar chart."})}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Future improvements"}),"\nFollowing are the future improvements that can be incorporated in vertical stacked bar charts:"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"Add support for animations: Animations can make the chart more engaging and help to highlight changes in the data over time. Adding support for animations would require using a library such as d3-transition."}),"\n",(0,a.jsx)(t.li,{children:"Add support for multiple data sets: Currently, the chart only supports a single data set. Adding support for multiple data sets would allow the user to compare different sets of data on the same chart. For example: grouped vertical stacked bar chart."}),"\n",(0,a.jsx)(t.li,{children:"Improve accessibility: The chart could be made more accessible by adding support for keyboard navigation. This would require adding additional attributes to the chart elements and updating the event handlers accordingly."}),"\n",(0,a.jsxs)(t.li,{children:["Following error handling scenarios can be improved:","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"Invalid or missing chart dimensions: If the dimensions of the chart are invalid or missing, the chart will not render and a message will be displayed to the user."}),"\n",(0,a.jsx)(t.li,{children:"Invalid or missing axis parameters: If the parameters for the x-axis or y-axis are invalid or missing, the chart will not render and a message will be displayed to the user."}),"\n",(0,a.jsx)(t.li,{children:"Invalid or missing legends: If the legends for the chart are invalid or missing, the chart will not render and a message will be displayed to the user."}),"\n",(0,a.jsx)(t.li,{children:"Invalid bar width: If the bar width for the chart is invalid, the chart will not render and a message will be displayed to the user."}),"\n",(0,a.jsx)(t.li,{children:"Invalid or missing data for callout: If the data for the callout is invalid or missing, the callout will not render and a message will be displayed to the user."}),"\n",(0,a.jsx)(t.li,{children:"Invalid or missing accessibility data: If the accessibility data for the chart is invalid or missing, the chart will not render and a message will be displayed to the user."}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.li,{children:"Localization support can be improved for all strings and numbers."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Interactions"}),"\nFollowing are the interactions that are allowed for vertical stacked bar chart:"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.em,{children:"Mouse Events"}),":\na. Hover mouse over a stacked bar, should call the corresponding handler and show the callout containing information about all the bars stacked over that bar.\nb. On mouse move on stacked Bar 1 (step 1) -> mouse leave (step 2) -> mouse move on stacked Bar 2 (step 3), should render the callout of the stacked Bar 2.\nc. On mouse over, callout should be defined, on mouse leave, callout should disappear.\nd. On mouse over on legends, should highlight the corresponding bar/line.\nf. On click on stacked Bar, should highlight the corresponding entire stacked bar.\ng. On mouse over a bar legend, should highlight all the bars of that type on all the stacked bars.\ng. On mouse out after mouse over on first legend, should have opacity 0.1 for second bar initially (during mouseOver on first legend) and opacity set to 1 for both the bars on mouse out."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.em,{children:"Keyboard Events"}),":\na. On focus on a bar, should render the corresponding callout.\nb. On focus on a line, should highlight the corresponding line and its legend."]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Learnings"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"While implementing the tests using react testing library, it was found that certain browser functions like\xa0getComputedTextLength()\xa0cannot be unit tested and needs to be tested End-to-End only."}),"\n",(0,a.jsx)(t.li,{children:"Order of imports are important.\nFor example: for Vertical bar charts tests, improper sequencing of the imports (data first and then render) results in incorrect and incopmlete rendering of charts:"}),"\n"]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:"import { chartPoints } from '../VerticalBarChart/VerticalBarChart.test';\nimport { render, screen, queryAllByAttribute, fireEvent, act } from '@testing-library/react';\n"})}),"\n",(0,a.jsx)(t.p,{children:"However, the following results in correct rendering:"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:"import { render, screen, queryAllByAttribute } from '@testing-library/react';\n\nimport { chartPoints } from './VerticalBarChart.test';\n"})}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"Certain props need async await structure (waitFor in react testing library) for different props or nested SVGs to render."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Design figma"}),"\nVertical Stacked Bar Chart Figma -\xa0",(0,a.jsx)(t.a,{href:"https://www.figma.com/file/WOoCs0CmNYZhYl9xXeCGpi/Data-viz-(Archive)?type=design&node-id=21153-80197&mode=design&t=kjtgBpG3tOGCcx00-0",children:"Link"}),"\xa0"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Known issues"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"Setting the margins externally via the props may cut the x and y ticks if the margins provided are very less. Setting a minimum margin would prevent any such distortions."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Performance"}),"\nThe performance aspect of a vertical stacked bar chart refers to how efficiently and effectively it conveys information to the viewer. Here are some key considerations regarding the performance of a line chart:"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"Data Visualization Efficiency"}),"\n",(0,a.jsx)(t.li,{children:"Clarity and Simplicity"}),"\n",(0,a.jsx)(t.li,{children:"Responsiveness"}),"\n",(0,a.jsx)(t.li,{children:"Handling Large Datasets"}),"\n",(0,a.jsx)(t.li,{children:"Interactive Features"}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"References"})}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/d3/d3-scale/blob/main/README.md",children:"D3-scale"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/d3/d3-selection/blob/main/README.md",children:"D3-selection"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/d3/d3-array/blob/main/README.md",children:"D3-array"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/d3/d3-axis/blob/main/README.md",children:"D3-axis"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/wiki/How-to-apply-theme-to-Fluent-UI-React-components",children:"How to apply theme"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/wiki/Theming",children:"Theming"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://developer.microsoft.com/en-us/fluentui#/controls/web/verticalbarchart/verticalstackedbarchart",children:"Vertical Stacked Bar Chart"})}),"\n"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"Appendix"}),"\nThe mathematical formulae used in the Vertical Stacked bar chart component are as follows:"]}),"\n"]}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsx)(t.li,{children:"Formula for calculating the\xa0yBarScale\xa0using\xa0d3ScaleLinear:"}),"\n"]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:"yBarScale = d3ScaleLinear()\n\n.domain([0, yMax])\n\n.range([0, containerHeight - margins.bottom! - margins.top!])\n"})}),"\n",(0,a.jsxs)(t.ol,{start:"2",children:["\n",(0,a.jsx)(t.li,{children:"Formula for calculating the\xa0xBarScale\xa0for numeric data using\xa0d3ScaleLinear:"}),"\n"]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:"xMax = d3Max(this.\\_dataset, (point: IDataPoint) => point.x as number)!\n\nxMin = d3Min(this.\\_dataset, (point: IDataPoint) => point.x as number)!\n\nxBarScale = d3ScaleLinear()\n\n.domain(this.\\_isRtl ? [xMax, xMin] : [xMin, xMax])\n\n.nice()\n\n.range([\n\n` `margins.left! + \\_domainMargin,\n\n` `containerWidth - margins.right! - \\_barWidth - \\_domainMargin,\n\n` `])\n"})}),"\n",(0,a.jsxs)(t.ol,{start:"3",children:["\n",(0,a.jsx)(t.li,{children:"Formula for calculating the\xa0xBarScale\xa0for categorical data using\xa0d3ScaleBand:"}),"\n"]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:"xBarScale = d3ScaleBand()\n\n.domain(\\_xAxisLabels)\n\n.range([margins.left! + \\_domainMargin, containerWidth - margins.right! - \\_domainMargin])\n\n.paddingInner(2 / 3)\n"})}),"\n",(0,a.jsxs)(t.ol,{start:"4",children:["\n",(0,a.jsx)(t.li,{children:"Formula for calculating the height of each bar in the chart:"}),"\n"]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:"barHeight = heightValueScale \\* point.data;\n\nWhen displaying gaps between the bars, the height of each bar is adjusted so that the total of all bars is not changed by the gaps\n\ntotalData = bars.reduce((iter, value) => iter + value.data, 0)\n\ntotalHeight = defaultTotalHeight ?? yBarScale(totalData)\n\ngaps = barGapMax && bars.length - 1\n\ngapHeight = gaps && Math.max(barGapMin, Math.min(barGapMax, (totalHeight \\* barGapMultiplier) / gaps))\n\nheightValueScale = (totalHeight - gapHeight \\* gaps) / totalData\n\nif (barHeight < barMinimumHeight) {\n\n` `barHeight = barMinimumHeight\n\n}\n\nDefault values:\n\nbarGapMax = props.barGapMax (default value = 0)\n\nWhen displaying gaps between bars, the max height of the gap is given in the props. The actual gap is calculated with this multiplier, with a minimum gap of 1 pixel.\n\nbarGapMin = 1\n\nbarGapMultiplier = 0.2\n"})}),"\n",(0,a.jsxs)(t.ol,{start:"5",children:["\n",(0,a.jsx)(t.li,{children:"Formula for calculating the x position of each bar in the chart:"}),"\n"]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:"x = xBarScale(bar.category) + (this.\\_barWidth / 2)\n"})}),"\n",(0,a.jsx)(t.hr,{})]})}function d(e={}){const{wrapper:t}={...(0,i.a)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},4757:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/VSBC1-de2ee9ef0194f703abc7f8806bc869e7.png"},3160:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/VSBC2-3decd6986a55117047292cb20444e7c1.png"},9845:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/VSBC3-01489e0f79d82ab97318b9dc49952bae.png"},1151:(e,t,n)=>{n.d(t,{Z:()=>h,a:()=>r});var a=n(7294);const i={},s=a.createContext(i);function r(e){const t=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function h(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),a.createElement(s.Provider,{value:t},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/b7f64af1.7bb0cce2.js b/assets/js/b7f64af1.7bb0cce2.js
deleted file mode 100644
index a0e9d0da31..0000000000
--- a/assets/js/b7f64af1.7bb0cce2.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[8751],{4622:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>r,default:()=>d,frontMatter:()=>s,metadata:()=>h,toc:()=>l});var a=n(5893),i=n(1151);const s={},r="Contributor guide: Vertical Stacked Bar Chart",h={id:"Charting-Concepts/VerticalStackedBarChart",title:"Contributor guide: Vertical Stacked Bar Chart",description:"VerticalStackedBarChart1.png",source:"@site/../../docs/Charting-Concepts/VerticalStackedBarChart.md",sourceDirName:"Charting-Concepts",slug:"/Charting-Concepts/VerticalStackedBarChart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/VerticalStackedBarChart",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Contributor guide: Vertical Bar Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/VerticalBarChart"},next:{title:"Debugging",permalink:"/fluentui-charting-contrib/docs/Debugging"}},o={},l=[];function c(e){const t={a:"a",code:"code",em:"em",h1:"h1",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.h1,{id:"contributor-guide-vertical-stacked-bar-chart",children:"Contributor guide: Vertical Stacked Bar Chart"}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"VerticalStackedBarChart1.png",src:n(4757).Z+"",width:"1207",height:"781"})}),"\n",(0,a.jsx)(t.p,{children:"A vertical stacked bar chart is a type of chart that displays multiple series of data as stacked bars, with each bar representing a category. The bars are stacked on top of each other, with the height of each bar representing the total value of the series at that category."}),"\n",(0,a.jsx)(t.p,{children:"In a vertical stacked bar chart, the x-axis represents the categories, while the y-axis represents the values of the series. Each bar is divided into segments, with each segment representing a different series. The segments are colored differently to differentiate between the series."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"Use cases"}),"\nHere are some common use cases for a vertical stacked bar chart:","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"Comparing the total size of different categories over time"}),"\n",(0,a.jsx)(t.li,{children:"Analyzing the composition of a whole category into subcategories"}),"\n",(0,a.jsx)(t.li,{children:"Identifying trends in the distribution of data over time"}),"\n",(0,a.jsx)(t.li,{children:"Comparing the relative sizes of different categories at a single point in time"}),"\n",(0,a.jsx)(t.li,{children:"Highlighting the contribution of each subcategory to the whole category"}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.strong,{children:"Mathematical/Geometrical concepts"})}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"VerticalStackedBarChart2.png",src:n(3160).Z+"",width:"1128",height:"753"})}),"\n",(0,a.jsx)(t.p,{children:"The major D3 functions that are involved in the creation of Vertical bar charts are:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"d3-scale:"}),"\nThe\xa0d3-scale\xa0module is a part of the d3 library, which is a collection of JavaScript functions that are used for data visualization. The\xa0d3-scale\xa0module provides several functions for creating and manipulating scales, which are used to map data values to visual properties, such as\xa0position, size, and color."]}),"\n",(0,a.jsx)(t.p,{children:"The\xa0d3-scale\xa0module includes several scale types, including linear, logarithmic, power, and time scales. These scales are used to map continuous data values to a continuous range of visual properties. The module also includes ordinal and band scales, which are used to map categorical data values to a discrete range of visual properties."}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"The\xa0d3-scale\xa0module provides several functions for creating and manipulating scales, including\xa0scaleLinear, scaleLog, scalePow, scaleTime, scaleOrdinal, and scaleBand. These functions take one or more arguments that define the domain and range of the scale, as well as any additional properties, such as the number of ticks or the padding between bands."}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Application in Vertical Stacked bar chart:"}),"\nIn the Vertical Stacked Bar Chart, d3-scale is used to create scales for the x and y axes of the chart. The d3-scale library provides a set of functions for creating different types of scales, such as linear, logarithmic, and ordinal scales. Here, the d3-scale library is used to create a linear scale for the y-axis of the chart."]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"d3.scaleLinear()"}),": The\xa0d3ScaleLinear\xa0is a function from the\xa0d3-scale\xa0module that is used to create a linear scale for the y-axis of the chart. The linear scale maps a continuous domain of data values to a continuous range of visual properties, such as position or height. The\xa0d3ScaleLinear\xa0function takes no arguments and returns a new linear scale. The scale can be customized using several methods, including\xa0domain, range, clamp, and nice. The\xa0domain\xa0method sets the domain of the scale, which is the range of data values that the scale maps to the range of visual properties. The\xa0range\xa0method sets the range of the scale, which is the range of visual properties that the scale maps to the domain of data values."]}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Application in Vertical Stacked bar chart:"}),"\nIn Vertical stacked bar chart,\xa0d3.scaleLinear()\xa0is used to create a linear scale for the y-axis of the chart."]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"A linear scale is a mapping function that maps a continuous input domain to a continuous output range. In this case, the input domain is the range of data values to be plotted on the y-axis, and the output range is the range of pixel values available for the y-axis on the chart."}),"\n",(0,a.jsx)(t.li,{children:"The\xa0scaleLinear()\xa0method of the\xa0d3\xa0library returns a new linear scale function. This function can be used to map data values to pixel values on the y-axis of the chart."}),"\n",(0,a.jsx)(t.li,{children:"To create the scale, the\xa0domain()\xa0method is used to set the minimum and maximum values of the data array as the input domain. The\xa0range()\xa0method is used to set the height of the chart minus the top and bottom margins as the output range."}),"\n",(0,a.jsx)(t.li,{children:"The resulting\xa0yScale\xa0function can then be used to map data values to pixel values on the y-axis of the chart."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"d3.scaleBand():"}),"\xa0The\xa0d3ScaleBand\xa0is a function from the\xa0d3-scale\xa0module that is used to create a band scale for the x-axis of the chart. The band scale maps a discrete domain of data values to a discrete range of visual properties, such as\xa0position or width. The\xa0d3ScaleBand\xa0function takes no arguments and returns a new band scale. The scale can be customized using several methods, including\xa0domain, range, padding, and align. The\xa0domain\xa0method sets the domain of the scale, which is the range of data values that the scale maps to the range of visual properties. The\xa0range\xa0method sets the range of the scale, which is the range of visual properties that the scale maps to the domain of data values. The\xa0padding\xa0method sets the padding between the bands of the scale, which determines the width of the bands. The\xa0align\xa0method sets the alignment of the bands within the range of the scale."]}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Application in Vertical Stacked bar chart:"}),"\nIn the vertical stacked bar chart,\xa0d3.scaleBand()\xa0is used to create a band scale for the x-axis of the chart."]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"A band scale is a mapping function that maps a discrete input domain to a continuous output range. In this case, the input domain is an array of discrete values to be plotted on the x-axis, and the output range is the range of pixel values available for the x-axis on the chart."}),"\n",(0,a.jsx)(t.li,{children:"The\xa0scaleBand()\xa0method of the\xa0d3\xa0library returns a new band scale function. This function can be used to map data values to pixel values on the x-axis of the chart."}),"\n",(0,a.jsx)(t.li,{children:"To create the scale, the\xa0domain()\xa0method is used to set the array of discrete values as the input domain. The\xa0range()\xa0method is used to set the width of the chart minus the left and right margins as the output range."}),"\n",(0,a.jsx)(t.li,{children:"The\xa0padding()\xa0method can be used to set the padding between the bands in the scale. The\xa0paddingInner()\xa0and\xa0paddingOuter()\xa0methods can be used to set the inner and outer padding, respectively."}),"\n",(0,a.jsx)(t.li,{children:"The resulting\xa0xScale\xa0function can then be used to map data values to pixel values on the x-axis of the chart."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"d3-selection:"}),"\xa0The\xa0d3-selection\xa0is a module from the d3 library that is used to select and manipulate DOM elements in the chart component. The\xa0d3-selection\xa0module provides several functions for selecting and manipulating DOM elements, including\xa0select, selectAll, append, attr, and style. The select function is used to select a single DOM element that matches a given selector. The\xa0selectAll\xa0function is used to select multiple DOM elements that match a given selector. The\xa0append\xa0function is used to append a new DOM element to a selected element. The\xa0attr\xa0function is used to set or get an attribute of a selected element. The\xa0style\xa0function is used to set or get a style property of a selected element."]}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Application in Vertical Stacked bar chart:"}),"\nIn the Vertical stacked bar chart, d3-selection is used to select and manipulate DOM elements in the chart."]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The\xa0d3-selection\xa0library provides various methods for selecting and manipulating DOM elements, such as\xa0select(), selectAll(), append(), and attr(). In this case, the\xa0d3-selection\xa0library is used to select the\xa0svg\xa0element that holds the chart and to create and manipulate the\xa0rect\xa0elements that represent the bars in the chart."}),"\n",(0,a.jsx)(t.li,{children:"To select the\xa0svg\xa0element, the\xa0d3-selection\xa0library's\xa0select()\xa0method is used. This method takes\xa0SVG\xa0node as an argument and returns a new selection object that represents the selected element. The resulting selection object can then be used to manipulate the selected element."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"d3-array:"}),"\xa0The\xa0d3-array\xa0is a module from the d3 library that is used to manipulate arrays of data in the chart component. The\xa0d3-array\xa0module provides several functions for manipulating arrays of data, including\xa0max, min, extent, sum, and mean. The\xa0max\xa0function is used to find the maximum value in an array of data. The\xa0min\xa0function is used to find the minimum value in an array of data. The\xa0extent\xa0function is used to find the minimum and maximum values in an array of data. The\xa0sum\xa0function is used to find the sum of the values in an array of data. The\xa0mean\xa0function is used to find the mean (average) of the values in an array of data."]}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Application in Vertical Stacked bar chart:"}),"\nIn the Vertical stacked bar chart,\xa0d3-array\xa0is used to calculate the minimum and maximum values of the data array."]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The\xa0d3-array\xa0library provides various methods for working with arrays of data, such as\xa0min(),\xa0max(), and\xa0sum(). In this case, the\xa0d3-array\xa0library is used to calculate the minimum and maximum values of the data array."}),"\n",(0,a.jsx)(t.li,{children:"To calculate the minimum and maximum values of the data array, the\xa0d3-array\xa0library's\xa0min()\xa0and\xa0max()\xa0methods are used. These methods take an array of data as an argument and return the minimum and maximum values of the array, respectively."}),"\n",(0,a.jsx)(t.li,{children:"The resulting minimum and maximum values are then used to set the input domain of the y-axis scale created using the\xa0d3-scale\xa0library."}),"\n",(0,a.jsx)(t.li,{children:"Overall, the\xa0d3-array\xa0library is used to calculate the minimum and maximum values of the data array by using the\xa0min()\xa0and\xa0max()\xa0methods. These values are then used to set the input domain of the y-axis scale created using the\xa0d3-scale\xa0library."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"d3-format:"}),"\xa0The\xa0d3-format\xa0is a module from the d3 library that is used to format numbers and strings in the chart component. The\xa0d3-format\xa0module provides several functions for formatting numbers and strings, including\xa0format, formatPrefix, precisionFixed, and precisionRound."]}),"\n",(0,a.jsx)(t.p,{children:"The\xa0format\xa0function is used to format a number or string using a specified format string. The format string can include placeholders for the value, such as\xa0%\xa0for a percentage or\xa0,\xa0for a comma-separated number. The\xa0formatPrefix\xa0function is used to format a number using a prefix notation that rounds the value to a specified precision and appends a prefix, such as k for thousands or M for millions. The\xa0precisionFixed\xa0function is used to format a number using a fixed number of decimal places. The\xa0precisionRound\xa0function is used to format a number using a variable number of decimal places that is determined by the magnitude of the value."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Application in Vertical Stacked bar chart:"}),"\nIn the Vertical stacked bar chart,\xa0d3-format\xa0is used to format the tick values on the y-axis of the chart."]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The\xa0d3-format\xa0library provides various methods for formatting numbers, such as\xa0format(),\xa0formatPrefix(), and\xa0precisionRound(). In this case, the\xa0d3-format\xa0library is used to format the tick values on the y-axis of the chart."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"To format the tick values, the\xa0d3-format\xa0library's\xa0format()\xa0method is used. This method takes a format string as an argument and returns a new function that can be used to format numbers according to the specified format."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The resulting format function is then used to format the tick values on the y-axis of the chart. The tick values are generated using the\xa0ticks()\xa0method of the y-axis scale created using the\xa0d3-scale\xa0library."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The\xa0tickFormat()\xa0method of the y-axis scale is then used to set the tick format function. This method takes the format function as an argument and sets it as the tick format function for the y-axis scale."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"Overall, the\xa0d3-format\xa0library is used to format the tick values on the y-axis of the chart by using the\xa0format()\xa0method to create a format function and setting this function as the tick format function for the y-axis scale using the\xa0tickFormat()\xa0method."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"d3-axis:"}),"\xa0The\xa0d3-axis\xa0module is a part of the d3 library, which is a collection of JavaScript functions that are used for data visualization. The\xa0d3-axis\xa0module provides several functions for creating and manipulating axes, which are used to display the scales of a chart component."]}),"\n",(0,a.jsx)(t.p,{children:"In data visualization, axes are used to display the scales of a chart component, such as the x-axis and y-axis of a bar chart. Axes provide visual cues to help readers interpret the data values of a chart component, such as the range and domain of the data values."}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"The\xa0d3-axis\xa0module provides several types of axes, including\xa0bottom, top, left, and right axes. Each type of axis has its own set of methods for customizing the axis and displaying the tick values."}),"\n",(0,a.jsx)(t.p,{children:"Overall, the\xa0d3-axis\xa0module is an essential part of data visualization, as it provides a powerful and flexible way to display the scales of a chart component and help readers interpret the data values of the chart."}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Application in Vertical Stacked bar chart:"}),"\nIn the Vertical stacked bar chart,\xa0d3-axis\xa0is used to create and render the x and y axes of the chart."]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The\xa0d3-axis\xa0library provides various methods for creating and rendering axes, such as\xa0axisBottom(),\xa0axisLeft(), and\xa0tickFormat(). In this case, the\xa0d3-axis\xa0library is used to create and render the x and y axes of the chart."}),"\n",(0,a.jsx)(t.li,{children:"To create the x and y axes, the\xa0d3-axis\xa0library's\xa0axisBottom()\xa0and\xa0axisLeft()\xa0methods are used, respectively. These methods take a scale function as an argument and return a new axis function that can be used to render the axis."}),"\n",(0,a.jsx)(t.li,{children:"The resulting x and y axis functions are then used to render the x and y axes of the chart. The\xa0call()\xa0method of the selection object is used to call the axis function and render the axis."}),"\n",(0,a.jsx)(t.li,{children:"The\xa0tickFormat()\xa0method of the y-axis scale is also used to set the tick format function for the y-axis. This method takes the format function created using the\xa0d3-format\xa0library as an argument and sets it as the tick format function for the y-axis."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Overall, the\xa0d3-axis\xa0library is used to create and render the x and y axes of the chart by using the\xa0axisBottom()\xa0and\xa0axisLeft()\xa0methods to create the axis functions and the\xa0call()\xa0method to render the axes. The\xa0tickFormat()\xa0method is also used to set the tick format function for the y-axis."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"Dev Design details"}),"\nFollowing are the major components that contribute towards creating a complete vertical stacked bar chart:","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"Axes:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"_getScales():"}),"\xa0This method is responsible for creating the x and y scales for the chart."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Function arguments:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"containerHeight: a number representing the height of the container in which the chart will be rendered."}),"\n",(0,a.jsx)(t.li,{children:"containerWidth: a number representing the width of the container in which the chart will be rendered."}),"\n",(0,a.jsx)(t.li,{children:"isNumeric: a boolean value indicating whether the x-axis data is numeric or not. If\xa0true, the x-axis data is numeric, otherwise it is not."}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The method takes several arguments, including the container height and width, and a boolean value indicating whether the x-axis is numeric or categorical."}),"\n",(0,a.jsx)(t.li,{children:"The method first calculates the maximum y-value of the chart data and creates a linear scale for the y-axis using the\xa0d3-scale\xa0library's\xa0scaleLinear()\xa0method. The domain of the y-axis scale is set to\xa0[0, yMax], where\xa0yMax\xa0is the maximum y-value of the chart data. The range of the y-axis scale is set to\xa0[0, containerHeight - this.margins.bottom! - this.margins.top!], where\xa0containerHeight\xa0is the height of the chart container and\xa0this.margins.bottom!\xa0and\xa0this.margins.top!\xa0are the bottom and top margins of the chart, respectively."}),"\n",(0,a.jsx)(t.li,{children:"If the x-axis is numeric, the method calculates the minimum and maximum x-values of the chart data using the\xa0d3-array\xa0library's\xa0d3Min()\xa0and\xa0d3Max()\xa0methods. It then creates a linear scale for the x-axis using the\xa0d3-scale\xa0library's\xa0scaleLinear()\xa0method. The domain of the x-axis scale is set to\xa0[xMin, xMax]\xa0or\xa0[xMax, xMin]\xa0if the chart is right-to-left, where\xa0xMin\xa0and\xa0xMax\xa0are the minimum and maximum x-values of the chart data, respectively. The range of the x-axis scale is set to\xa0[this.margins.left! + this._domainMargin, containerWidth - this.margins.right! - this._barWidth - this._domainMargin], where\xa0this.margins.left!\xa0and\xa0this.margins.right!\xa0are the left and right margins of the chart, respectively, and\xa0this._barWidth\xa0and\xa0this._domainMargin\xa0are properties of the chart."}),"\n",(0,a.jsx)(t.li,{children:"If the x-axis is categorical, the method creates a band scale for the x-axis using the\xa0d3-scale\xa0library's\xa0scaleBand()\xa0method. The domain of the x-axis scale is set to the unique x-axis labels of the chart data. The range of the x-axis scale is set to\xa0[this.margins.left! + this._domainMargin, containerWidth - this.margins.right! - this._domainMargin], where\xa0this.margins.left!\xa0and\xa0this.margins.right!\xa0are the left and right margins of the chart, respectively, and\xa0this._domainMargin\xa0is a property of the chart. The\xa0paddingInner()\xa0method is used to set the inner padding of the bars to\xa02 / 3."}),"\n",(0,a.jsx)(t.li,{children:"Finally, the method returns an object with the x and y scales."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Overall, the\xa0_getScales\xa0method is responsible for creating the x and y scales for the chart using the\xa0d3-scale\xa0library's\xa0scaleLinear()\xa0and\xa0scaleBand()\xa0methods. The method calculates the domain and range of the scales based on the chart data and properties of the chart."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"_getDomainMargins():"}),"\xa0This method is responsible for calculating the margins for the x-axis domain based on the width of the chart container and the width of the bars."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Function arguments:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"containerWidth\xa0which is a number representing the width of the container in which the chart is being rendered."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The method takes a single argument,\xa0containerWidth, which is the width of the chart container."}),"\n",(0,a.jsx)(t.li,{children:"The method first checks whether the x-axis is numeric or categorical. If the x-axis is not numeric, the method calculates the total width available to render the bars by subtracting the left and right margins and the minimum domain margin from the container width. It then calculates the required width to render the bars based on the number of x-axis labels and the bar width. If the total width available is greater than or equal to the required width, the method sets the domain margin to half of the difference between the total width available and the required width to center align the chart. If the total width available is less than the required width, the method calculates the maximum possible bar width to maintain a 2:1 spacing between the bars and sets the domain margin to the minimum domain margin."}),"\n",(0,a.jsx)(t.li,{children:"The method then sets the bar width and domain margin properties of the chart based on the calculated values."}),"\n",(0,a.jsx)(t.li,{children:"Finally, the method returns an object with the margins for the x-axis domain, which includes the left and right margins and the domain margin."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Overall, the\xa0_getDomainMargins\xa0method is responsible for calculating the margins for the x-axis domain based on the width of the chart container and the width of the bars. The method calculates the total width available to render the bars, the required width to render the bars, and the maximum possible bar width to maintain a 2:1 spacing between the bars. The method then sets the domain margin and bar width properties of the chart based on the calculated values."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"createNumericXAxis():"}),"\xa0The code above is a function called\xa0createNumericXAxis\xa0in the\xa0utilities.ts\xa0file. This function is responsible for creating a numeric x-axis for a chart component. The function takes two arguments:\xa0xAxisParams\xa0and\xa0chartType.\xa0xAxisParams\xa0is an object that contains several properties, including\xa0domainNRangeValues,\xa0showRoundOffXTickValues,\xa0xAxistickSize,\xa0tickPadding,\xa0xAxisCount, and\xa0xAxisElement.\xa0chartType\xa0is an enumeration that specifies the type of chart component."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Function arguments:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["xAxisParams\xa0of type\xa0IXAxisParams\xa0which is an object containing the following properties:","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"domainNRangeValues\xa0of type\xa0IDomainNRange\xa0which is an object containing the domain and range values for the x-axis."}),"\n",(0,a.jsx)(t.li,{children:"showRoundOffXTickValues\xa0of type\xa0boolean\xa0which is an optional property that determines whether to round off the x-axis tick values."}),"\n",(0,a.jsx)(t.li,{children:"xAxistickSize\xa0of type\xa0number\xa0which is an optional property that determines the size of the x-axis ticks."}),"\n",(0,a.jsx)(t.li,{children:"tickPadding\xa0of type\xa0number\xa0which is an optional property that determines the padding between the x-axis ticks and the x-axis labels."}),"\n",(0,a.jsx)(t.li,{children:"xAxisCount\xa0of type\xa0number\xa0which is an optional property that determines the number of x-axis ticks."}),"\n",(0,a.jsx)(t.li,{children:"xAxisElement\xa0of type\xa0SVGElement | null\xa0which is an optional property that represents the x-axis element."}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.li,{children:"chartType\xa0of type\xa0ChartTypes\xa0which is an enum that represents the type of chart."}),"\n",(0,a.jsx)(t.li,{children:"culture\xa0of type string which is an optional paramter represents the locale into which the numeric x-axis labels will be localized."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The function first extracts the properties of the\xa0xAxisParams\xa0object using destructuring. The\xa0domainNRangeValues\xa0property is an object that contains the start and end values of the domain and range of the x-axis. The\xa0showRoundOffXTickValues\xa0property is a boolean that specifies whether to round off the tick values of the x-axis. The\xa0xAxistickSize\xa0property is a number that specifies the size of the ticks of the x-axis. The\xa0tickPadding\xa0property is a number that specifies the padding between the ticks and the labels of the x-axis. The\xa0xAxisCount\xa0property is a number that specifies the number of ticks of the x-axis. The\xa0xAxisElement\xa0property is a reference to the DOM node that contains the x-axis of the chart."}),"\n",(0,a.jsx)(t.li,{children:"The function then creates a linear scale for the x-axis using the\xa0d3ScaleLinear\xa0function from the\xa0d3-scale\xa0module. The scale is customized using the\xa0domain\xa0and\xa0range\xa0methods, which set the domain and range of the scale, respectively. If the\xa0showRoundOffXTickValues\xa0property is\xa0true, the\xa0nice\xa0method is called on the scale to round off the tick values of the x-axis."}),"\n",(0,a.jsx)(t.li,{children:"The function then creates a bottom axis for the x-axis using the\xa0d3AxisBottom\xa0function from the\xa0d3-axis\xa0module. The axis is customized using the\xa0tickSize,\xa0tickPadding,\xa0ticks, and\xa0tickFormat\xa0methods. The\xa0tickSize\xa0method sets the size of the ticks of the x-axis. The\xa0tickPadding\xa0method sets the padding between the ticks and the labels of the x-axis. The\xa0ticks\xa0method sets the number of ticks of the x-axis. The\xa0tickFormat\xa0method formats the tick values of the x-axis using the\xa0convertToLocaleString\xa0function and the\xa0culture\xa0parameter."}),"\n",(0,a.jsx)(t.li,{children:"If the\xa0xAxisElement\xa0property is not\xa0null, the axis is rendered on the DOM node using the\xa0call\xa0method of the\xa0d3-selection\xa0module. The\xa0selectAll\xa0method is called on the axis to select all the text elements of the x-axis, and the\xa0attr\xa0method is called to set the\xa0aria-hidden\xa0attribute of the text elements to\xa0true."}),"\n",(0,a.jsx)(t.li,{children:"Finally, the function computes the tick values of the x-axis using the\xa0ticks\xa0and\xa0tickFormat\xa0methods of the scale, and returns an object that contains the x-axis scale and the tick values."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Overall, the\xa0createNumericXAxis\xa0function is responsible for creating a numeric x-axis for a chart component. The function creates a linear scale for the x-axis and a bottom axis for the x-axis using the\xa0d3-scale\xa0and\xa0d3-axis\xa0modules, respectively. The function customizes the scale and axis using several methods, including\xa0domain,\xa0range,\xa0tickSize,\xa0tickPadding,\xa0ticks, and\xa0tickFormat. The function also renders the axis on the DOM node and computes the tick values of the x-axis."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"createStringXAxis():"}),"\xa0This function is responsible for creating a string x-axis for a chart component. The function takes four arguments:\xa0xAxisParams,\xa0tickParams,\xa0dataset, and\xa0culture.\xa0xAxisParams\xa0is an object that contains several properties, including\xa0domainNRangeValues,\xa0xAxisCount,\xa0xAxistickSize,\xa0tickPadding,\xa0xAxisPadding,\xa0xAxisInnerPadding, and\xa0xAxisOuterPadding.\xa0tickParams\xa0is an object that contains several properties, including\xa0tickValues\xa0and\xa0tickFormat.\xa0dataset\xa0is an array of strings that contains the values of the x-axis.\xa0culture\xa0is a string that specifies the locale into which the x-axis labels can be localized."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Function Arguments:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"xAxisParams: An object containing the parameters for the x-axis, including the domain and range values, tick size, tick padding, number of ticks, padding for the inner and outer edges of the axis, and the element to render the axis."}),"\n",(0,a.jsx)(t.li,{children:"tickParams: An object containing the parameters for the ticks on the x-axis, including the tick values and tick format."}),"\n",(0,a.jsx)(t.li,{children:"dataset: An array of strings representing the data points for the x-axis."}),"\n",(0,a.jsx)(t.li,{children:"culture: An optional string representing the culture to use for formatting the tick labels on the x-axis. However, the localization works only if the string can be converted to a numeric value. Otherwise, the x-axis labels remain unlocalized."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The function first extracts the properties of the\xa0xAxisParams\xa0object using destructuring. The\xa0domainNRangeValues\xa0property is an object that contains the start and end values of the domain and range of the x-axis. The\xa0xAxisCount\xa0property is a number that specifies the number of ticks of the x-axis. The\xa0xAxistickSize\xa0property is a number that specifies the size of the ticks of the x-axis. The\xa0tickPadding\xa0property is a number that specifies the padding between the ticks and the labels of the x-axis. The\xa0xAxisPadding\xa0property is a number that specifies the padding between the bars of the chart. The\xa0xAxisInnerPadding\xa0property is a number that specifies the inner padding between the bars of the chart. The\xa0xAxisOuterPadding\xa0property is a number that specifies the outer padding between the bars of the chart."}),"\n",(0,a.jsx)(t.li,{children:"The function then creates a band scale for the x-axis using the\xa0d3ScaleBand\xa0function from the\xa0d3-scale\xa0module. The scale is customized using the\xa0domain\xa0and\xa0range\xa0methods, which set the domain and range of the scale, respectively. The\xa0paddingInner\xa0and\xa0paddingOuter\xa0methods are used to set the inner and outer padding between the bars of the chart, respectively."}),"\n",(0,a.jsx)(t.li,{children:"The function then creates a bottom axis for the x-axis using the\xa0d3AxisBottom\xa0function from the\xa0d3-axis\xa0module. The axis is customized using the\xa0tickSize,\xa0tickPadding,\xa0ticks, and\xa0tickFormat\xa0methods. The\xa0tickSize\xa0method sets the size of the ticks of the x-axis. The\xa0tickPadding\xa0method sets the padding between the ticks and the labels of the x-axis. The\xa0ticks\xa0method sets the number of ticks of the x-axis. The\xa0tickFormat\xa0method formats the tick values of the x-axis using the\xa0convertToLocaleString\xa0function and the\xa0culture\xa0parameter."}),"\n",(0,a.jsx)(t.li,{children:"If the\xa0xAxisParams.xAxisElement\xa0property is not\xa0null, the axis is rendered on the DOM node using the\xa0call\xa0method of the\xa0d3-selection\xa0module. The\xa0selectAll\xa0method is called on the axis to select all the text elements of the x-axis, and the\xa0attr\xa0method is called to set the\xa0aria-hidden\xa0attribute of the text elements to\xa0true."}),"\n",(0,a.jsx)(t.li,{children:"Finally, the function computes the tick values of the x-axis using the\xa0tickFormat\xa0method of the axis, and returns an object that contains the x-axis scale and the tick values."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Overall, the\xa0createStringXAxis\xa0function is responsible for creating a string x-axis for a chart component. The function creates a band scale for the x-axis and a bottom axis for the x-axis using the\xa0d3-scale\xa0and\xa0d3-axis\xa0modules, respectively. The function customizes the scale and axis using several methods, including\xa0domain,\xa0range,\xa0paddingInner,\xa0paddingOuter,\xa0tickSize,\xa0tickPadding,\xa0ticks, and\xa0tickFormat. The function also renders the axis on the DOM node and computes the tick values of the x-axis."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"createYAxis():"}),"\xa0In the Vertical bar chart component, the\xa0d3-axis\xa0module is used to create and customize the y-axis of a vertical bar chart. The\xa0createYAxis\xa0function is responsible for creating the y-axis using the\xa0createYAxisForOtherCharts\xa0function. The function takes in several parameters, including\xa0yAxisParams,\xa0isRtl,\xa0axisData, and\xa0useSecondaryYScale. These parameters are used to customize the y-axis, such as setting the tick values, tick format, and tick padding."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Function arguments:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["yAxisParams: An object that contains various parameters related to the y-axis of the chart. It has the following properties:","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"yMinMaxValues: An object that contains the start and end values of the y-axis."}),"\n",(0,a.jsx)(t.li,{children:"yAxisElement: The DOM element that represents the y-axis."}),"\n",(0,a.jsx)(t.li,{children:"yMaxValue: The maximum value of the y-axis."}),"\n",(0,a.jsx)(t.li,{children:"yMinValue: The minimum value of the y-axis."}),"\n",(0,a.jsx)(t.li,{children:"containerHeight: The height of the container that holds the chart."}),"\n",(0,a.jsx)(t.li,{children:"containerWidth: The width of the container that holds the chart."}),"\n",(0,a.jsx)(t.li,{children:"margins: An object that contains the margins of the chart."}),"\n",(0,a.jsx)(t.li,{children:"tickPadding: The padding between the ticks and the axis line."}),"\n",(0,a.jsx)(t.li,{children:"maxOfYVal: The maximum value of the y-axis for area chart and Grouped vertical bar chart."}),"\n",(0,a.jsx)(t.li,{children:"yAxisTickFormat: The format of the y-axis tick labels."}),"\n",(0,a.jsx)(t.li,{children:"yAxisTickCount: The number of ticks on the y-axis."}),"\n",(0,a.jsx)(t.li,{children:"eventAnnotationProps: An object that contains the properties of the event annotation."}),"\n",(0,a.jsx)(t.li,{children:"eventLabelHeight: The height of the event label."}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.li,{children:"isRtl: A boolean value that indicates whether the chart is in right-to-left mode."}),"\n",(0,a.jsx)(t.li,{children:"axisData: An object that contains the data related to the axis of the chart."}),"\n",(0,a.jsx)(t.li,{children:"useSecondaryYScale: A boolean value that indicates whether to use a secondary y-axis scale."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The function first extracts the necessary parameters from the\xa0yAxisParams\xa0object, such as the\xa0yMinMaxValues, yAxisElement, containerHeight, and containerWidth. It then calculates the final maximum and minimum values for the y-axis, based on the\xa0maxOfYVal, yMaxValue, and yMinValue\xa0parameters."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The function then prepares the datapoints for the y-axis using the\xa0prepareDatapoints\xa0function, which calculates the tick values based on the maximum and minimum values of the y-axis. It then creates a linear scale for the y-axis using the\xa0d3ScaleLinear\xa0function from the\xa0d3-scale\xa0library."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The function then creates the y-axis using the\xa0d3AxisLeft\xa0or\xa0d3AxisRight\xa0function from the\xa0d3-axis\xa0library, depending on the\xa0isRtl and useSecondaryYScale\xa0parameters. It sets the tick padding, tick values, and tick size for the y-axis, and formats the tick labels using the\xa0yAxisTickFormat\xa0parameter."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"Finally, the function uses the d3Select function to select the\xa0yAxisElement\xa0and apply the y-axis to it using the call method. It also sets the aria-hidden attribute of the y-axis text elements to true to improve accessibility."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"createStringYAxis():"}),"\xa0In the Vertical bar chart component, the\xa0d3-axis\xa0module is used to create and customize the y-axis of a vertical bar chart. The\xa0createStringYAxis\xa0function is responsible for creating the y-axis that use string values for the y-axis using the\xa0createStringYAxisForOtherCharts\xa0function. The function takes in several parameters, including\xa0yAxisParams, dataPoints, and isRtl. These parameters are used to customize the y-axis, such as setting the tick values, tick format, and tick padding."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Function arguments:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"yAxisParams: An object that contains the parameters for the y-axis, including\xa0containerHeight,\xa0tickPadding,\xa0margins,\xa0yAxisTickFormat,\xa0yAxisElement, and\xa0yAxisPadding."}),"\n",(0,a.jsx)(t.li,{children:"dataPoints: An array of strings that represent the data points for the y-axis."}),"\n",(0,a.jsx)(t.li,{children:"isRtl: A boolean value that indicates whether the chart is in right-to-left mode."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The function first extracts the necessary parameters from the\xa0yAxisParams\xa0object, such as the\xa0containerHeight,\xa0margins,\xa0yAxisTickFormat,\xa0yAxisElement, and\xa0yAxisPadding. It then creates a band scale for the y-axis using the\xa0d3ScaleBand\xa0function from the\xa0d3-scale\xa0library."}),"\n",(0,a.jsx)(t.li,{children:"The band scale is defined using the\xa0dataPoints\xa0array as the domain, and the\xa0containerHeight\xa0and\xa0margins\xa0parameters as the range. The\xa0padding\xa0method is used to set the padding between the bands in the y-axis."}),"\n",(0,a.jsx)(t.li,{children:"The function then creates the y-axis using the\xa0d3AxisLeft\xa0or\xa0d3AxisRight\xa0function from the\xa0d3-axis\xa0library, depending on the\xa0isRtl\xa0parameter. It sets the tick padding, tick values, and tick size for the y-axis, and formats the tick labels using the\xa0yAxisTickFormat\xa0parameter."}),"\n",(0,a.jsx)(t.li,{children:"Finally, the function uses the\xa0d3Select\xa0function to select the\xa0yAxisElement\xa0and apply the y-axis to it using the\xa0call\xa0method. It also selects all the text elements of the y-axis and returns the y-axis scale."}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"Bars:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"_createBar():"}),"\xa0This method is responsible for creating and rendering the bars of the chart."]}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Function arguments:"}),"\nThe\xa0_createBar\xa0function takes four arguments:"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"xBarScale: This is a scaling function that maps the x-axis data points to the corresponding x-axis positions on the chart. The type of this argument is\xa0any, which means that it can be any type of scaling function."}),"\n",(0,a.jsx)(t.li,{children:"yBarScale: This is a scaling function that maps the y-axis data points to the corresponding y-axis positions on the chart. The type of this argument is\xa0NumericScale, which is a custom type defined elsewhere in the code."}),"\n",(0,a.jsx)(t.li,{children:"containerHeight: This is the height of the container element that holds the chart. This is used to calculate the y-axis position of the bars."}),"\n",(0,a.jsx)(t.li,{children:"xElement: This is an SVG element that represents the x-axis of the chart. This is used to calculate the x-axis position of the bars."}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The method takes several arguments, including the x and y scales, the container height and width, and an SVG element for the x-axis. It first checks whether the chart has any line data and whether to focus on the whole stack or not."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The method then iterates over each item in the chart data and calculates the x and y coordinates for each bar using the scales and the bar width. It also calculates the height of each bar based on the data and the y scale. If the bar height is less than the minimum bar height, it sets the height to the minimum bar height."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"For each bar, the method creates a rectangle element using the\xa0rect\xa0SVG element and sets the x, y, width, height, fill, and other properties. It also adds an\xa0onMouseOver,\xa0onMouseMove,\xa0onMouseLeave,\xa0onFocus,\xa0onBlur, and\xa0onClick\xa0event listener for the bar if the legend is selected."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"If the bar has a corner radius and is the last bar in the stack, it creates a path element using the\xa0path\xa0SVG element and sets the\xa0d, fill, and other properties. It also adds an\xa0onMouseOver,\xa0onMouseMove,\xa0onMouseLeave,\xa0onFocus,\xa0onBlur, and\xa0onClick\xa0event listener for the path if the legend is selected."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The method then creates a group element using the\xa0g\xa0SVG element and adds the rectangle and path elements to the group. It also adds an\xa0onMouseOver,\xa0onMouseMove,\xa0onMouseLeave,\xa0onFocus,\xa0onBlur, and\xa0onClick\xa0event listener for the group if the legend is selected."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"Finally, the method returns the bars as a React fragment."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Numeric bars (_createNumericBars()):"}),"\xa0This method is responsible for creating and rendering the numeric bars of the chart."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Function arguments:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"containerHeight\xa0(number): The height of the container in which the chart is rendered."}),"\n",(0,a.jsx)(t.li,{children:"containerWidth\xa0(number): The width of the container in which the chart is rendered."}),"\n",(0,a.jsx)(t.li,{children:"xElement\xa0(SVGElement): The SVG element that represents the x-axis of the chart."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The method takes several arguments, including the container height and width, and an SVG element for the x-axis. It first gets the x and y bar scales using the _getScales method with the numeric parameter set to true."}),"\n",(0,a.jsx)(t.li,{children:"The method then calls the _createBar method with the x and y bar scales, container height, and x-axis element as arguments. The _createBar method is responsible for creating and rendering the bars of the chart."}),"\n",(0,a.jsx)(t.li,{children:"The _createBar method creates a rectangle element for each bar using the rect SVG element and sets the x, y, width, height, fill, and other properties. It also adds event listeners for the bar if the legend is selected."}),"\n",(0,a.jsx)(t.li,{children:"The _createBar method then creates a group element using the g SVG element and adds the rectangle elements to the group. It also adds event listeners for the group if the legend is selected."}),"\n",(0,a.jsx)(t.li,{children:"Finally, the _createBar method returns the bars as a React fragment."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Overall, the _createNumericBars method is responsible for creating and rendering the numeric bars of the chart by calling the _createBar method with the appropriate scales and arguments. The _createBar method is responsible for creating and rendering the bars of the chart using the rect and g SVG elements and adding event listeners for interactivity."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"String bars (_createStringBars()):"}),"\xa0This method is responsible for creating and rendering the string bars of the chart."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Function arguments:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"containerHeight\xa0(number): The height of the container in which the chart is rendered."}),"\n",(0,a.jsx)(t.li,{children:"containerWidth\xa0(number): The width of the container in which the chart is rendered."}),"\n",(0,a.jsx)(t.li,{children:"xElement\xa0(SVGElement): The SVG element that represents the x-axis of the chart."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The method takes several arguments, including the container height and width, and an SVG element for the x-axis. It first gets the x and y bar scales using the _getScales method with the numeric parameter set to false."}),"\n",(0,a.jsx)(t.li,{children:"The method then calls the _createBar method with the x and y bar scales, container height, and x-axis element as arguments. The _createBar method is responsible for creating and rendering the bars of the chart."}),"\n",(0,a.jsx)(t.li,{children:"The _createBar method creates a rectangle element for each bar using the rect SVG element and sets the x, y, width, height, fill, and other properties. It also adds event listeners for the bar if the legend is selected."}),"\n",(0,a.jsx)(t.li,{children:"The _createBar method then creates a group element using the g SVG element and adds the rectangle elements to the group. It also adds event listeners for the group if the legend is selected."}),"\n",(0,a.jsx)(t.li,{children:"Finally, the _createBar method returns the bars as a React fragment."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Overall, the _createStringBars method is responsible for creating and rendering the string bars of the chart by calling the _createBar method with the appropriate scales and arguments. The _createBar method is responsible for creating and rendering the bars of the chart using the rect and g SVG elements and adding event listeners for interactivity."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"Lines:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"_createLines():"}),"\xa0This method is responsible for creating and rendering the lines and dots of the chart."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Function arguments:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"xScale: A\xa0NumericScale\xa0object that represents the scale for the x-axis of the chart."}),"\n",(0,a.jsx)(t.li,{children:"yScale: A\xa0NumericScale\xa0object that represents the scale for the y-axis of the chart."}),"\n",(0,a.jsx)(t.li,{children:"containerHeight: A number that represents the height of the container that holds the chart."}),"\n",(0,a.jsx)(t.li,{children:"containerWidth: A number that represents the width of the container that holds the chart."}),"\n",(0,a.jsx)(t.li,{children:"secondaryYScale: An optional\xa0NumericScale\xa0object that represents the scale for the secondary y-axis of the chart. This argument is only used if the chart has a secondary y-axis."}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The method takes several arguments, including the x and y scales, the container height and width, and an optional secondary y scale. It first checks whether the x-axis is numeric or not and gets the scales using the\xa0_getScales\xa0method."}),"\n",(0,a.jsx)(t.li,{children:"The method then gets the formatted line data using the\xa0_getFormattedLineData\xa0method and iterates over each item in the line object. For each item, it checks whether the legend is highlighted or not and iterates over each point in the line. It calculates the x and y coordinates for each point using the scales and whether to use the secondary y scale or not."}),"\n",(0,a.jsx)(t.li,{children:"If the line border width is greater than zero, it creates a line element for the border of the line using the\xa0line\xa0SVG element. It then creates a line element for the line itself using the same\xa0line\xa0SVG element and adds an\xa0onMouseOver\xa0and\xa0onMouseLeave\xa0event listener if the legend is selected."}),"\n",(0,a.jsx)(t.li,{children:"Finally, it creates a circle element for each point in the line using the\xa0circle\xa0SVG element and adds an\xa0onMouseOver\xa0and\xa0onMouseLeave\xa0event listener if the legend is selected. It sets the radius and visibility of the circle based on the legend and x-axis point."}),"\n",(0,a.jsx)(t.li,{children:"The method returns the border lines, lines, and dots as a React fragment."}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"Legends:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"_getLegendData():"}),"\xa0This method is responsible for creating and rendering the legend of the chart."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Function arguments:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"data: an array of IVerticalStackedChartProps objects, which contain the chart data to be displayed."}),"\n",(0,a.jsx)(t.li,{children:"palette: an object of type IPalette that contains a set of colors to be used for the chart."}),"\n",(0,a.jsx)(t.li,{children:"lineLegends: an array of LineLegends objects, which contain the legend data for any lines that are displayed on the chart."}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The method takes several arguments, including the chart data, the color palette, and an array of line legends. It first checks whether the legend should be hidden or not based on the\xa0hideLegend\xa0prop."}),"\n",(0,a.jsx)(t.li,{children:"The method then iterates over each item in the chart data and creates a legend for each unique legend title and color combination. It generates a random color from the default palette if the point does not have a color. It also checks whether there are any similar legends already created and skips the creation if there are."}),"\n",(0,a.jsx)(t.li,{children:"For each legend, the method creates an object with the legend title, color, and event listeners for click, hover, and mouse out actions. It adds the legend object to an array of actions."}),"\n",(0,a.jsx)(t.li,{children:"If there are any line legends, the method iterates over each item in the line legends and creates a legend object with the title, color, and event listeners. It adds the legend object to an array of line legends."}),"\n",(0,a.jsx)(t.li,{children:"The method then concatenates the arrays of actions and line legends and creates a\xa0Legends\xa0component with the resulting array of legends. It also passes any additional props for the\xa0Legends\xa0component."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Overall, the\xa0_getLegendData\xa0method is responsible for creating and rendering the legend of the chart by iterating over the chart data and line legends and creating legend objects with event listeners. It then passes the resulting array of legends to a\xa0Legends\xa0component for rendering."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"Callouts:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"_renderCallout():"}),"\xa0This method is responsible for rendering the callout for a data point when it is hovered over."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The method takes an optional\xa0IVSChartDataPoint\xa0object as an argument, which contains the data for the hovered data point. If the argument is not provided, the method returns\xa0null."}),"\n",(0,a.jsx)(t.li,{children:"If the argument is provided, the method creates a\xa0ChartHoverCard\xa0component with the\xa0XValue, Legend, YValue, color, and culture\xa0props set to the corresponding values from the\xa0IVSChartDataPoint\xa0object. The\xa0ChartHoverCard\xa0component is responsible for rendering the callout with the data for the hovered data point."}),"\n",(0,a.jsx)(t.li,{children:"Finally, the method returns the\xa0ChartHoverCard\xa0component."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Overall, the\xa0_renderCallout\xa0method is responsible for rendering the callout for a data point when it is hovered over by creating a\xa0ChartHoverCard\xa0component with the data for the hovered data point."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"_getCustomizedCallout():"}),"\xa0This method is responsible for rendering the callout for a data point or stack when it is hovered over."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Working algorithm:"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The method first checks whether the chart has any line data by iterating over the chart data and checking whether each item has a\xa0lineData\xa0property with a length greater than zero. If the chart has any line data, it sets a boolean variable\xa0_isHavingLines\xa0to\xa0true."}),"\n",(0,a.jsx)(t.li,{children:"The method then checks whether the\xa0onRenderCalloutPerStack\xa0prop is defined. If it is defined, the method calls the\xa0onRenderCalloutPerStack\xa0function with the\xa0stackCalloutProps\xa0object as an argument. The\xa0stackCalloutProps\xa0object contains the data for the hovered stack."}),"\n",(0,a.jsx)(t.li,{children:"If the\xa0onRenderCalloutPerStack\xa0prop is not defined, the method checks whether the\xa0onRenderCalloutPerDataPoint\xa0prop is defined and whether the chart has any line data. If the\xa0onRenderCalloutPerDataPoint\xa0prop is defined and the chart does not have any line data, the method calls the\xa0onRenderCalloutPerDataPoint\xa0function with the\xa0dataPointCalloutProps\xa0object and the\xa0_renderCallout\xa0method as arguments. The\xa0dataPointCalloutProps\xa0object contains the data for the hovered data point."}),"\n",(0,a.jsx)(t.li,{children:"If neither the\xa0onRenderCalloutPerStack\xa0nor the\xa0onRenderCalloutPerDataPoint\xa0prop is defined, the method returns\xa0null."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Overall, the\xa0_getCustomizedCallout\xa0method is responsible for rendering the callout for a data point or stack when it is hovered over by calling the appropriate\xa0onRenderCallout\xa0function with the corresponding data. If neither\xa0onRenderCallout\xa0function is defined, the method returns\xa0null."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"Rendering details"}),"\nThe Vertical stacked bar chart uses d3 SVG based rendering, which follows the following render cycles:","\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:"- Invocation cycle: Vertical stacked bar Chart -> Cartesian base chart -> X-axis -> X-axis labels -> Y-axis -> Y-axis labels -> bars, legends, callouts\n- Rendering cycle: Vertical stacked bar chart <- Bars (rect), lines (line), Legends, Callouts <- Axes (d3.axis, d3.scale)\n"})}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Following are the rendering details:"})}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsx)(t.li,{children:"The Vertical stacked bar chart component defines a class component that renders a vertical stacked bar chart. The chart can be either numeric or categorical, depending on the type of data passed in. The chart is rendered using\xa0SVG\xa0elements."}),"\n",(0,a.jsx)(t.li,{children:"The component has several private methods that are used to create the chart. The\xa0_getScales\xa0method is used to create the x and y scales for the chart. The\xa0_createNumericBars\xa0and\xa0_createStringBars\xa0methods are used to create the bars for the chart. The\xa0_getGraphData\xa0method is used to get the data for the chart. The\xa0_getAxisData\xa0method is used to get the data for the y-axis."}),"\n",(0,a.jsx)(t.li,{children:"The component also has several private variables that are used to calculate the margins and bar width for the chart. The\xa0_domainMargin\xa0variable is used to calculate the margin for the x-axis. The\xa0_barWidth\xa0variable is used to calculate the width of the bars in the chart."}),"\n",(0,a.jsx)(t.li,{children:"The component also has several private methods that are used to handle user interactions with the chart. The\xa0_legendHighlighted\xa0method is used to check if a legend is highlighted. The\xa0_noLegendHighlighted\xa0method is used to check if no legend is highlighted. The\xa0_getAriaLabel\xa0method is used to get the aria label for the chart."}),"\n",(0,a.jsx)(t.li,{children:"Finally, the component has a render method that renders the chart using\xa0SVG\xa0elements. The chart is rendered as a series of stacked bars, with each bar representing a category or value. The chart also includes a legend and a callout that displays additional information about the data point when the user hovers over it."}),"\n"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Variants"}),"\nFollowing are the variants of vertical bar chart:\xa0",(0,a.jsx)(t.a,{href:"https://developer.microsoft.com/en-us/fluentui#/controls/web/verticalbarchart/verticalstackedbarchart",children:"Ref8"}),"\xa0"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.em,{children:"Basic Vertical stacked bar Chart"}),": Only basic props are provided."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.em,{children:"Custom Callout"}),": Can show customized callout data."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.em,{children:"Custom Accessibility"}),": Providing custom aria labels."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.em,{children:"Styled"}),": Can show bars with a single callout or a stacked callout."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.em,{children:"Tooltip"}),": Can show tooltip over x-axis ticks."]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Testing"}),"\nThe manual tests for Vertical stacked bar chart has been completed and the component tests are in PR. Following is the improvement in code coverage:\n",(0,a.jsx)(t.img,{alt:"VerticalStackedBarChart3.png",src:n(9845).Z+"",width:"2477",height:"538"})]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["Component Tests:","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["Work item ",(0,a.jsx)(t.a,{href:"https://uifabric.visualstudio.com/iss/_workitems/edit/7439",children:"7439"})]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["Unit Tests:","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["Work item ",(0,a.jsx)(t.a,{href:"https://uifabric.visualstudio.com/iss/_workitems/edit/7440",children:"7440"})]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["Manual Tests:","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["Work item ",(0,a.jsx)(t.a,{href:"https://uifabric.visualstudio.com/iss/_workitems/edit/8602",children:"8602"})]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["Accessibility Tests:","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["Work item ",(0,a.jsx)(t.a,{href:"https://uifabric.visualstudio.com/iss/_workitems/edit/7438",children:"7438"})]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Accessibility"}),"\nFAST pass checks resulted in no error for Vertical stacked bar chart. Link to the ",(0,a.jsx)(t.a,{href:"https://accessibilityinsights.io/docs/web/getstarted/fastpass/",children:"FAST pass tool"}),"\nOur charts have elaborate accessibility support. The charts are WCAG 2.1 MAS C compliant for accessibility.\nConsumers can define their own aria labels for each point by setting the\xa0callOutAccessibilityData\xa0properties."]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Theming"}),'\nThe palette for donut chart is set from the "theme" prop as passed to the component during rendering. Both light and dark themes are supported and users can create there own theme too.\xa0',(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/wiki/Theming",children:"Ref3"}),"\xa0\xa0and\xa0",(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/wiki/How-to-apply-theme-to-Fluent-UI-React-components",children:"Ref4"}),"\xa0\xa0explains theming in detail."]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Debugging"}),"\nThe detailed steps on debugging has been given in\xa0",(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui-charting-contrib/blob/main/docs/Debugging.md",children:"Debugging"}),"."]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Error scenarios"}),"\nThe Vertical stacked bar chart handles the following error scenario:"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"Empty data: If the data passed to the chart component is empty, the chart will not render and a message will be narrated to the user.\xa0_isChartEmpty\xa0functions handles that scenario."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Localization aspects"}),"\nThe component has a\xa0culture\xa0prop, which is used to set the culture for the chart. This prop is used to format the x-axis labels and the callout values based on the specified culture. Currently, vertical bar chart provides localization only for the x-axis ticks if they are numbers."]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Some notable PRs and their brief description"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/12308",children:"Added the vertical stacked bar chart component"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/commit/f986d68c3fad2ff4034ebb86fd4618df11d81221",children:"Vertical stacked bar chart code refactor. Cartesian chart implemented in base file"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/16914",children:"Accessibility: narrator issues fixed in bar charts"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/17571",children:"Accessibility: Callout dismiss on ESC issue solved in all bar charts"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/19072",children:"Accessibility change for Vertical Stacked Bar chart"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/28594",children:"Adding component tests for Vertical Stacked Bar chart."})}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Future improvements"}),"\nFollowing are the future improvements that can be incorporated in vertical stacked bar charts:"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"Add support for animations: Animations can make the chart more engaging and help to highlight changes in the data over time. Adding support for animations would require using a library such as d3-transition."}),"\n",(0,a.jsx)(t.li,{children:"Add support for multiple data sets: Currently, the chart only supports a single data set. Adding support for multiple data sets would allow the user to compare different sets of data on the same chart. For example: grouped vertical stacked bar chart."}),"\n",(0,a.jsx)(t.li,{children:"Improve accessibility: The chart could be made more accessible by adding support for keyboard navigation. This would require adding additional attributes to the chart elements and updating the event handlers accordingly."}),"\n",(0,a.jsxs)(t.li,{children:["Following error handling scenarios can be improved:","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"Invalid or missing chart dimensions: If the dimensions of the chart are invalid or missing, the chart will not render and a message will be displayed to the user."}),"\n",(0,a.jsx)(t.li,{children:"Invalid or missing axis parameters: If the parameters for the x-axis or y-axis are invalid or missing, the chart will not render and a message will be displayed to the user."}),"\n",(0,a.jsx)(t.li,{children:"Invalid or missing legends: If the legends for the chart are invalid or missing, the chart will not render and a message will be displayed to the user."}),"\n",(0,a.jsx)(t.li,{children:"Invalid bar width: If the bar width for the chart is invalid, the chart will not render and a message will be displayed to the user."}),"\n",(0,a.jsx)(t.li,{children:"Invalid or missing data for callout: If the data for the callout is invalid or missing, the callout will not render and a message will be displayed to the user."}),"\n",(0,a.jsx)(t.li,{children:"Invalid or missing accessibility data: If the accessibility data for the chart is invalid or missing, the chart will not render and a message will be displayed to the user."}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.li,{children:"Localization support can be improved for all strings and numbers."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Interactions"}),"\nFollowing are the interactions that are allowed for vertical stacked bar chart:"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.em,{children:"Mouse Events"}),":\na. Hover mouse over a stacked bar, should call the corresponding handler and show the callout containing information about all the bars stacked over that bar.\nb. On mouse move on stacked Bar 1 (step 1) -> mouse leave (step 2) -> mouse move on stacked Bar 2 (step 3), should render the callout of the stacked Bar 2.\nc. On mouse over, callout should be defined, on mouse leave, callout should disappear.\nd. On mouse over on legends, should highlight the corresponding bar/line.\nf. On click on stacked Bar, should highlight the corresponding entire stacked bar.\ng. On mouse over a bar legend, should highlight all the bars of that type on all the stacked bars.\ng. On mouse out after mouse over on first legend, should have opacity 0.1 for second bar initially (during mouseOver on first legend) and opacity set to 1 for both the bars on mouse out."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.em,{children:"Keyboard Events"}),":\na. On focus on a bar, should render the corresponding callout.\nb. On focus on a line, should highlight the corresponding line and its legend."]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Learnings"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"While implementing the tests using react testing library, it was found that certain browser functions like\xa0getComputedTextLength()\xa0cannot be unit tested and needs to be tested End-to-End only."}),"\n",(0,a.jsx)(t.li,{children:"Order of imports are important.\nFor example: for Vertical bar charts tests, improper sequencing of the imports (data first and then render) results in incorrect and incopmlete rendering of charts:"}),"\n"]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:"import { chartPoints } from '../VerticalBarChart/VerticalBarChart.test';\nimport { render, screen, queryAllByAttribute, fireEvent, act } from '@testing-library/react';\n"})}),"\n",(0,a.jsx)(t.p,{children:"However, the following results in correct rendering:"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:"import { render, screen, queryAllByAttribute } from '@testing-library/react';\n\nimport { chartPoints } from './VerticalBarChart.test';\n"})}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"Certain props need async await structure (waitFor in react testing library) for different props or nested SVGs to render."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Design figma"}),"\nVertical Stacked Bar Chart Figma -\xa0",(0,a.jsx)(t.a,{href:"https://www.figma.com/file/WOoCs0CmNYZhYl9xXeCGpi/Data-viz-(Archive)?type=design&node-id=21153-80197&mode=design&t=kjtgBpG3tOGCcx00-0",children:"Link"}),"\xa0"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"Known issues"})}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"Setting the margins externally via the props may cut the x and y ticks if the margins provided are very less. Setting a minimum margin would prevent any such distortions."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Performance"}),"\nThe performance aspect of a vertical stacked bar chart refers to how efficiently and effectively it conveys information to the viewer. Here are some key considerations regarding the performance of a line chart:"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"Data Visualization Efficiency"}),"\n",(0,a.jsx)(t.li,{children:"Clarity and Simplicity"}),"\n",(0,a.jsx)(t.li,{children:"Responsiveness"}),"\n",(0,a.jsx)(t.li,{children:"Handling Large Datasets"}),"\n",(0,a.jsx)(t.li,{children:"Interactive Features"}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.strong,{children:"References"})}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/d3/d3-scale/blob/main/README.md",children:"D3-scale"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/d3/d3-selection/blob/main/README.md",children:"D3-selection"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/d3/d3-array/blob/main/README.md",children:"D3-array"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/d3/d3-axis/blob/main/README.md",children:"D3-axis"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/wiki/How-to-apply-theme-to-Fluent-UI-React-components",children:"How to apply theme"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/wiki/Theming",children:"Theming"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://developer.microsoft.com/en-us/fluentui#/controls/web/verticalbarchart/verticalstackedbarchart",children:"Vertical Stacked Bar Chart"})}),"\n"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.strong,{children:"Appendix"}),"\nThe mathematical formulae used in the Vertical Stacked bar chart component are as follows:"]}),"\n"]}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsx)(t.li,{children:"Formula for calculating the\xa0yBarScale\xa0using\xa0d3ScaleLinear:"}),"\n"]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:"yBarScale = d3ScaleLinear()\n\n.domain([0, yMax])\n\n.range([0, containerHeight - margins.bottom! - margins.top!])\n"})}),"\n",(0,a.jsxs)(t.ol,{start:"2",children:["\n",(0,a.jsx)(t.li,{children:"Formula for calculating the\xa0xBarScale\xa0for numeric data using\xa0d3ScaleLinear:"}),"\n"]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:"xMax = d3Max(this.\\_dataset, (point: IDataPoint) => point.x as number)!\n\nxMin = d3Min(this.\\_dataset, (point: IDataPoint) => point.x as number)!\n\nxBarScale = d3ScaleLinear()\n\n.domain(this.\\_isRtl ? [xMax, xMin] : [xMin, xMax])\n\n.nice()\n\n.range([\n\n` `margins.left! + \\_domainMargin,\n\n` `containerWidth - margins.right! - \\_barWidth - \\_domainMargin,\n\n` `])\n"})}),"\n",(0,a.jsxs)(t.ol,{start:"3",children:["\n",(0,a.jsx)(t.li,{children:"Formula for calculating the\xa0xBarScale\xa0for categorical data using\xa0d3ScaleBand:"}),"\n"]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:"xBarScale = d3ScaleBand()\n\n.domain(\\_xAxisLabels)\n\n.range([margins.left! + \\_domainMargin, containerWidth - margins.right! - \\_domainMargin])\n\n.paddingInner(2 / 3)\n"})}),"\n",(0,a.jsxs)(t.ol,{start:"4",children:["\n",(0,a.jsx)(t.li,{children:"Formula for calculating the height of each bar in the chart:"}),"\n"]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:"barHeight = heightValueScale \\* point.data;\n\nWhen displaying gaps between the bars, the height of each bar is adjusted so that the total of all bars is not changed by the gaps\n\ntotalData = bars.reduce((iter, value) => iter + value.data, 0)\n\ntotalHeight = defaultTotalHeight ?? yBarScale(totalData)\n\ngaps = barGapMax && bars.length - 1\n\ngapHeight = gaps && Math.max(barGapMin, Math.min(barGapMax, (totalHeight \\* barGapMultiplier) / gaps))\n\nheightValueScale = (totalHeight - gapHeight \\* gaps) / totalData\n\nif (barHeight < barMinimumHeight) {\n\n` `barHeight = barMinimumHeight\n\n}\n\nDefault values:\n\nbarGapMax = props.barGapMax (default value = 0)\n\nWhen displaying gaps between bars, the max height of the gap is given in the props. The actual gap is calculated with this multiplier, with a minimum gap of 1 pixel.\n\nbarGapMin = 1\n\nbarGapMultiplier = 0.2\n"})}),"\n",(0,a.jsxs)(t.ol,{start:"5",children:["\n",(0,a.jsx)(t.li,{children:"Formula for calculating the x position of each bar in the chart:"}),"\n"]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:"x = xBarScale(bar.category) + (this.\\_barWidth / 2)\n"})}),"\n",(0,a.jsx)(t.hr,{})]})}function d(e={}){const{wrapper:t}={...(0,i.a)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},4757:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/VSBC1-de2ee9ef0194f703abc7f8806bc869e7.png"},3160:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/VSBC2-3decd6986a55117047292cb20444e7c1.png"},9845:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/VSBC3-01489e0f79d82ab97318b9dc49952bae.png"},1151:(e,t,n)=>{n.d(t,{Z:()=>h,a:()=>r});var a=n(7294);const i={},s=a.createContext(i);function r(e){const t=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function h(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),a.createElement(s.Provider,{value:t},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/df751193.11c160c7.js b/assets/js/df751193.11c160c7.js
deleted file mode 100644
index aa5af5ce7e..0000000000
--- a/assets/js/df751193.11c160c7.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[5966],{5321:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>h,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>c});var s=n(5893),a=n(1151);const r={},i="Contributor guide: Donut Chart",o={id:"Charting-Concepts/DonutChart",title:"Contributor guide: Donut Chart",description:"DonutChart1.png",source:"@site/../../docs/Charting-Concepts/DonutChart.md",sourceDirName:"Charting-Concepts",slug:"/Charting-Concepts/DonutChart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/DonutChart",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Contributor guide: Area Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/AreaChart"},next:{title:"Contributor guide: Gauge Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/GaugeChart"}},h={},c=[{value:"Use cases",id:"use-cases",level:2},{value:"Mathematical/Geometrical concepts",id:"mathematicalgeometrical-concepts",level:2},{value:"Dev Design details",id:"dev-design-details",level:2}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"contributor-guide-donut-chart",children:"Contributor guide: Donut Chart"}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"DonutChart1.png",src:n(3088).Z+"",width:"749",height:"529"})}),"\n",(0,s.jsx)(t.p,{children:"A Donut chart is a type of chart used to visualize data as a circular shape with the central area hollow. It is similar to a Pie chart, but with the area in the center cut out instead of a solid circle.\nDonut charts are useful for displaying data as parts of a whole, where each segment represents a percentage or proportion of the total. The segments are typically colored differently to make them easier to distinguish."}),"\n",(0,s.jsx)(t.h2,{id:"use-cases",children:"Use cases"}),"\n",(0,s.jsx)(t.p,{children:"Donut charts are commonly used in business and finance to display financial data, such as revenue or expenses. They are also used in marketing to display customer demographics or market share. Here are some real-world use cases for Donut charts:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Sales data: Donut charts can be used to display sales data, where each segment represents a product or service category. This can help businesses identify which products or services are performing well and which ones need improvement."}),"\n",(0,s.jsx)(t.li,{children:"Budget data: Donut charts can be used to display budget data, where each segment represents a budget category. This can help businesses identify areas where they are overspending or underspending."}),"\n",(0,s.jsx)(t.li,{children:"Demographic data: Donut charts can be used to display demographic data, where each segment represents a different demographic group. This can help businesses identify their target audience and tailor their marketing efforts accordingly."}),"\n",(0,s.jsx)(t.li,{children:"Market share data: Donut charts can be used to display market share data, where each segment represents a different company or brand. This can help businesses identify their competitors and their position in the market."}),"\n",(0,s.jsx)(t.li,{children:"Survey data: Donut charts can be used to display survey data, where each segment represents a different response option. This can help businesses identify the most popular responses and areas where improvements can be made."}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Overall, Donut charts are useful for displaying data as parts of a whole, where each segment represents a percentage or proportion of the total. They are a popular choice for visualizing financial, marketing, and survey data."}),"\n",(0,s.jsx)(t.h2,{id:"mathematicalgeometrical-concepts",children:"Mathematical/Geometrical concepts"}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"DonutChart2.png",src:n(5269).Z+"",width:"1117",height:"662"})}),"\n",(0,s.jsx)(t.p,{children:"The d3-shape library provides various functions for creating and manipulating shapes such as arcs, lines, and areas. Following are the main mathematical/geometrical concepts that are used while drawing a donut chart."}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"d3.arc():"})," Creates an arc generator function that can be used to create an SVG arc path. The arc generator function takes in an object that specifies the start and end angles of the arc, as well as the inner and outer radii of the arc. The following are some of the main props that the arc generator accepts:"]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{children:"- startAngle: The starting angle of the arc, in radians. The default value is 0.\n- endAngle: The ending angle of the arc, in radians. The default value is 2\u03c0 (i.e., a full circle).\n- innerRadius: The inner radius of the arc, in pixels. The default value is 0.\n- outerRadius: The outer radius of the arc, in pixels. This prop is required.\n- padAngle: The amount of padding to add between adjacent arcs, in radians. The default value is 0.\n"})}),"\n",(0,s.jsxs)(t.ol,{start:"2",children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"d3.pie():"})," creates a pie generator function that can be used to create a pie chart. The pie generator function takes in an array of data and returns an array of objects that represent each data point in the pie chart."]}),"\n"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Pie formation: The function uses the data values to calculate the angles for each data point. It then uses the angles to create a series of arcs that represent each data point in the pie chart. The arcs are created using the d3.arc() function, which creates an SVG arc path based on the start and end angles of the arc."}),"\n",(0,s.jsx)(t.li,{children:"Supported props: The function also provides various options for customizing the pie chart, such as the pie start angle, the pie end angle, and the sort order of the data points. These options can be used to create different types of pie charts, such as donut charts or exploded pie charts.\nHere are the main props that can be passed to the pie generator function:"}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{children:"- data: the input datum; the corresponding element in the input data array.\n- value: the numeric value of the arc.\n- index: the zero-based sorted index of the arc.\n- startAngle: The starting angle of the pie chart, in radians. The default value is 0.\n- endAngle: The ending angle of the pie chart, in radians. The default value is 2\u03c0 (i.e., a full circle).\n- padAngle: The amount of padding to add between adjacent data points, in radians. The default zalue is 0.\n"})}),"\n",(0,s.jsx)(t.h2,{id:"dev-design-details",children:"Dev Design details"}),"\n",(0,s.jsx)(t.p,{children:"This section contains the technical design of various sub components of a donut chart and how they interact with each other. This section can also contain any key interface or class structure of the donut chart.\nThe Donut chart consists of the following sub-components:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.strong,{children:"Arc:"})}),"\n"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Arc creation:"})," This component is used to render an arc in a pie chart, and it receives various props such as the arc data, color, and focus state. The component uses the d3-shape library to create the arc shape, and it also uses the @fluentui/react library to apply styles to the component."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Arc event handlers:"})," The Arc component has several methods that handle events such as _onFocus, _hoverOn, _hoverOff, _onBlur and onClick. These methods are used to update the component's state and to trigger callbacks that are passed in as props. The component also has a method called _renderArcLabel that is used to render the label for the arc."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Arc update:"})," The Arc component uses the getDerivedStateFromProps method to update the chart whenever new props are received. This method calls the _updateChart function, which updates the inner and outer radius of the arc based on the new props.\nOverall, the Arc component is a reusable component that can be used to render an arc in a pie chart. It is highly customizable and can be used in a variety of contexts."]}),"\n"]}),"\n",(0,s.jsxs)(t.ol,{start:"2",children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.strong,{children:"Pie:"})}),"\n"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Pie creation:"})," This component is used to render a pie chart, and it receives various props such as the chart data, inner and outer radius, and callbacks for hover and focus events. The component uses the d3-shape library to create the pie chart shape, and it also uses the @fluentui/react library to apply styles to the component."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Constraint:"})," The inner radius has to be greater than 0."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Pie handlers:"})," The Pie component has several methods that handle events such as _focusCallback and _hoverCallback. These methods are used to update the component's state and to trigger callbacks that are passed in as props. The component also has a method called _computeTotalValue that is used to calculate the total value of the chart data."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Pie update:"})," The Pie component uses the getDerivedStateFromProps method to update the chart whenever new props are received. This method calls the _updateChart function, which updates the inner and outer radius of the chart based on the new props.\nOverall, the Pie component is a reusable component that can be used to render a pie chart. It is highly customizable and can be used in a variety of contexts."]}),"\n"]}),"\n",(0,s.jsxs)(t.ol,{start:"3",children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.strong,{children:"Callout:"})}),"\n"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Callout creation:"})," The DonutChart component has a method called _renderCallouts that is used to render callouts for the data points. This method creates a Callout component from the @fluentui/react library and passes in various props such as the target element, the callout ID, and the callout content. The method also sets up various actions for the callout, such as hover and dismiss actions."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Callout behaviour:"})," The Callout component is used to display additional information about a data point when it is hovered over. It is positioned relative to the hovered data point and displays information such as the data point's legend, value, and color. The Callout component is highly customizable and can be used in a variety of contexts."]}),"\n"]}),"\n",(0,s.jsxs)(t.ol,{start:"4",children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.strong,{children:"Legends:"})}),"\n"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Legend creation:"})," The DonutChart component has a private method called _createLegends that is used to create the legends for the chart. This method takes in the chart data and color palette as arguments and returns a JSX element that contains the legends. The method maps over the chart data and creates a legend for each data point. It also sets up various actions for each legend, such as hover and click actions."]}),"\n"]}),"\n",(0,s.jsxs)(t.ol,{start:"5",children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.strong,{children:"Inner Text:"})}),"\n"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Inner text description:"})," The inner text in a Donut chart is the text displayed in the centre of the donut chart, inside the hollow region. This text can be used to display additional information about the data being displayed, such as the total value or the name of the data set."]}),"\n"]}),"\n",(0,s.jsxs)(t.ol,{start:"6",children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Rendering details"}),"\nThe donut chart uses d3 SVG based rendering, which follows the following render cycles:"]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{children:"Invocation cycle: Donut Chart -> Pie -> Arc\nRendering cycle: Donut chart <- d3.pie() <- d3.arc()\n"})}),"\n",(0,s.jsxs)(t.ol,{start:"7",children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.strong,{children:"Error scenarios"})}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Currently, donut chart cannot handle long inner texts which overflows and results in error state. Fix for this issue is already in PR."}),"\n",(0,s.jsxs)(t.ol,{start:"8",children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Localization aspects"}),"\nCurrently, donut chart provides localization only for the inner text."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Testing"}),"\nThe manual, component and unit testing of donut charts have been completed. Following is the improvement in code coverage:"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"DonutChart3.png",src:n(2621).Z+"",width:"2475",height:"537"})}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["Component Tests:\no Work item: ",(0,s.jsx)(t.a,{href:"https://uifabric.visualstudio.com/iss/_workitems/edit/6798/",children:"https://uifabric.visualstudio.com/iss/_workitems/edit/6798/"}),"\no Test plan: ",(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/blob/master/packages/react-charting/docs/TestPlans/DonutChart/ComponentTests.md",children:"https://github.com/microsoft/fluentui/blob/master/packages/react-charting/docs/TestPlans/DonutChart/ComponentTests.md"})]}),"\n",(0,s.jsxs)(t.li,{children:["Unit Tests:\no Work item: ",(0,s.jsx)(t.a,{href:"https://uifabric.visualstudio.com/iss/_workitems/edit/7403",children:"https://uifabric.visualstudio.com/iss/_workitems/edit/7403"})]}),"\n"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Accessibility"}),"\nFAST pass checks resulted in no error for Donut chart. Link to the FAST pass tool: ",(0,s.jsx)(t.a,{href:"https://accessibilityinsights.io/docs/web/getstarted/fastpass/",children:"https://accessibilityinsights.io/docs/web/getstarted/fastpass/"}),"\nOur charts have elaborate accessibility support. The charts are WCAG 2.1 MAS C compliant for accessibility.\nConsumers can define their own aria labels for each point by setting the xAxisCalloutAccessibilityData and callOutAccessibilityData properties."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Theming"}),'\nThe palette for donut chart is set from the "theme" prop as passed to the component during rendering. Both light and dark themes are supported and users can create there own theme too. Ref[3] and Ref[4] explains theming in detail.']}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Debugging"}),"\nThe detailed steps on debugging has been given in\xa0",(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui-charting-contrib/blob/main/docs/Debugging.md",children:"Debugging"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Variants"}),"\nFollowing are the variants of donut chart: ",(0,s.jsx)(t.a,{href:"https://developer.microsoft.com/en-us/fluentui#/controls/web/donutchart",children:"Ref2"})]}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"Basic Donut Chart: Only basic props are provided."}),"\n",(0,s.jsx)(t.li,{children:"Dynamic Donut Chart: The data and pie colors can change."}),"\n",(0,s.jsx)(t.li,{children:"Custom Callout: Can show customized callout data."}),"\n",(0,s.jsx)(t.li,{children:"Custom Accessibility: Providing custom aria labels."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Interaction"}),"\nFollowing are the interactions that are allowed for donut chart:"]}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"Mouse Events:\na. On mouse over on the donut chart, should render callout.\nb. On mouse move on Pie 1 (step 1) -> mouse leave (step 2) -> mouse move on Pie 2 (step 3), should render the callout of the Pie 2.\nc. On mouse over, callout should be defined, on mouse leave, callout should disappear.\nd. On mouse over on legends, should highlight the corresponding pie.\ne. On mouse over on legends, should change the value inside donut with the legend value.\nf. On click on Pie, should highlight the corresponding pie with aria-selected set to \u201ctrue\u201d and tabIndex set to 0.\ng. On mouse out after mouse over on first legend, should have opacity 0.1 for second Pie initially (during mouseOver on first legend) and opacity set to 1 for both the Pies on mouse out."}),"\n",(0,s.jsx)(t.li,{children:"Keyboard Events:\na. On focus on a Pie, should render the corresponding callout.\nb. On blur on a Pie, should remove focus from the corresponding Pie."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Some notable PRs and their brief description"})}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/commit/b60d3dfb35367467568d91c2933bb7053e9b716b",children:"Adding the Donut Chart main component"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/commit/5349c8cbc522ff7b9eac2e5858cbad092d22eb82",children:"Adding Tests for Donut Chart using React Testing Library"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/commit/50ee71862affde61ace35edcb5c3d6f67928f343",children:"Allow focus navigation with tab key in donut chart (Accessibility)"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Learnings"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:"While implementing the tests using react testing library, it was found that certain browser functions like getComputedTextLength() cannot be unit tested and needs to be tested End-to-End only."}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:"Order of imports are important.\nFor example: for Vertical bar charts tests, improper sequencing of the imports (data first and then render) results in incorrect and incopmlete rendering of charts:"}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{children:"import { chartPoints } from '../VerticalBarChart/VerticalBarChart.test';\nimport { render, screen, queryAllByAttribute, fireEvent, act } from '@testing- \nlibrary/react';\nHowever, the following results in correct rendering:\n\nimport { render, screen, queryAllByAttribute } from '@testing-library/react';\nimport { chartPoints } from './VerticalBarChart.test';\n"})}),"\n",(0,s.jsxs)(t.ol,{start:"3",children:["\n",(0,s.jsx)(t.li,{children:"Certain props need async await structure (waitFor in react testing library) for different props or nested SVGs to render."}),"\n"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.strong,{children:"Known issues"})}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["The value inside Donut chart overflows. Should be ideally wrapping inside the donut chart. Work item 5321 captures this bug. This item has already been fixed in this ",(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/26192",children:"PR"}),"."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.strong,{children:"Future improvements"})}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Following are the list of future improvements for the donut chart:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"The donut chart component can be extended to support Nested Donut Charts which can also be used to display multiple sets of data, where each ring represents a different data set."}),"\n"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Design figma"}),"\nDonut Chart Figma: ",(0,s.jsx)(t.a,{href:"https://www.figma.com/file/WOoCs0CmNYZhYl9xXeCGpi/Data-viz-(Archive)?type=design&node-id=3361-77520&mode=design&t=lvW5txXwtfI7wvOI-0",children:"Link"})]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Performance"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The performance aspect of a donut chart refers to how efficiently and effectively it conveys information to the viewer. Here are some key considerations regarding the performance of a line chart:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Data Visualization Efficiency"}),"\n",(0,s.jsx)(t.li,{children:"Clarity and Simplicity"}),"\n",(0,s.jsx)(t.li,{children:"Responsiveness"}),"\n",(0,s.jsx)(t.li,{children:"Handling Large Datasets"}),"\n",(0,s.jsxs)(t.li,{children:["Interactive Features\nWe use Lighthouse tool for measuring the performance of our charts. Following are few of the scenarios for which we measure the performance score for donut chart:","\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"chart with 100 data points"}),"\n",(0,s.jsx)(t.li,{children:"charts with localized data\nAll of the above scenarios have 95+ Lighthouse score. We are efficient in terms of the performance of the donut chart."}),"\n"]}),"\n"]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,a.a)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},3088:(e,t,n)=>{n.d(t,{Z:()=>s});const s=n.p+"assets/images/DonutChart1-9f10b2df3479f2d893fa20709ae72eb0.png"},5269:(e,t,n)=>{n.d(t,{Z:()=>s});const s=n.p+"assets/images/DonutChart2-8fa01069f0af01a5a142c8909c588c1f.png"},2621:(e,t,n)=>{n.d(t,{Z:()=>s});const s=n.p+"assets/images/DonutChart3-43bb764e6b1372961370da02b2f7196b.png"},1151:(e,t,n)=>{n.d(t,{Z:()=>o,a:()=>i});var s=n(7294);const a={},r=s.createContext(a);function i(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/df751193.4637bd9c.js b/assets/js/df751193.4637bd9c.js
new file mode 100644
index 0000000000..e1ee1f6dd9
--- /dev/null
+++ b/assets/js/df751193.4637bd9c.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[5966],{5321:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>h,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>c});var s=n(5893),a=n(1151);const r={},i="Donut Chart",o={id:"Charting-Concepts/DonutChart",title:"Donut Chart",description:"DonutChart1.png",source:"@site/../../docs/Charting-Concepts/DonutChart.md",sourceDirName:"Charting-Concepts",slug:"/Charting-Concepts/DonutChart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/DonutChart",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Area Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/AreaChart"},next:{title:"Gauge Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/GaugeChart"}},h={},c=[{value:"Use cases",id:"use-cases",level:2},{value:"Mathematical/Geometrical concepts",id:"mathematicalgeometrical-concepts",level:2},{value:"Dev Design details",id:"dev-design-details",level:2}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"donut-chart",children:"Donut Chart"}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"DonutChart1.png",src:n(3088).Z+"",width:"749",height:"529"})}),"\n",(0,s.jsx)(t.p,{children:"A Donut chart is a type of chart used to visualize data as a circular shape with the central area hollow. It is similar to a Pie chart, but with the area in the center cut out instead of a solid circle.\nDonut charts are useful for displaying data as parts of a whole, where each segment represents a percentage or proportion of the total. The segments are typically colored differently to make them easier to distinguish."}),"\n",(0,s.jsx)(t.h2,{id:"use-cases",children:"Use cases"}),"\n",(0,s.jsx)(t.p,{children:"Donut charts are commonly used in business and finance to display financial data, such as revenue or expenses. They are also used in marketing to display customer demographics or market share. Here are some real-world use cases for Donut charts:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Sales data: Donut charts can be used to display sales data, where each segment represents a product or service category. This can help businesses identify which products or services are performing well and which ones need improvement."}),"\n",(0,s.jsx)(t.li,{children:"Budget data: Donut charts can be used to display budget data, where each segment represents a budget category. This can help businesses identify areas where they are overspending or underspending."}),"\n",(0,s.jsx)(t.li,{children:"Demographic data: Donut charts can be used to display demographic data, where each segment represents a different demographic group. This can help businesses identify their target audience and tailor their marketing efforts accordingly."}),"\n",(0,s.jsx)(t.li,{children:"Market share data: Donut charts can be used to display market share data, where each segment represents a different company or brand. This can help businesses identify their competitors and their position in the market."}),"\n",(0,s.jsx)(t.li,{children:"Survey data: Donut charts can be used to display survey data, where each segment represents a different response option. This can help businesses identify the most popular responses and areas where improvements can be made."}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Overall, Donut charts are useful for displaying data as parts of a whole, where each segment represents a percentage or proportion of the total. They are a popular choice for visualizing financial, marketing, and survey data."}),"\n",(0,s.jsx)(t.h2,{id:"mathematicalgeometrical-concepts",children:"Mathematical/Geometrical concepts"}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"DonutChart2.png",src:n(5269).Z+"",width:"1117",height:"662"})}),"\n",(0,s.jsx)(t.p,{children:"The d3-shape library provides various functions for creating and manipulating shapes such as arcs, lines, and areas. Following are the main mathematical/geometrical concepts that are used while drawing a donut chart."}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"d3.arc():"})," Creates an arc generator function that can be used to create an SVG arc path. The arc generator function takes in an object that specifies the start and end angles of the arc, as well as the inner and outer radii of the arc. The following are some of the main props that the arc generator accepts:"]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{children:"- startAngle: The starting angle of the arc, in radians. The default value is 0.\n- endAngle: The ending angle of the arc, in radians. The default value is 2\u03c0 (i.e., a full circle).\n- innerRadius: The inner radius of the arc, in pixels. The default value is 0.\n- outerRadius: The outer radius of the arc, in pixels. This prop is required.\n- padAngle: The amount of padding to add between adjacent arcs, in radians. The default value is 0.\n"})}),"\n",(0,s.jsxs)(t.ol,{start:"2",children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"d3.pie():"})," creates a pie generator function that can be used to create a pie chart. The pie generator function takes in an array of data and returns an array of objects that represent each data point in the pie chart."]}),"\n"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Pie formation: The function uses the data values to calculate the angles for each data point. It then uses the angles to create a series of arcs that represent each data point in the pie chart. The arcs are created using the d3.arc() function, which creates an SVG arc path based on the start and end angles of the arc."}),"\n",(0,s.jsx)(t.li,{children:"Supported props: The function also provides various options for customizing the pie chart, such as the pie start angle, the pie end angle, and the sort order of the data points. These options can be used to create different types of pie charts, such as donut charts or exploded pie charts.\nHere are the main props that can be passed to the pie generator function:"}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{children:"- data: the input datum; the corresponding element in the input data array.\n- value: the numeric value of the arc.\n- index: the zero-based sorted index of the arc.\n- startAngle: The starting angle of the pie chart, in radians. The default value is 0.\n- endAngle: The ending angle of the pie chart, in radians. The default value is 2\u03c0 (i.e., a full circle).\n- padAngle: The amount of padding to add between adjacent data points, in radians. The default zalue is 0.\n"})}),"\n",(0,s.jsx)(t.h2,{id:"dev-design-details",children:"Dev Design details"}),"\n",(0,s.jsx)(t.p,{children:"This section contains the technical design of various sub components of a donut chart and how they interact with each other. This section can also contain any key interface or class structure of the donut chart.\nThe Donut chart consists of the following sub-components:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.strong,{children:"Arc:"})}),"\n"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Arc creation:"})," This component is used to render an arc in a pie chart, and it receives various props such as the arc data, color, and focus state. The component uses the d3-shape library to create the arc shape, and it also uses the @fluentui/react library to apply styles to the component."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Arc event handlers:"})," The Arc component has several methods that handle events such as _onFocus, _hoverOn, _hoverOff, _onBlur and onClick. These methods are used to update the component's state and to trigger callbacks that are passed in as props. The component also has a method called _renderArcLabel that is used to render the label for the arc."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Arc update:"})," The Arc component uses the getDerivedStateFromProps method to update the chart whenever new props are received. This method calls the _updateChart function, which updates the inner and outer radius of the arc based on the new props.\nOverall, the Arc component is a reusable component that can be used to render an arc in a pie chart. It is highly customizable and can be used in a variety of contexts."]}),"\n"]}),"\n",(0,s.jsxs)(t.ol,{start:"2",children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.strong,{children:"Pie:"})}),"\n"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Pie creation:"})," This component is used to render a pie chart, and it receives various props such as the chart data, inner and outer radius, and callbacks for hover and focus events. The component uses the d3-shape library to create the pie chart shape, and it also uses the @fluentui/react library to apply styles to the component."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Constraint:"})," The inner radius has to be greater than 0."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Pie handlers:"})," The Pie component has several methods that handle events such as _focusCallback and _hoverCallback. These methods are used to update the component's state and to trigger callbacks that are passed in as props. The component also has a method called _computeTotalValue that is used to calculate the total value of the chart data."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Pie update:"})," The Pie component uses the getDerivedStateFromProps method to update the chart whenever new props are received. This method calls the _updateChart function, which updates the inner and outer radius of the chart based on the new props.\nOverall, the Pie component is a reusable component that can be used to render a pie chart. It is highly customizable and can be used in a variety of contexts."]}),"\n"]}),"\n",(0,s.jsxs)(t.ol,{start:"3",children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.strong,{children:"Callout:"})}),"\n"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Callout creation:"})," The DonutChart component has a method called _renderCallouts that is used to render callouts for the data points. This method creates a Callout component from the @fluentui/react library and passes in various props such as the target element, the callout ID, and the callout content. The method also sets up various actions for the callout, such as hover and dismiss actions."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Callout behaviour:"})," The Callout component is used to display additional information about a data point when it is hovered over. It is positioned relative to the hovered data point and displays information such as the data point's legend, value, and color. The Callout component is highly customizable and can be used in a variety of contexts."]}),"\n"]}),"\n",(0,s.jsxs)(t.ol,{start:"4",children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.strong,{children:"Legends:"})}),"\n"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Legend creation:"})," The DonutChart component has a private method called _createLegends that is used to create the legends for the chart. This method takes in the chart data and color palette as arguments and returns a JSX element that contains the legends. The method maps over the chart data and creates a legend for each data point. It also sets up various actions for each legend, such as hover and click actions."]}),"\n"]}),"\n",(0,s.jsxs)(t.ol,{start:"5",children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.strong,{children:"Inner Text:"})}),"\n"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Inner text description:"})," The inner text in a Donut chart is the text displayed in the centre of the donut chart, inside the hollow region. This text can be used to display additional information about the data being displayed, such as the total value or the name of the data set."]}),"\n"]}),"\n",(0,s.jsxs)(t.ol,{start:"6",children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Rendering details"}),"\nThe donut chart uses d3 SVG based rendering, which follows the following render cycles:"]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{children:"Invocation cycle: Donut Chart -> Pie -> Arc\nRendering cycle: Donut chart <- d3.pie() <- d3.arc()\n"})}),"\n",(0,s.jsxs)(t.ol,{start:"7",children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.strong,{children:"Error scenarios"})}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Currently, donut chart cannot handle long inner texts which overflows and results in error state. Fix for this issue is already in PR."}),"\n",(0,s.jsxs)(t.ol,{start:"8",children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Localization aspects"}),"\nCurrently, donut chart provides localization only for the inner text."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Testing"}),"\nThe manual, component and unit testing of donut charts have been completed. Following is the improvement in code coverage:"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"DonutChart3.png",src:n(2621).Z+"",width:"2475",height:"537"})}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["Component Tests:\no Work item: ",(0,s.jsx)(t.a,{href:"https://uifabric.visualstudio.com/iss/_workitems/edit/6798/",children:"https://uifabric.visualstudio.com/iss/_workitems/edit/6798/"}),"\no Test plan: ",(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/blob/master/packages/react-charting/docs/TestPlans/DonutChart/ComponentTests.md",children:"https://github.com/microsoft/fluentui/blob/master/packages/react-charting/docs/TestPlans/DonutChart/ComponentTests.md"})]}),"\n",(0,s.jsxs)(t.li,{children:["Unit Tests:\no Work item: ",(0,s.jsx)(t.a,{href:"https://uifabric.visualstudio.com/iss/_workitems/edit/7403",children:"https://uifabric.visualstudio.com/iss/_workitems/edit/7403"})]}),"\n"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Accessibility"}),"\nFAST pass checks resulted in no error for Donut chart. Link to the FAST pass tool: ",(0,s.jsx)(t.a,{href:"https://accessibilityinsights.io/docs/web/getstarted/fastpass/",children:"https://accessibilityinsights.io/docs/web/getstarted/fastpass/"}),"\nOur charts have elaborate accessibility support. The charts are WCAG 2.1 MAS C compliant for accessibility.\nConsumers can define their own aria labels for each point by setting the xAxisCalloutAccessibilityData and callOutAccessibilityData properties."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Theming"}),'\nThe palette for donut chart is set from the "theme" prop as passed to the component during rendering. Both light and dark themes are supported and users can create there own theme too. Ref[3] and Ref[4] explains theming in detail.']}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Debugging"}),"\nThe detailed steps on debugging has been given in\xa0",(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui-charting-contrib/blob/main/docs/Debugging.md",children:"Debugging"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Variants"}),"\nFollowing are the variants of donut chart: ",(0,s.jsx)(t.a,{href:"https://developer.microsoft.com/en-us/fluentui#/controls/web/donutchart",children:"Ref2"})]}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"Basic Donut Chart: Only basic props are provided."}),"\n",(0,s.jsx)(t.li,{children:"Dynamic Donut Chart: The data and pie colors can change."}),"\n",(0,s.jsx)(t.li,{children:"Custom Callout: Can show customized callout data."}),"\n",(0,s.jsx)(t.li,{children:"Custom Accessibility: Providing custom aria labels."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Interaction"}),"\nFollowing are the interactions that are allowed for donut chart:"]}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"Mouse Events:\na. On mouse over on the donut chart, should render callout.\nb. On mouse move on Pie 1 (step 1) -> mouse leave (step 2) -> mouse move on Pie 2 (step 3), should render the callout of the Pie 2.\nc. On mouse over, callout should be defined, on mouse leave, callout should disappear.\nd. On mouse over on legends, should highlight the corresponding pie.\ne. On mouse over on legends, should change the value inside donut with the legend value.\nf. On click on Pie, should highlight the corresponding pie with aria-selected set to \u201ctrue\u201d and tabIndex set to 0.\ng. On mouse out after mouse over on first legend, should have opacity 0.1 for second Pie initially (during mouseOver on first legend) and opacity set to 1 for both the Pies on mouse out."}),"\n",(0,s.jsx)(t.li,{children:"Keyboard Events:\na. On focus on a Pie, should render the corresponding callout.\nb. On blur on a Pie, should remove focus from the corresponding Pie."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Some notable PRs and their brief description"})}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/commit/b60d3dfb35367467568d91c2933bb7053e9b716b",children:"Adding the Donut Chart main component"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/commit/5349c8cbc522ff7b9eac2e5858cbad092d22eb82",children:"Adding Tests for Donut Chart using React Testing Library"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/commit/50ee71862affde61ace35edcb5c3d6f67928f343",children:"Allow focus navigation with tab key in donut chart (Accessibility)"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Learnings"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:"While implementing the tests using react testing library, it was found that certain browser functions like getComputedTextLength() cannot be unit tested and needs to be tested End-to-End only."}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:"Order of imports are important.\nFor example: for Vertical bar charts tests, improper sequencing of the imports (data first and then render) results in incorrect and incopmlete rendering of charts:"}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{children:"import { chartPoints } from '../VerticalBarChart/VerticalBarChart.test';\nimport { render, screen, queryAllByAttribute, fireEvent, act } from '@testing- \nlibrary/react';\nHowever, the following results in correct rendering:\n\nimport { render, screen, queryAllByAttribute } from '@testing-library/react';\nimport { chartPoints } from './VerticalBarChart.test';\n"})}),"\n",(0,s.jsxs)(t.ol,{start:"3",children:["\n",(0,s.jsx)(t.li,{children:"Certain props need async await structure (waitFor in react testing library) for different props or nested SVGs to render."}),"\n"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.strong,{children:"Known issues"})}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["The value inside Donut chart overflows. Should be ideally wrapping inside the donut chart. Work item 5321 captures this bug. This item has already been fixed in this ",(0,s.jsx)(t.a,{href:"https://github.com/microsoft/fluentui/pull/26192",children:"PR"}),"."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.strong,{children:"Future improvements"})}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Following are the list of future improvements for the donut chart:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"The donut chart component can be extended to support Nested Donut Charts which can also be used to display multiple sets of data, where each ring represents a different data set."}),"\n"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Design figma"}),"\nDonut Chart Figma: ",(0,s.jsx)(t.a,{href:"https://www.figma.com/file/WOoCs0CmNYZhYl9xXeCGpi/Data-viz-(Archive)?type=design&node-id=3361-77520&mode=design&t=lvW5txXwtfI7wvOI-0",children:"Link"})]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Performance"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The performance aspect of a donut chart refers to how efficiently and effectively it conveys information to the viewer. Here are some key considerations regarding the performance of a line chart:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Data Visualization Efficiency"}),"\n",(0,s.jsx)(t.li,{children:"Clarity and Simplicity"}),"\n",(0,s.jsx)(t.li,{children:"Responsiveness"}),"\n",(0,s.jsx)(t.li,{children:"Handling Large Datasets"}),"\n",(0,s.jsxs)(t.li,{children:["Interactive Features\nWe use Lighthouse tool for measuring the performance of our charts. Following are few of the scenarios for which we measure the performance score for donut chart:","\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"chart with 100 data points"}),"\n",(0,s.jsx)(t.li,{children:"charts with localized data\nAll of the above scenarios have 95+ Lighthouse score. We are efficient in terms of the performance of the donut chart."}),"\n"]}),"\n"]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,a.a)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},3088:(e,t,n)=>{n.d(t,{Z:()=>s});const s=n.p+"assets/images/DonutChart1-9f10b2df3479f2d893fa20709ae72eb0.png"},5269:(e,t,n)=>{n.d(t,{Z:()=>s});const s=n.p+"assets/images/DonutChart2-8fa01069f0af01a5a142c8909c588c1f.png"},2621:(e,t,n)=>{n.d(t,{Z:()=>s});const s=n.p+"assets/images/DonutChart3-43bb764e6b1372961370da02b2f7196b.png"},1151:(e,t,n)=>{n.d(t,{Z:()=>o,a:()=>i});var s=n(7294);const a={},r=s.createContext(a);function i(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/e1621294.0a2fc20e.js b/assets/js/e1621294.0a2fc20e.js
new file mode 100644
index 0000000000..c0a63ffc73
--- /dev/null
+++ b/assets/js/e1621294.0a2fc20e.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[3633],{7037:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>h,contentTitle:()=>r,default:()=>d,frontMatter:()=>s,metadata:()=>o,toc:()=>l});var a=t(5893),i=t(1151);const s={},r="Sparkline Chart",o={id:"Charting-Concepts/SparklineChart",title:"Sparkline Chart",description:"Sparkline1.png",source:"@site/../../docs/Charting-Concepts/SparklineChart.md",sourceDirName:"Charting-Concepts",slug:"/Charting-Concepts/SparklineChart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/SparklineChart",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Sankey Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/SankeyChart"},next:{title:"Stacked Bar Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/StackedBarChart"}},h={},l=[];function c(e){const n={a:"a",code:"code",em:"em",h1:"h1",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h1,{id:"sparkline-chart",children:"Sparkline Chart"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{alt:"Sparkline1.png",src:t(5458).Z+"",width:"919",height:"326"})}),"\n",(0,a.jsx)(n.p,{children:"A Sparkline chart is a small, simple chart that is used to display trends over time or changes in data. It is typically used in dashboards or reports where space is limited. The chart consists of a line that shows the trend over time, and an area that shows the range of the data. The chart is designed to be small and compact, so it can be used in dashboards or reports where space is limited."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Use cases"}),"\nFollowing are some use cases for Sparkline Chart:","\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Displaying trends over time:"}),"\xa0Sparkline charts are great for showing trends over time, such as stock prices, website traffic, or weather patterns. By compressing the data into a small space, sparklines can quickly show whether the trend is up, down, or flat."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Showing changes in data:"}),"\xa0Sparkline charts can also be used to show changes in data, such as the number of sales per day or the number of website visitors per hour. By comparing the data points to each other, sparklines can show whether the changes are significant or not."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Comparing multiple data sets:"}),"\xa0Sparkline charts can be used to compare multiple data sets, such as the sales of different products or the performance of different teams. By placing the sparklines side by side, it's easy to see which data set is performing better."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Visualizing data in a small space:"}),"\xa0Sparkline charts are great for visualizing data in a small space, such as a dashboard or a report. By compressing the data into a small chart, sparklines can provide a quick overview of the data without taking up too much space."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Providing a quick overview of data:"}),"\xa0Sparkline charts can be used to provide a quick overview of data, such as the performance of a website or the progress of a project. By placing the sparkline chart in a prominent location, it's easy to see whether the data is trending in the right direction."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Displaying data in a dashboard or report:"}),"\xa0Sparkline charts are often used in dashboards or reports to provide a quick overview of data. By combining sparkline charts with other types of charts and graphs, it's possible to create a comprehensive view of the data."]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Mathematical/Geometrical concepts"}),"\nThe major D3 functions that are involved in the creation of Vertical bar charts are:","\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"d3-scale:"}),"\nThe\xa0d3-scale\xa0module is a part of the d3 library, which is a collection of JavaScript functions that are used for data visualization. The\xa0d3-scale\xa0module provides several functions for creating and manipulating scales, which are used to map data values to visual properties, such as\xa0position, size, and color."]}),"\n",(0,a.jsx)(n.p,{children:"The\xa0d3-scale\xa0module includes several scale types, including linear, logarithmic, power, and time scales. These scales are used to map continuous data values to a continuous range of visual properties. The module also includes ordinal and band scales, which are used to map categorical data values to a discrete range of visual properties."}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"The\xa0d3-scale\xa0module provides several functions for creating and manipulating scales, including\xa0scaleLinear, scaleLog, scalePow, scaleTime, scaleOrdinal, and scaleBand. These functions take one or more arguments that define the domain and range of the scale, as well as any additional properties, such as the number of ticks or the padding between bands."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Application in Sparkline chart:"}),"\nIn Sparkline chart, d3Scale is used to create a linear scale for the x and y axes of the sparkline chart."]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"d3.scaleLinear()"}),": The\xa0d3.scaleLinear\xa0is a function from the\xa0d3-scale\xa0module that is used to create a linear scale for the y-axis of the chart. The linear scale maps a continuous domain of data values to a continuous range of visual properties, such as position or height. The\xa0d3ScaleLinear\xa0function takes no arguments and returns a new linear scale. The scale can be customized using several methods, including\xa0domain, range, clamp, and nice. The\xa0domain\xa0method sets the domain of the scale, which is the range of data values that the scale maps to the range of visual properties. The\xa0range\xa0method sets the range of the scale, which is the range of visual properties that the scale maps to the domain of data values."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Application in Sparkline chart:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"In Sparkline chart,\xa0d3.scaleLinear()\xa0is used to create a linear scale for the x and y axes of the sparkline chart."}),"\n",(0,a.jsx)(n.li,{children:"The x scale is created using the\xa0d3.scaleLinear()\xa0function and is defined by the minimum and maximum values of the x-axis data points."}),"\n",(0,a.jsx)(n.li,{children:"The y scale is also created using the\xa0d3.scaleLinear()\xa0function and is defined by the minimum and maximum values of the y-axis data points."}),"\n",(0,a.jsx)(n.li,{children:"These scales are then used to map the data points to the corresponding positions on the chart."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"d3-shape:"}),"\xa0The d3-shape library provides various functions for creating and manipulating shapes such as arcs, lines, and areas. Following are the main mathematical/geometrical concepts that are used while drawing a Sparkline chart.\n",(0,a.jsx)(n.strong,{children:"Application in Sparkline chart:"})]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"d3.area():"}),'\xa0In Sparkline chart,\xa0d3.area()\xa0is used to create an area chart for the Sparkline component. It is initialized in the\xa0componentDidMount\xa0method and takes in an array of data points as input. The\xa0x\xa0and\xa0y\xa0values of each data point are used to create the shape of the area chart. The\xa0x\xa0value is mapped to the\xa0x-axis\xa0and the\xa0y\xa0value is mapped to the\xa0y-axis. The area chart is then rendered using the\xa0drawSparkline\xa0method, which returns a path element with the class name "area". The fill color of the area chart is set to the color of the line chart data point and the opacity is set to\xa00.2. The\xa0aria-label\xa0attribute is also set to the legend of the line chart data point.']}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"d3.line():"}),"\xa0In Sparkline chart, d3Line is used to create a line generator function that is used to generate a line path for the Sparkline chart. The line generator function takes an array of data points and generates a path string that represents the line connecting those points. The\xa0x\xa0and\xa0y\xa0values of each data point are mapped to the\xa0x\xa0and\xa0y\xa0coordinates of the line path using the\xa0x\xa0and\xa0y\xa0scales created using\xa0d3.scaleLinear(). The\xa0curveLinear\xa0function is used to specify the type of curve used to interpolate between the data points. The resulting line path is then rendered in the SVG element of the Sparkline chart."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"d3.curveLinear():"}),"\xa0In the Sparkline chart,\xa0d3.curveLinear()\xa0is used to define the curve type for the line and area charts in the Sparkline component. It is used in the\xa0componentDidMount\xa0method to create an area and line function that will be used to draw the chart. The\xa0curve\xa0method is called on both the\xa0area\xa0and\xa0line\xa0functions, passing in\xa0d3.curveLinear()\xa0as the argument. This sets the curve type to be a straight line between each data point. This means that the line and area charts will be drawn with straight lines connecting each data point, rather than a curved line."]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"d3-array:"}),"\xa0The\xa0d3-array\xa0is a module from the d3 library that is used to manipulate arrays of data in the chart component. The\xa0d3-array\xa0module provides several functions for manipulating arrays of data, including\xa0max, min, extent, sum, and mean. The\xa0max\xa0function is used to find the maximum value in an array of data. The\xa0min\xa0function is used to find the minimum value in an array of data. The\xa0extent\xa0function is used to find the minimum and maximum values in an array of data. The\xa0sum\xa0function is used to find the sum of the values in an array of data. The\xa0mean\xa0function is used to find the mean (average) of the values in an array of data."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Application in Sparkline chart:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"d3.max():"}),"\xa0In Sparkline chart,\xa0d3.max()\xa0is used to find the maximum value of the y-axis domain for the Sparkline chart. It takes an array of data points and a function that returns the value to be compared. In this case, it compares the y value of each data point. The maximum y value is then used to set the upper limit of the y-axis scale."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"d3.extent():"}),"\xa0In Sparkline chart,\xa0d3.extent()\xa0is used to calculate the minimum and maximum values of the x-axis of the sparkline chart. It takes an array of data points as its first argument and a function that returns the value to be used for the extent calculation as its second argument. In this case, the function returns the x-value of each data point. The resulting array of minimum and maximum values is then used to set the domain of the x-axis scale."]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Dev Design details"}),"\nThis section contains the technical design of various sub-components of a Sparkline chart and how they interact with each other. This section can also contain any key interface or class structure of the donut chart.\nThe Sparkline chart consists of the following sub-components:"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"1. Line:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Line creation:"}),"\xa0In the Sparkline chart, the line is created using the\xa0d3Line()\xa0function from the\xa0d3-shape\xa0library. The\xa0d3Line()\xa0function generates a line generator function that can be used to generate a line path string for the given data points."]}),"\n",(0,a.jsx)(n.p,{children:"In the\xa0Sparkline\xa0component, the\xa0line\xa0variable is assigned to the line generator function created using\xa0d3Line(). The\xa0x\xa0and\xa0y\xa0values for each data point are specified using the\xa0x()\xa0and\xa0y()\xa0methods of the line generator function, respectively. The\xa0curve()\xa0method is used to specify the type of curve to use for the line."}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Finally, the line path string is generated by calling the\xa0line()\xa0method of the line generator function with the array of data points as its argument. This path string is then used to draw the line in the chart."}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"2. Area:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Area creation:"}),"\xa0The area in the Sparkline chart is created using the\xa0d3.area()\xa0function from the\xa0d3-shape\xa0library. The\xa0d3.area()\xa0function generates an area shape for the given data points. In this code, the\xa0d3.area()\xa0function is called with the following parameters:","\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:".x((d: any) => this.x(d.x)): This sets the x-coordinate of each point in the area to the corresponding x-coordinate of the data point."}),"\n",(0,a.jsx)(n.li,{children:".y0(this.state._height): This sets the y-coordinate of the bottom of the area to the height of the Sparkline chart."}),"\n",(0,a.jsx)(n.li,{children:".y1((d: any) => this.y(d.y)): This sets the y-coordinate of each point in the area to the corresponding y-coordinate of the data point."}),"\n",(0,a.jsx)(n.li,{children:".curve(d3curveLinear): This sets the curve of the area to a linear curve."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"The resulting area shape is then rendered in the\xa0drawSparkline\xa0method of the\xa0Sparkline\xa0component."}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"3. Legend:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"If\xa0showLegend\xa0prop is set to true, the chart displays the value of the legend which is mentioned in the provided data. Otherwise, no value is displayed."}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.strong,{children:"Rendering details"})}),"\n"]}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"A Sparkline chart is drawn using a line and an area that represent the trend of the data over time. The line shows the trend of the data, while the area shows the range of the data. The chart is typically small and compact, making it ideal for displaying trends and changes in data in a small space."}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"The chart is drawn using the D3 (Data-Driven Documents) library. The\xa0drawSparkline\xa0method of the\xa0Sparkline\xa0component returns a JSX element that contains two SVG paths, one for the line and one for the area."}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"The\xa0line\xa0and\xa0area\xa0variables are created using the\xa0d3.line()\xa0and\xa0d3.area()\xa0functions respectively. These functions take an array of data points and generate a path string that can be used to draw the line or area."}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"The\xa0x\xa0and\xa0y\xa0scales are created using the\xa0d3.scaleLinear()\xa0function, which maps the data points to the x and y coordinates of the chart. The\xa0domain\xa0method sets the range of the data, while the\xa0range\xa0method sets the range of the chart."}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Once the scales are created, the\xa0line\xa0and\xa0area\xa0functions are called with the data points to generate the path strings. These path strings are then used to draw the line and area on the chart."}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"The\xa0drawSparkline\xa0method also sets the stroke and fill colors of the line and area based on the\xa0color\xa0property of the\xa0lineChartData\xa0object. The\xa0opacity\xa0and\xa0fillOpacity\xa0properties are also set to control the transparency of the chart."}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Finally, the\xa0aria-label\xa0property is set to provide an accessible label for the chart. This label includes the legend text of the\xa0lineChartData\xa0object."}),"\n",(0,a.jsx)(n.p,{children:"Overall, the Sparkline chart is drawn using D3 to generate the path strings for the line and area of the chart and sets the properties of the chart based on the\xa0lineChartData\xa0object."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Error scenarios"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:'The Sparkline chart handles the scenario where there is no data to display. In this case, it displays a message stating that the graph has no data to display. This is done by rendering a div with an id of\xa0_SparklineChart_empty\xa0and setting its opacity to 0. The div has an aria-label attribute with the value "Graph has no data to display".'}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Localization aspects"}),"\nCurrently, Sparkline chart does not provide any localization support."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Testing"}),"\nFollowing is the test report for Sparkline Chart:\n",(0,a.jsx)(n.img,{alt:"Sparkline2.png",src:t(9636).Z+"",width:"2479",height:"535"})]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Accessibility"}),"\nFAST pass checks resulted in no error for Sparkline chart. Link to the ",(0,a.jsx)(n.a,{href:"https://accessibilityinsights.io/docs/web/getstarted/fastpass/",children:"FAST pass tool"}),"\xa0\nOur charts have elaborate accessibility support. The charts are WCAG 2.1 MAS C compliant for accessibility."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Theming"}),'\nThe palette for donut chart is set from the "theme" prop as passed to the component during rendering. Both light and dark themes are supported and users can create there own theme too.\xa0',(0,a.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/wiki/Theming",children:"Ref3"}),"\xa0\xa0and\xa0",(0,a.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/wiki/How-to-apply-theme-to-Fluent-UI-React-components",children:"Ref4"}),"\xa0\xa0explains theming in detail."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Debugging"}),"\nThe detailed steps on debugging has been given in\xa0",(0,a.jsx)(n.a,{href:"https://github.com/microsoft/fluentui-charting-contrib/blob/main/docs/Debugging.md",children:"Debugging"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Variants"}),"\nFollowing are the variants of donut chart:\xa0",(0,a.jsx)(n.a,{href:"https://developer.microsoft.com/en-us/fluentui#/controls/web/sparklinechart",children:"Ref2"}),"\xa0","\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Basic Sparkline Chart: Only basic props are provided."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Interaction"}),"\nFollowing are the interactions that are allowed for Sparkline chart:","\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"The Sparkline charts are focusable using mouse and keyboard."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Some notable PRs and their brief description"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/commit/e4efe4f056ed6af7d6e55e87580906efacc9a1fc",children:"Adding the Sparkline Chart main component and tests"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/commit/9af1af0649760df3eb0fae4a9c542466388318ac",children:"Fixing charting visualization bugs"})}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Learnings"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["While implementing the tests using react testing library, it was found that certain browser functions like\xa0",(0,a.jsx)(n.em,{children:"getComputedTextLength()"}),"\xa0cannot be unit tested and needs to be tested End-to-End only."]}),"\n",(0,a.jsx)(n.li,{children:"Order of imports are important.\nFor example: for Vertical bar charts tests, improper sequencing of the imports (data first and then render) results in incorrect and incomplete rendering of charts:"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:" - import { chartPoints } from '../VerticalBarChart/VerticalBarChart.test';\n - import { render, screen, queryAllByAttribute, fireEvent, act } from '@testing-library/react';\n"})}),"\n",(0,a.jsx)(n.p,{children:"However, the following results in correct rendering:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"import { render, screen, queryAllByAttribute } from '@testing-library/react';\n\nimport { chartPoints } from './VerticalBarChart.test';\n"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Certain props need async await structure (waitFor\xa0in react testing library) for different props or nested SVGs to render."}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Future improvements"})}),"\n",(0,a.jsx)(n.p,{children:"Following are the list of potential future improvements for the Sparkline chart:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Add sub-components: Callouts can be added on hover over a point on Sparkline chart."}),"\n",(0,a.jsx)(n.li,{children:"Add support for multiple data series: Currently, the component only supports a single data series. It could be improved to allow for multiple series to be displayed on the same chart."}),"\n",(0,a.jsx)(n.li,{children:"Improve accessibility: The component could be improved to better support accessibility, such as by adding support for keyboard navigation and improving the use of ARIA attributes."}),"\n",(0,a.jsx)(n.li,{children:"Add support for custom styling: Currently, the component has a limited set of styles that can be customized. It could be improved to allow for more customization, such as by allowing users to specify custom CSS classes or inline styles."}),"\n",(0,a.jsx)(n.li,{children:"Improve performance: Depending on the size of the data set, the component could potentially have performance issues. It could be improved to better handle large data sets or to use more performant rendering techniques, such as canvas rendering."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Design figma"}),"\nSparkline Chart Figma:\xa0",(0,a.jsx)(n.a,{href:"https://www.figma.com/file/WOoCs0CmNYZhYl9xXeCGpi/Data-viz-(Archive)?type=design&node-id=3583-83411&mode=design&t=q0qfn10YyA5UiKNb-0",children:"Link"}),"\xa0"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Performance"})}),"\n",(0,a.jsx)(n.p,{children:"The performance aspect of a donut chart refers to how efficiently and effectively it conveys information to the viewer. Here are some key considerations regarding the performance of a line chart:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Data Visualization Efficiency"}),"\n",(0,a.jsx)(n.li,{children:"Clarity and Simplicity"}),"\n",(0,a.jsx)(n.li,{children:"Responsiveness"}),"\n",(0,a.jsx)(n.li,{children:"Handling Large Datasets\n-Interactive Features"}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"References"})}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://github.com/d3/d3-shape/blob/main/README.md",children:"D3-shape"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://developer.microsoft.com/en-us/fluentui#/controls/web/sparklinechart",children:"Sparkline Chart"})}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/wiki/Theming",children:"Theming"}),"\xa0"]}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/wiki/How-to-apply-theme-to-Fluent-UI-React-components",children:"How to apply theme"})}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},5458:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/Sparkline1-a8ff43c85309eba19385b762775ce8af.png"},9636:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/Sparkline2-3d71bcc13bdec5365ffc0802a3515f57.png"},1151:(e,n,t)=>{t.d(n,{Z:()=>o,a:()=>r});var a=t(7294);const i={},s=a.createContext(i);function r(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/e1621294.274910be.js b/assets/js/e1621294.274910be.js
deleted file mode 100644
index 52408f379c..0000000000
--- a/assets/js/e1621294.274910be.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[3633],{7037:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>h,contentTitle:()=>s,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var a=t(5893),i=t(1151);const r={},s="Contributor guide: Sparkline Chart",o={id:"Charting-Concepts/SparklineChart",title:"Contributor guide: Sparkline Chart",description:"Sparkline1.png",source:"@site/../../docs/Charting-Concepts/SparklineChart.md",sourceDirName:"Charting-Concepts",slug:"/Charting-Concepts/SparklineChart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/SparklineChart",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Contributor Guide: Sankey Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/SankeyChart"},next:{title:"Contributor guide: Stacked Bar Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/StackedBarChart"}},h={},l=[];function c(e){const n={a:"a",code:"code",em:"em",h1:"h1",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h1,{id:"contributor-guide-sparkline-chart",children:"Contributor guide: Sparkline Chart"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{alt:"Sparkline1.png",src:t(5458).Z+"",width:"919",height:"326"})}),"\n",(0,a.jsx)(n.p,{children:"A Sparkline chart is a small, simple chart that is used to display trends over time or changes in data. It is typically used in dashboards or reports where space is limited. The chart consists of a line that shows the trend over time, and an area that shows the range of the data. The chart is designed to be small and compact, so it can be used in dashboards or reports where space is limited."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Use cases"}),"\nFollowing are some use cases for Sparkline Chart:","\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Displaying trends over time:"}),"\xa0Sparkline charts are great for showing trends over time, such as stock prices, website traffic, or weather patterns. By compressing the data into a small space, sparklines can quickly show whether the trend is up, down, or flat."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Showing changes in data:"}),"\xa0Sparkline charts can also be used to show changes in data, such as the number of sales per day or the number of website visitors per hour. By comparing the data points to each other, sparklines can show whether the changes are significant or not."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Comparing multiple data sets:"}),"\xa0Sparkline charts can be used to compare multiple data sets, such as the sales of different products or the performance of different teams. By placing the sparklines side by side, it's easy to see which data set is performing better."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Visualizing data in a small space:"}),"\xa0Sparkline charts are great for visualizing data in a small space, such as a dashboard or a report. By compressing the data into a small chart, sparklines can provide a quick overview of the data without taking up too much space."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Providing a quick overview of data:"}),"\xa0Sparkline charts can be used to provide a quick overview of data, such as the performance of a website or the progress of a project. By placing the sparkline chart in a prominent location, it's easy to see whether the data is trending in the right direction."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Displaying data in a dashboard or report:"}),"\xa0Sparkline charts are often used in dashboards or reports to provide a quick overview of data. By combining sparkline charts with other types of charts and graphs, it's possible to create a comprehensive view of the data."]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Mathematical/Geometrical concepts"}),"\nThe major D3 functions that are involved in the creation of Vertical bar charts are:","\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"d3-scale:"}),"\nThe\xa0d3-scale\xa0module is a part of the d3 library, which is a collection of JavaScript functions that are used for data visualization. The\xa0d3-scale\xa0module provides several functions for creating and manipulating scales, which are used to map data values to visual properties, such as\xa0position, size, and color."]}),"\n",(0,a.jsx)(n.p,{children:"The\xa0d3-scale\xa0module includes several scale types, including linear, logarithmic, power, and time scales. These scales are used to map continuous data values to a continuous range of visual properties. The module also includes ordinal and band scales, which are used to map categorical data values to a discrete range of visual properties."}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"The\xa0d3-scale\xa0module provides several functions for creating and manipulating scales, including\xa0scaleLinear, scaleLog, scalePow, scaleTime, scaleOrdinal, and scaleBand. These functions take one or more arguments that define the domain and range of the scale, as well as any additional properties, such as the number of ticks or the padding between bands."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Application in Sparkline chart:"}),"\nIn Sparkline chart, d3Scale is used to create a linear scale for the x and y axes of the sparkline chart."]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"d3.scaleLinear()"}),": The\xa0d3.scaleLinear\xa0is a function from the\xa0d3-scale\xa0module that is used to create a linear scale for the y-axis of the chart. The linear scale maps a continuous domain of data values to a continuous range of visual properties, such as position or height. The\xa0d3ScaleLinear\xa0function takes no arguments and returns a new linear scale. The scale can be customized using several methods, including\xa0domain, range, clamp, and nice. The\xa0domain\xa0method sets the domain of the scale, which is the range of data values that the scale maps to the range of visual properties. The\xa0range\xa0method sets the range of the scale, which is the range of visual properties that the scale maps to the domain of data values."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Application in Sparkline chart:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"In Sparkline chart,\xa0d3.scaleLinear()\xa0is used to create a linear scale for the x and y axes of the sparkline chart."}),"\n",(0,a.jsx)(n.li,{children:"The x scale is created using the\xa0d3.scaleLinear()\xa0function and is defined by the minimum and maximum values of the x-axis data points."}),"\n",(0,a.jsx)(n.li,{children:"The y scale is also created using the\xa0d3.scaleLinear()\xa0function and is defined by the minimum and maximum values of the y-axis data points."}),"\n",(0,a.jsx)(n.li,{children:"These scales are then used to map the data points to the corresponding positions on the chart."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"d3-shape:"}),"\xa0The d3-shape library provides various functions for creating and manipulating shapes such as arcs, lines, and areas. Following are the main mathematical/geometrical concepts that are used while drawing a Sparkline chart.\n",(0,a.jsx)(n.strong,{children:"Application in Sparkline chart:"})]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"d3.area():"}),'\xa0In Sparkline chart,\xa0d3.area()\xa0is used to create an area chart for the Sparkline component. It is initialized in the\xa0componentDidMount\xa0method and takes in an array of data points as input. The\xa0x\xa0and\xa0y\xa0values of each data point are used to create the shape of the area chart. The\xa0x\xa0value is mapped to the\xa0x-axis\xa0and the\xa0y\xa0value is mapped to the\xa0y-axis. The area chart is then rendered using the\xa0drawSparkline\xa0method, which returns a path element with the class name "area". The fill color of the area chart is set to the color of the line chart data point and the opacity is set to\xa00.2. The\xa0aria-label\xa0attribute is also set to the legend of the line chart data point.']}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"d3.line():"}),"\xa0In Sparkline chart, d3Line is used to create a line generator function that is used to generate a line path for the Sparkline chart. The line generator function takes an array of data points and generates a path string that represents the line connecting those points. The\xa0x\xa0and\xa0y\xa0values of each data point are mapped to the\xa0x\xa0and\xa0y\xa0coordinates of the line path using the\xa0x\xa0and\xa0y\xa0scales created using\xa0d3.scaleLinear(). The\xa0curveLinear\xa0function is used to specify the type of curve used to interpolate between the data points. The resulting line path is then rendered in the SVG element of the Sparkline chart."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"d3.curveLinear():"}),"\xa0In the Sparkline chart,\xa0d3.curveLinear()\xa0is used to define the curve type for the line and area charts in the Sparkline component. It is used in the\xa0componentDidMount\xa0method to create an area and line function that will be used to draw the chart. The\xa0curve\xa0method is called on both the\xa0area\xa0and\xa0line\xa0functions, passing in\xa0d3.curveLinear()\xa0as the argument. This sets the curve type to be a straight line between each data point. This means that the line and area charts will be drawn with straight lines connecting each data point, rather than a curved line."]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"d3-array:"}),"\xa0The\xa0d3-array\xa0is a module from the d3 library that is used to manipulate arrays of data in the chart component. The\xa0d3-array\xa0module provides several functions for manipulating arrays of data, including\xa0max, min, extent, sum, and mean. The\xa0max\xa0function is used to find the maximum value in an array of data. The\xa0min\xa0function is used to find the minimum value in an array of data. The\xa0extent\xa0function is used to find the minimum and maximum values in an array of data. The\xa0sum\xa0function is used to find the sum of the values in an array of data. The\xa0mean\xa0function is used to find the mean (average) of the values in an array of data."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Application in Sparkline chart:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"d3.max():"}),"\xa0In Sparkline chart,\xa0d3.max()\xa0is used to find the maximum value of the y-axis domain for the Sparkline chart. It takes an array of data points and a function that returns the value to be compared. In this case, it compares the y value of each data point. The maximum y value is then used to set the upper limit of the y-axis scale."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"d3.extent():"}),"\xa0In Sparkline chart,\xa0d3.extent()\xa0is used to calculate the minimum and maximum values of the x-axis of the sparkline chart. It takes an array of data points as its first argument and a function that returns the value to be used for the extent calculation as its second argument. In this case, the function returns the x-value of each data point. The resulting array of minimum and maximum values is then used to set the domain of the x-axis scale."]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Dev Design details"}),"\nThis section contains the technical design of various sub-components of a Sparkline chart and how they interact with each other. This section can also contain any key interface or class structure of the donut chart.\nThe Sparkline chart consists of the following sub-components:"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"1. Line:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Line creation:"}),"\xa0In the Sparkline chart, the line is created using the\xa0d3Line()\xa0function from the\xa0d3-shape\xa0library. The\xa0d3Line()\xa0function generates a line generator function that can be used to generate a line path string for the given data points."]}),"\n",(0,a.jsx)(n.p,{children:"In the\xa0Sparkline\xa0component, the\xa0line\xa0variable is assigned to the line generator function created using\xa0d3Line(). The\xa0x\xa0and\xa0y\xa0values for each data point are specified using the\xa0x()\xa0and\xa0y()\xa0methods of the line generator function, respectively. The\xa0curve()\xa0method is used to specify the type of curve to use for the line."}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Finally, the line path string is generated by calling the\xa0line()\xa0method of the line generator function with the array of data points as its argument. This path string is then used to draw the line in the chart."}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"2. Area:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Area creation:"}),"\xa0The area in the Sparkline chart is created using the\xa0d3.area()\xa0function from the\xa0d3-shape\xa0library. The\xa0d3.area()\xa0function generates an area shape for the given data points. In this code, the\xa0d3.area()\xa0function is called with the following parameters:","\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:".x((d: any) => this.x(d.x)): This sets the x-coordinate of each point in the area to the corresponding x-coordinate of the data point."}),"\n",(0,a.jsx)(n.li,{children:".y0(this.state._height): This sets the y-coordinate of the bottom of the area to the height of the Sparkline chart."}),"\n",(0,a.jsx)(n.li,{children:".y1((d: any) => this.y(d.y)): This sets the y-coordinate of each point in the area to the corresponding y-coordinate of the data point."}),"\n",(0,a.jsx)(n.li,{children:".curve(d3curveLinear): This sets the curve of the area to a linear curve."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"The resulting area shape is then rendered in the\xa0drawSparkline\xa0method of the\xa0Sparkline\xa0component."}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"3. Legend:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"If\xa0showLegend\xa0prop is set to true, the chart displays the value of the legend which is mentioned in the provided data. Otherwise, no value is displayed."}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.strong,{children:"Rendering details"})}),"\n"]}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"A Sparkline chart is drawn using a line and an area that represent the trend of the data over time. The line shows the trend of the data, while the area shows the range of the data. The chart is typically small and compact, making it ideal for displaying trends and changes in data in a small space."}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"The chart is drawn using the D3 (Data-Driven Documents) library. The\xa0drawSparkline\xa0method of the\xa0Sparkline\xa0component returns a JSX element that contains two SVG paths, one for the line and one for the area."}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"The\xa0line\xa0and\xa0area\xa0variables are created using the\xa0d3.line()\xa0and\xa0d3.area()\xa0functions respectively. These functions take an array of data points and generate a path string that can be used to draw the line or area."}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"The\xa0x\xa0and\xa0y\xa0scales are created using the\xa0d3.scaleLinear()\xa0function, which maps the data points to the x and y coordinates of the chart. The\xa0domain\xa0method sets the range of the data, while the\xa0range\xa0method sets the range of the chart."}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Once the scales are created, the\xa0line\xa0and\xa0area\xa0functions are called with the data points to generate the path strings. These path strings are then used to draw the line and area on the chart."}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"The\xa0drawSparkline\xa0method also sets the stroke and fill colors of the line and area based on the\xa0color\xa0property of the\xa0lineChartData\xa0object. The\xa0opacity\xa0and\xa0fillOpacity\xa0properties are also set to control the transparency of the chart."}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Finally, the\xa0aria-label\xa0property is set to provide an accessible label for the chart. This label includes the legend text of the\xa0lineChartData\xa0object."}),"\n",(0,a.jsx)(n.p,{children:"Overall, the Sparkline chart is drawn using D3 to generate the path strings for the line and area of the chart and sets the properties of the chart based on the\xa0lineChartData\xa0object."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Error scenarios"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:'The Sparkline chart handles the scenario where there is no data to display. In this case, it displays a message stating that the graph has no data to display. This is done by rendering a div with an id of\xa0_SparklineChart_empty\xa0and setting its opacity to 0. The div has an aria-label attribute with the value "Graph has no data to display".'}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Localization aspects"}),"\nCurrently, Sparkline chart does not provide any localization support."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Testing"}),"\nFollowing is the test report for Sparkline Chart:\n",(0,a.jsx)(n.img,{alt:"Sparkline2.png",src:t(9636).Z+"",width:"2479",height:"535"})]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Accessibility"}),"\nFAST pass checks resulted in no error for Sparkline chart. Link to the ",(0,a.jsx)(n.a,{href:"https://accessibilityinsights.io/docs/web/getstarted/fastpass/",children:"FAST pass tool"}),"\xa0\nOur charts have elaborate accessibility support. The charts are WCAG 2.1 MAS C compliant for accessibility."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Theming"}),'\nThe palette for donut chart is set from the "theme" prop as passed to the component during rendering. Both light and dark themes are supported and users can create there own theme too.\xa0',(0,a.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/wiki/Theming",children:"Ref3"}),"\xa0\xa0and\xa0",(0,a.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/wiki/How-to-apply-theme-to-Fluent-UI-React-components",children:"Ref4"}),"\xa0\xa0explains theming in detail."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Debugging"}),"\nThe detailed steps on debugging has been given in\xa0",(0,a.jsx)(n.a,{href:"https://github.com/microsoft/fluentui-charting-contrib/blob/main/docs/Debugging.md",children:"Debugging"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Variants"}),"\nFollowing are the variants of donut chart:\xa0",(0,a.jsx)(n.a,{href:"https://developer.microsoft.com/en-us/fluentui#/controls/web/sparklinechart",children:"Ref2"}),"\xa0","\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Basic Sparkline Chart: Only basic props are provided."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Interaction"}),"\nFollowing are the interactions that are allowed for Sparkline chart:","\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"The Sparkline charts are focusable using mouse and keyboard."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Some notable PRs and their brief description"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/commit/e4efe4f056ed6af7d6e55e87580906efacc9a1fc",children:"Adding the Sparkline Chart main component and tests"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/commit/9af1af0649760df3eb0fae4a9c542466388318ac",children:"Fixing charting visualization bugs"})}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Learnings"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["While implementing the tests using react testing library, it was found that certain browser functions like\xa0",(0,a.jsx)(n.em,{children:"getComputedTextLength()"}),"\xa0cannot be unit tested and needs to be tested End-to-End only."]}),"\n",(0,a.jsx)(n.li,{children:"Order of imports are important.\nFor example: for Vertical bar charts tests, improper sequencing of the imports (data first and then render) results in incorrect and incomplete rendering of charts:"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:" - import { chartPoints } from '../VerticalBarChart/VerticalBarChart.test';\n - import { render, screen, queryAllByAttribute, fireEvent, act } from '@testing-library/react';\n"})}),"\n",(0,a.jsx)(n.p,{children:"However, the following results in correct rendering:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"import { render, screen, queryAllByAttribute } from '@testing-library/react';\n\nimport { chartPoints } from './VerticalBarChart.test';\n"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Certain props need async await structure (waitFor\xa0in react testing library) for different props or nested SVGs to render."}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Future improvements"})}),"\n",(0,a.jsx)(n.p,{children:"Following are the list of potential future improvements for the Sparkline chart:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Add sub-components: Callouts can be added on hover over a point on Sparkline chart."}),"\n",(0,a.jsx)(n.li,{children:"Add support for multiple data series: Currently, the component only supports a single data series. It could be improved to allow for multiple series to be displayed on the same chart."}),"\n",(0,a.jsx)(n.li,{children:"Improve accessibility: The component could be improved to better support accessibility, such as by adding support for keyboard navigation and improving the use of ARIA attributes."}),"\n",(0,a.jsx)(n.li,{children:"Add support for custom styling: Currently, the component has a limited set of styles that can be customized. It could be improved to allow for more customization, such as by allowing users to specify custom CSS classes or inline styles."}),"\n",(0,a.jsx)(n.li,{children:"Improve performance: Depending on the size of the data set, the component could potentially have performance issues. It could be improved to better handle large data sets or to use more performant rendering techniques, such as canvas rendering."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Design figma"}),"\nSparkline Chart Figma:\xa0",(0,a.jsx)(n.a,{href:"https://www.figma.com/file/WOoCs0CmNYZhYl9xXeCGpi/Data-viz-(Archive)?type=design&node-id=3583-83411&mode=design&t=q0qfn10YyA5UiKNb-0",children:"Link"}),"\xa0"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Performance"})}),"\n",(0,a.jsx)(n.p,{children:"The performance aspect of a donut chart refers to how efficiently and effectively it conveys information to the viewer. Here are some key considerations regarding the performance of a line chart:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Data Visualization Efficiency"}),"\n",(0,a.jsx)(n.li,{children:"Clarity and Simplicity"}),"\n",(0,a.jsx)(n.li,{children:"Responsiveness"}),"\n",(0,a.jsx)(n.li,{children:"Handling Large Datasets\n-Interactive Features"}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"References"})}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://github.com/d3/d3-shape/blob/main/README.md",children:"D3-shape"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://developer.microsoft.com/en-us/fluentui#/controls/web/sparklinechart",children:"Sparkline Chart"})}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/wiki/Theming",children:"Theming"}),"\xa0"]}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://github.com/microsoft/fluentui/wiki/How-to-apply-theme-to-Fluent-UI-React-components",children:"How to apply theme"})}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},5458:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/Sparkline1-a8ff43c85309eba19385b762775ce8af.png"},9636:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/Sparkline2-3d71bcc13bdec5365ffc0802a3515f57.png"},1151:(e,n,t)=>{t.d(n,{Z:()=>o,a:()=>s});var a=t(7294);const i={},r=a.createContext(i);function s(e){const n=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),a.createElement(r.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/fdebbd26.9af8dffb.js b/assets/js/fdebbd26.9af8dffb.js
new file mode 100644
index 0000000000..24312d8ef9
--- /dev/null
+++ b/assets/js/fdebbd26.9af8dffb.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[8864],{7338:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>d});var s=t(5893),o=t(1151);const i={},r=void 0,c={id:"Debugging",title:"Debugging",description:"The chart components can be debugged using few techniques.",source:"@site/../../docs/Debugging.md",sourceDirName:".",slug:"/Debugging",permalink:"/fluentui-charting-contrib/docs/Debugging",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Detailed Implementation Steps",permalink:"/fluentui-charting-contrib/docs/Detailed Implementation Steps"},next:{title:"Implementation Best Practices",permalink:"/fluentui-charting-contrib/docs/Implementation Best Practices"}},l={},d=[];function a(e){const n={code:"code",li:"li",ol:"ol",p:"p",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"The chart components can be debugged using few techniques."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Using browser developer tools."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Open developer tools (Pressing ",(0,s.jsx)(n.code,{children:"F12"}),")."]}),"\n",(0,s.jsxs)(n.li,{children:["Go to sources tab and open search bar (Pressing ",(0,s.jsx)(n.code,{children:"Ctrl + Shift + F"}),")."]}),"\n",(0,s.jsx)(n.li,{children:"Search for the component name and open the sources file from the search results."}),"\n",(0,s.jsx)(n.li,{children:"Apply breakpoints and run the scenario to see the breakpoints getting hit."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Add console logs with the variables that you want to test. (Make sure to remove these logs while commiting your changes.)"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Add a ",(0,s.jsx)(n.code,{children:"debugger"})," statement wherever you want to debug. Open dev tools and run the scenario. The execution will pause once the debugger statement is hit. (Make sure to remove these logs while commiting your changes.)"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Debugging using test cases"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Open visual studio code from fluent ui root folder. (Not from ",(0,s.jsx)(n.code,{children:"packages\\react-charting"}),")"]}),"\n",(0,s.jsxs)(n.li,{children:["Check whether the ",(0,s.jsx)(n.code,{children:"Debug current open test"})," debug option is visible under the run and debug tab."]}),"\n",(0,s.jsxs)(n.li,{children:["Add breakpoints to the relevant test case and start debugging using ",(0,s.jsx)(n.code,{children:"Debug current open test"})," option.\nNote that this option renders the components under a headless browser. So some actual rendering dependent functions like ",(0,s.jsx)(n.code,{children:"getBoundingClientRect"})," will not work and will need to be mocked."]}),"\n"]}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>c,a:()=>r});var s=t(7294);const o={},i=s.createContext(o);function r(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/fdebbd26.e19eb6a0.js b/assets/js/fdebbd26.e19eb6a0.js
deleted file mode 100644
index e700513ee7..0000000000
--- a/assets/js/fdebbd26.e19eb6a0.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[8864],{7338:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>d});var s=t(5893),o=t(1151);const i={},r=void 0,c={id:"Debugging",title:"Debugging",description:"The chart components can be debugged using few techniques.",source:"@site/../../docs/Debugging.md",sourceDirName:".",slug:"/Debugging",permalink:"/fluentui-charting-contrib/docs/Debugging",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Contributor guide: Vertical Stacked Bar Chart",permalink:"/fluentui-charting-contrib/docs/Charting-Concepts/VerticalStackedBarChart"},next:{title:"Implementation Best Practices",permalink:"/fluentui-charting-contrib/docs/Implementation Best Practices"}},l={},d=[];function a(e){const n={code:"code",li:"li",ol:"ol",p:"p",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"The chart components can be debugged using few techniques."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Using browser developer tools."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Open developer tools (Pressing ",(0,s.jsx)(n.code,{children:"F12"}),")."]}),"\n",(0,s.jsxs)(n.li,{children:["Go to sources tab and open search bar (Pressing ",(0,s.jsx)(n.code,{children:"Ctrl + Shift + F"}),")."]}),"\n",(0,s.jsx)(n.li,{children:"Search for the component name and open the sources file from the search results."}),"\n",(0,s.jsx)(n.li,{children:"Apply breakpoints and run the scenario to see the breakpoints getting hit."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Add console logs with the variables that you want to test. (Make sure to remove these logs while commiting your changes.)"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Add a ",(0,s.jsx)(n.code,{children:"debugger"})," statement wherever you want to debug. Open dev tools and run the scenario. The execution will pause once the debugger statement is hit. (Make sure to remove these logs while commiting your changes.)"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Debugging using test cases"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Open visual studio code from fluent ui root folder. (Not from ",(0,s.jsx)(n.code,{children:"packages\\react-charting"}),")"]}),"\n",(0,s.jsxs)(n.li,{children:["Check whether the ",(0,s.jsx)(n.code,{children:"Debug current open test"})," debug option is visible under the run and debug tab."]}),"\n",(0,s.jsxs)(n.li,{children:["Add breakpoints to the relevant test case and start debugging using ",(0,s.jsx)(n.code,{children:"Debug current open test"})," option.\nNote that this option renders the components under a headless browser. So some actual rendering dependent functions like ",(0,s.jsx)(n.code,{children:"getBoundingClientRect"})," will not work and will need to be mocked."]}),"\n"]}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>c,a:()=>r});var s=t(7294);const o={},i=s.createContext(o);function r(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/runtime~main.04a480b9.js b/assets/js/runtime~main.9669ca4a.js
similarity index 50%
rename from assets/js/runtime~main.04a480b9.js
rename to assets/js/runtime~main.9669ca4a.js
index d2fd014892..5e71731e17 100644
--- a/assets/js/runtime~main.04a480b9.js
+++ b/assets/js/runtime~main.9669ca4a.js
@@ -1 +1 @@
-(()=>{"use strict";var e,a,f,c,d,t={},b={};function r(e){var a=b[e];if(void 0!==a)return a.exports;var f=b[e]={id:e,loaded:!1,exports:{}};return t[e].call(f.exports,f,f.exports,r),f.loaded=!0,f.exports}r.m=t,r.c=b,e=[],r.O=(a,f,c,d)=>{if(!f){var t=1/0;for(i=0;i=d)&&Object.keys(r.O).every((e=>r.O[e](f[o])))?f.splice(o--,1):(b=!1,d0&&e[i-1][2]>d;i--)e[i]=e[i-1];e[i]=[f,c,d]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},f=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,c){if(1&c&&(e=this(e)),8&c)return e;if("object"==typeof e&&e){if(4&c&&e.__esModule)return e;if(16&c&&"function"==typeof e.then)return e}var d=Object.create(null);r.r(d);var t={};a=a||[null,f({}),f([]),f(f)];for(var b=2&c&&e;"object"==typeof b&&!~a.indexOf(b);b=f(b))Object.getOwnPropertyNames(b).forEach((a=>t[a]=()=>e[a]));return t.default=()=>e,r.d(d,t),d},r.d=(e,a)=>{for(var f in a)r.o(a,f)&&!r.o(e,f)&&Object.defineProperty(e,f,{enumerable:!0,get:a[f]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((a,f)=>(r.f[f](e,a),a)),[])),r.u=e=>"assets/js/"+({53:"935f2afb",150:"41748239",774:"544aba92",917:"ec9b348c",982:"19139c30",1125:"8f2faa25",1181:"5b2e78ee",1283:"25929091",1321:"80060540",1351:"e9780fb0",1444:"3cf0876a",1483:"1b37b4b0",1605:"6158391e",1888:"35f90ace",1914:"10c2b1cf",2083:"9becebd9",2094:"8d775e4d",2190:"a85ccfbf",2357:"43c91bec",2408:"fa9519d0",2430:"c1b0a72f",2482:"2f599c6d",2632:"65a720d8",2637:"6ede8325",2871:"c81dfe5f",2907:"78e65ac0",3072:"72f1352f",3237:"1df93b7f",3400:"e8f56a24",3469:"918c9c28",3633:"e1621294",3861:"1d29b0d8",3946:"ebaf9aeb",4014:"e8c0cc48",4145:"82e69e4a",4356:"48224a32",4368:"a94703ab",4494:"5f0d6238",4630:"53fd9a32",4798:"a62d60fb",5069:"c67f0456",5112:"b0683616",5291:"e849b732",5671:"1ff5abae",5724:"100d50c4",5966:"df751193",5998:"e2d1ed78",6119:"418823fc",6662:"44a464d7",6863:"712b8a2d",6942:"6fe236e0",6970:"c0f01452",7478:"7bec51cf",7659:"5181bfc2",7706:"5fc975be",7792:"3b5ed4ca",7918:"17896441",7920:"1a4e3797",8137:"4d3d5107",8171:"c1fd7385",8466:"7ef89a43",8518:"a7bd4aaa",8673:"b0e8dd6d",8751:"b7f64af1",8864:"fdebbd26",8968:"ddc35001",9013:"2bd67647",9088:"67b1613a",9159:"785e1e6a",9330:"62692344",9368:"4c3c7f6c",9428:"a4b720fd",9597:"d620695a",9661:"5e95c892",9860:"790ff6d5"}[e]||e)+"."+{53:"d81b4fa2",150:"308d9309",774:"70e03cf8",917:"2cc92972",982:"4f7b6cbe",1125:"1f8e5cc5",1181:"8b4a2eea",1283:"4bcc76f7",1321:"a76e6a01",1351:"8b54cb62",1426:"ada98236",1444:"428e32d6",1483:"75412d65",1605:"5ebdff7e",1772:"05b37fcf",1888:"d08ce316",1914:"b046c885",2083:"822c72d3",2094:"de1b00a1",2190:"d4e7bdd2",2357:"db589e06",2408:"08a5e7fd",2430:"b56d97de",2482:"03033809",2632:"13074926",2637:"4dd5a347",2871:"55a95f78",2907:"59b2ef74",3072:"311a6085",3237:"0fc48f5c",3400:"194de0ce",3469:"442e3710",3633:"274910be",3861:"8fa1bc20",3946:"7eb0c752",4014:"9c908003",4145:"47151c70",4356:"ae238b0a",4368:"978f186e",4494:"07b7af73",4630:"1618df65",4798:"49014181",5069:"d83488f7",5112:"c91f045c",5291:"98b8fe46",5671:"b0c49283",5724:"49ead4c4",5966:"11c160c7",5998:"3bc94e31",6119:"84656fe2",6662:"ef547f4b",6863:"b2c49b65",6942:"ded0e513",6945:"73cb8f6d",6970:"e21d96f9",7478:"58a9bcae",7659:"b1d31591",7706:"8d26ad56",7792:"2b860f61",7918:"eba4c161",7920:"1065628c",8137:"69a82cd1",8171:"19344f10",8466:"37a63f5c",8518:"5fdeee4a",8673:"14bdb836",8751:"7bb0cce2",8864:"e19eb6a0",8894:"d8733546",8968:"41e90c63",9013:"758121c9",9088:"58e75e41",9159:"720f9aed",9330:"d438a31c",9368:"a4278219",9428:"7a47f5f7",9597:"2b3a4bdd",9661:"53db30f1",9860:"5e42560f"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),c={},d="docsite:",r.l=(e,a,f,t)=>{if(c[e])c[e].push(a);else{var b,o;if(void 0!==f)for(var n=document.getElementsByTagName("script"),i=0;i{b.onerror=b.onload=null,clearTimeout(s);var d=c[e];if(delete c[e],b.parentNode&&b.parentNode.removeChild(b),d&&d.forEach((e=>e(f))),a)return a(f)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:b}),12e4);b.onerror=l.bind(null,b.onerror),b.onload=l.bind(null,b.onload),o&&document.head.appendChild(b)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/fluentui-charting-contrib/",r.gca=function(e){return e={17896441:"7918",25929091:"1283",41748239:"150",62692344:"9330",80060540:"1321","935f2afb":"53","544aba92":"774",ec9b348c:"917","19139c30":"982","8f2faa25":"1125","5b2e78ee":"1181",e9780fb0:"1351","3cf0876a":"1444","1b37b4b0":"1483","6158391e":"1605","35f90ace":"1888","10c2b1cf":"1914","9becebd9":"2083","8d775e4d":"2094",a85ccfbf:"2190","43c91bec":"2357",fa9519d0:"2408",c1b0a72f:"2430","2f599c6d":"2482","65a720d8":"2632","6ede8325":"2637",c81dfe5f:"2871","78e65ac0":"2907","72f1352f":"3072","1df93b7f":"3237",e8f56a24:"3400","918c9c28":"3469",e1621294:"3633","1d29b0d8":"3861",ebaf9aeb:"3946",e8c0cc48:"4014","82e69e4a":"4145","48224a32":"4356",a94703ab:"4368","5f0d6238":"4494","53fd9a32":"4630",a62d60fb:"4798",c67f0456:"5069",b0683616:"5112",e849b732:"5291","1ff5abae":"5671","100d50c4":"5724",df751193:"5966",e2d1ed78:"5998","418823fc":"6119","44a464d7":"6662","712b8a2d":"6863","6fe236e0":"6942",c0f01452:"6970","7bec51cf":"7478","5181bfc2":"7659","5fc975be":"7706","3b5ed4ca":"7792","1a4e3797":"7920","4d3d5107":"8137",c1fd7385:"8171","7ef89a43":"8466",a7bd4aaa:"8518",b0e8dd6d:"8673",b7f64af1:"8751",fdebbd26:"8864",ddc35001:"8968","2bd67647":"9013","67b1613a":"9088","785e1e6a":"9159","4c3c7f6c":"9368",a4b720fd:"9428",d620695a:"9597","5e95c892":"9661","790ff6d5":"9860"}[e]||e,r.p+r.u(e)},(()=>{var e={1303:0,532:0};r.f.j=(a,f)=>{var c=r.o(e,a)?e[a]:void 0;if(0!==c)if(c)f.push(c[2]);else if(/^(1303|532)$/.test(a))e[a]=0;else{var d=new Promise(((f,d)=>c=e[a]=[f,d]));f.push(c[2]=d);var t=r.p+r.u(a),b=new Error;r.l(t,(f=>{if(r.o(e,a)&&(0!==(c=e[a])&&(e[a]=void 0),c)){var d=f&&("load"===f.type?"missing":f.type),t=f&&f.target&&f.target.src;b.message="Loading chunk "+a+" failed.\n("+d+": "+t+")",b.name="ChunkLoadError",b.type=d,b.request=t,c[1](b)}}),"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,f)=>{var c,d,t=f[0],b=f[1],o=f[2],n=0;if(t.some((a=>0!==e[a]))){for(c in b)r.o(b,c)&&(r.m[c]=b[c]);if(o)var i=o(r)}for(a&&a(f);n{"use strict";var e,f,a,d,c,b={},t={};function r(e){var f=t[e];if(void 0!==f)return f.exports;var a=t[e]={id:e,loaded:!1,exports:{}};return b[e].call(a.exports,a,a.exports,r),a.loaded=!0,a.exports}r.m=b,r.c=t,e=[],r.O=(f,a,d,c)=>{if(!a){var b=1/0;for(i=0;i=c)&&Object.keys(r.O).every((e=>r.O[e](a[o])))?a.splice(o--,1):(t=!1,c0&&e[i-1][2]>c;i--)e[i]=e[i-1];e[i]=[a,d,c]},r.n=e=>{var f=e&&e.__esModule?()=>e.default:()=>e;return r.d(f,{a:f}),f},a=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,d){if(1&d&&(e=this(e)),8&d)return e;if("object"==typeof e&&e){if(4&d&&e.__esModule)return e;if(16&d&&"function"==typeof e.then)return e}var c=Object.create(null);r.r(c);var b={};f=f||[null,a({}),a([]),a(a)];for(var t=2&d&&e;"object"==typeof t&&!~f.indexOf(t);t=a(t))Object.getOwnPropertyNames(t).forEach((f=>b[f]=()=>e[f]));return b.default=()=>e,r.d(c,b),c},r.d=(e,f)=>{for(var a in f)r.o(f,a)&&!r.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:f[a]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((f,a)=>(r.f[a](e,f),f)),[])),r.u=e=>"assets/js/"+({53:"935f2afb",150:"41748239",774:"544aba92",917:"ec9b348c",982:"19139c30",1125:"8f2faa25",1181:"5b2e78ee",1283:"25929091",1321:"80060540",1351:"e9780fb0",1444:"3cf0876a",1483:"1b37b4b0",1605:"6158391e",1888:"35f90ace",1914:"10c2b1cf",2083:"9becebd9",2094:"8d775e4d",2190:"a85ccfbf",2357:"43c91bec",2408:"fa9519d0",2430:"c1b0a72f",2482:"2f599c6d",2632:"65a720d8",2637:"6ede8325",2871:"c81dfe5f",2907:"78e65ac0",3072:"72f1352f",3237:"1df93b7f",3400:"e8f56a24",3469:"918c9c28",3633:"e1621294",3861:"1d29b0d8",3946:"ebaf9aeb",4014:"e8c0cc48",4145:"82e69e4a",4356:"48224a32",4368:"a94703ab",4494:"5f0d6238",4630:"53fd9a32",4798:"a62d60fb",5069:"c67f0456",5112:"b0683616",5291:"e849b732",5671:"1ff5abae",5724:"100d50c4",5966:"df751193",5998:"e2d1ed78",6119:"418823fc",6662:"44a464d7",6863:"712b8a2d",6942:"6fe236e0",6970:"c0f01452",7478:"7bec51cf",7659:"5181bfc2",7706:"5fc975be",7792:"3b5ed4ca",7918:"17896441",7920:"1a4e3797",8137:"4d3d5107",8171:"c1fd7385",8466:"7ef89a43",8518:"a7bd4aaa",8673:"b0e8dd6d",8751:"b7f64af1",8864:"fdebbd26",8968:"ddc35001",9013:"2bd67647",9088:"67b1613a",9159:"785e1e6a",9330:"62692344",9368:"4c3c7f6c",9428:"a4b720fd",9597:"d620695a",9661:"5e95c892",9860:"790ff6d5"}[e]||e)+"."+{53:"b83907d5",150:"308d9309",774:"973bfd97",917:"2cc92972",982:"4f7b6cbe",1125:"1f8e5cc5",1181:"8b4a2eea",1283:"4bcc76f7",1321:"fa6ad726",1351:"8b54cb62",1426:"ada98236",1444:"428e32d6",1483:"75412d65",1605:"5ebdff7e",1772:"05b37fcf",1888:"d08ce316",1914:"b046c885",2083:"822c72d3",2094:"de1b00a1",2190:"d4e7bdd2",2357:"db589e06",2408:"08a5e7fd",2430:"b56d97de",2482:"03033809",2632:"13074926",2637:"4dd5a347",2871:"55a95f78",2907:"59b2ef74",3072:"311a6085",3237:"1ca22ede",3400:"194de0ce",3469:"a570135e",3633:"0a2fc20e",3861:"21c83f2c",3946:"7eb0c752",4014:"9c908003",4145:"47151c70",4356:"ae238b0a",4368:"978f186e",4494:"07b7af73",4630:"1618df65",4798:"49014181",5069:"d83488f7",5112:"c91f045c",5291:"98b8fe46",5671:"3774152c",5724:"49ead4c4",5966:"4637bd9c",5998:"3bc94e31",6119:"84656fe2",6662:"bfee92aa",6863:"8a52facb",6942:"ded0e513",6945:"73cb8f6d",6970:"e21d96f9",7478:"58a9bcae",7659:"1cd0a538",7706:"8d26ad56",7792:"2b860f61",7918:"eba4c161",7920:"1065628c",8137:"69a82cd1",8171:"19344f10",8466:"154ed672",8518:"5fdeee4a",8673:"480b3d8a",8751:"4fb71bce",8864:"9af8dffb",8894:"d8733546",8968:"41e90c63",9013:"758121c9",9088:"58e75e41",9159:"720f9aed",9330:"29aaf915",9368:"4099e1b2",9428:"7a47f5f7",9597:"2b3a4bdd",9661:"53db30f1",9860:"5e42560f"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,f)=>Object.prototype.hasOwnProperty.call(e,f),d={},c="docsite:",r.l=(e,f,a,b)=>{if(d[e])d[e].push(f);else{var t,o;if(void 0!==a)for(var n=document.getElementsByTagName("script"),i=0;i{t.onerror=t.onload=null,clearTimeout(s);var c=d[e];if(delete d[e],t.parentNode&&t.parentNode.removeChild(t),c&&c.forEach((e=>e(a))),f)return f(a)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=l.bind(null,t.onerror),t.onload=l.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/fluentui-charting-contrib/",r.gca=function(e){return e={17896441:"7918",25929091:"1283",41748239:"150",62692344:"9330",80060540:"1321","935f2afb":"53","544aba92":"774",ec9b348c:"917","19139c30":"982","8f2faa25":"1125","5b2e78ee":"1181",e9780fb0:"1351","3cf0876a":"1444","1b37b4b0":"1483","6158391e":"1605","35f90ace":"1888","10c2b1cf":"1914","9becebd9":"2083","8d775e4d":"2094",a85ccfbf:"2190","43c91bec":"2357",fa9519d0:"2408",c1b0a72f:"2430","2f599c6d":"2482","65a720d8":"2632","6ede8325":"2637",c81dfe5f:"2871","78e65ac0":"2907","72f1352f":"3072","1df93b7f":"3237",e8f56a24:"3400","918c9c28":"3469",e1621294:"3633","1d29b0d8":"3861",ebaf9aeb:"3946",e8c0cc48:"4014","82e69e4a":"4145","48224a32":"4356",a94703ab:"4368","5f0d6238":"4494","53fd9a32":"4630",a62d60fb:"4798",c67f0456:"5069",b0683616:"5112",e849b732:"5291","1ff5abae":"5671","100d50c4":"5724",df751193:"5966",e2d1ed78:"5998","418823fc":"6119","44a464d7":"6662","712b8a2d":"6863","6fe236e0":"6942",c0f01452:"6970","7bec51cf":"7478","5181bfc2":"7659","5fc975be":"7706","3b5ed4ca":"7792","1a4e3797":"7920","4d3d5107":"8137",c1fd7385:"8171","7ef89a43":"8466",a7bd4aaa:"8518",b0e8dd6d:"8673",b7f64af1:"8751",fdebbd26:"8864",ddc35001:"8968","2bd67647":"9013","67b1613a":"9088","785e1e6a":"9159","4c3c7f6c":"9368",a4b720fd:"9428",d620695a:"9597","5e95c892":"9661","790ff6d5":"9860"}[e]||e,r.p+r.u(e)},(()=>{var e={1303:0,532:0};r.f.j=(f,a)=>{var d=r.o(e,f)?e[f]:void 0;if(0!==d)if(d)a.push(d[2]);else if(/^(1303|532)$/.test(f))e[f]=0;else{var c=new Promise(((a,c)=>d=e[f]=[a,c]));a.push(d[2]=c);var b=r.p+r.u(f),t=new Error;r.l(b,(a=>{if(r.o(e,f)&&(0!==(d=e[f])&&(e[f]=void 0),d)){var c=a&&("load"===a.type?"missing":a.type),b=a&&a.target&&a.target.src;t.message="Loading chunk "+f+" failed.\n("+c+": "+b+")",t.name="ChunkLoadError",t.type=c,t.request=b,d[1](t)}}),"chunk-"+f,f)}},r.O.j=f=>0===e[f];var f=(f,a)=>{var d,c,b=a[0],t=a[1],o=a[2],n=0;if(b.some((f=>0!==e[f]))){for(d in t)r.o(t,d)&&(r.m[d]=t[d]);if(o)var i=o(r)}for(f&&f(a);n
Accessibility | FluentUI Charting Contrib Docsite
-
+
-The react charting library is accessibility MAS C compliant.
+
The react charting library is accessibility MAS C compliant.
We satisfy accessibility requirements for the following aspects (and more).
Screen readers and narrators in different browser modes.
diff --git a/docs/BundleSize.html b/docs/BundleSize.html
index 6e75edefec..b455101ff2 100644
--- a/docs/BundleSize.html
+++ b/docs/BundleSize.html
@@ -5,11 +5,11 @@
Bundle Size | FluentUI Charting Contrib Docsite
-
+
-Bundle Size
+
Bundle Size
This table measures the maximum unpacked size of each chart control. This is measured by the monosize tool .
Each chart is tree shakable .
The actual size overhead for your application consuming the chart will depend on only the piece of functionality that you are importing.
diff --git a/docs/CHANGELOG.html b/docs/CHANGELOG.html
index 20338c5a53..f0daa4c9ad 100644
--- a/docs/CHANGELOG.html
+++ b/docs/CHANGELOG.html
@@ -5,7 +5,7 @@
Release Log | FluentUI Charting Contrib Docsite
-
+
diff --git a/docs/Charting-Concepts/AreaChart.html b/docs/Charting-Concepts/AreaChart.html
index fa9d56d26a..ae53d9b009 100644
--- a/docs/Charting-Concepts/AreaChart.html
+++ b/docs/Charting-Concepts/AreaChart.html
@@ -3,13 +3,13 @@
-
Contributor guide: Area Chart | FluentUI Charting Contrib Docsite
+
Area Chart | FluentUI Charting Contrib Docsite
-
+
-
Charting Concepts Contributor guide: Area Chart On this page
\ No newline at end of file
diff --git a/docs/Charting-Concepts/DonutChart.html b/docs/Charting-Concepts/DonutChart.html
index 739907ae6d..24135187a6 100644
--- a/docs/Charting-Concepts/DonutChart.html
+++ b/docs/Charting-Concepts/DonutChart.html
@@ -3,13 +3,13 @@
-
Contributor guide: Donut Chart | FluentUI Charting Contrib Docsite
+
Donut Chart | FluentUI Charting Contrib Docsite
-
+
-
Charting Concepts Contributor guide: Donut Chart On this page
Contributor guide: Donut Chart
+
On this page
Donut Chart
A Donut chart is a type of chart used to visualize data as a circular shape with the central area hollow. It is similar to a Pie chart, but with the area in the center cut out instead of a solid circle.
Donut charts are useful for displaying data as parts of a whole, where each segment represents a percentage or proportion of the total. The segments are typically colored differently to make them easier to distinguish.
@@ -208,6 +208,6 @@
Dev Desig
All of the above scenarios have 95+ Lighthouse score. We are efficient in terms of the performance of the donut chart.
-
+
\ No newline at end of file
diff --git a/docs/Charting-Concepts/GaugeChart.html b/docs/Charting-Concepts/GaugeChart.html
index fb72fe6af6..64b6cfa593 100644
--- a/docs/Charting-Concepts/GaugeChart.html
+++ b/docs/Charting-Concepts/GaugeChart.html
@@ -3,13 +3,13 @@
-
Contributor guide: Gauge Chart | FluentUI Charting Contrib Docsite
+
Gauge Chart | FluentUI Charting Contrib Docsite
-
+
-
Charting Concepts Contributor guide: Gauge Chart On this page
Contributor guide: Gauge Chart
+
On this page
Gauge Chart
Gauge chart measures the progress of a metric against its target and its primary components are a speedometer and a needle. The speedometer usually consists of color-coded segments progressing value from left to right.
Use cases
Gauge chart offers a quick and intuitive way to evaluate a single value within a specific range and its relation to targets or thresholds. Here are some common use cases for gauge chart:
@@ -265,6 +265,6 @@
+
Extensions
\ No newline at end of file
diff --git a/docs/Charting-Concepts/GroupedVerticalBarChart.html b/docs/Charting-Concepts/GroupedVerticalBarChart.html
index 7ff0dadf70..854de65fe0 100644
--- a/docs/Charting-Concepts/GroupedVerticalBarChart.html
+++ b/docs/Charting-Concepts/GroupedVerticalBarChart.html
@@ -3,13 +3,13 @@
-
Contributor guide: Grouped Vertical Bar Chart | FluentUI Charting Contrib Docsite
+
Grouped Vertical Bar Chart | FluentUI Charting Contrib Docsite
-
+
-
Charting Concepts Contributor guide: Grouped Vertical Bar Chart Contributor guide: Grouped Vertical Bar Chart
+
Grouped Vertical Bar Chart
A grouped vertical bar chart is a type of chart that displays multiple series of data as groups of bars, with each bar representing a category. The bars are grouped together side by side, with each group representing a different series.
In a grouped vertical bar chart, the x-axis represents the categories, while the y-axis represents the values of the series. Each bar in a group is colored differently to differentiate between the series.
@@ -561,6 +561,6 @@
Formula for calculating the width of each bar:
-
barWidth = (x0.bandwidth() - spaceBetweenBars) / this._keys.length
+
barWidth = (x0.bandwidth() - spaceBetweenBars) / this._keys.length