[{"data":1,"prerenderedAt":2803},["ShallowReactive",2],{"doc:\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-gauge-chart-in-excel-with-python":3,"surround:\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-gauge-chart-in-excel-with-python":2770,"ancestors:\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-gauge-chart-in-excel-with-python":2779,"children:\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-gauge-chart-in-excel-with-python":2784,"related:\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-gauge-chart-in-excel-with-python":2785},{"id":4,"title":5,"body":6,"dateModified":2736,"datePublished":2736,"description":2737,"extension":2738,"faq":2739,"keyword":2748,"kind":2749,"meta":2750,"navigation":190,"path":2759,"seo":2760,"slug":2763,"stem":2764,"topics":2765,"type":2768,"__hash__":2769},"docs\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-gauge-chart-in-excel-with-python\u002Findex.md","Create a Gauge Chart in Excel with Python",{"type":7,"value":8,"toc":2724},"minimark",[9,19,24,50,53,155,159,162,627,647,651,654,1053,1062,1066,1069,1156,1163,1369,1373,1376,1492,1690,1693,1697,1700,2462,2477,2594,2598,2645,2649,2659,2663,2669,2675,2681,2687,2691,2720],[10,11,12,13,18],"p",{},"Dashboards love gauges: a half-circle dial showing one number against its good, acceptable and bad ranges — customer satisfaction at 72 out of 100, in the green band that starts at 75? No, just short, in amber. Excel has no gauge chart type, but the classic construction needs only a doughnut chart: make it a half circle by giving the bottom half an invisible slice, colour the bands for the thresholds, and add a second ring whose coloured arc runs from the start of the dial to the current value. Built from Python with openpyxl, the gauge is driven by formulas on the sheet, so when the KPI value is updated the dial moves with it. This page is part of ",[14,15,17],"a",{"href":16},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002F","Creating Charts in Excel with openpyxl",".",[20,21,23],"h2",{"id":22},"prerequisites","Prerequisites",[25,26,31],"pre",{"className":27,"code":28,"language":29,"meta":30,"style":30},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install openpyxl\n","bash","",[32,33,34],"code",{"__ignoreMap":30},[35,36,39,43,47],"span",{"class":37,"line":38},"line",1,[35,40,42],{"class":41},"sMTad","pip",[35,44,46],{"class":45},"srMev"," install",[35,48,49],{"class":45}," openpyxl\n",[10,51,52],{},"The gauge shows a customer satisfaction score from 0 to 100, with red below 50, amber from 50 to 75 and green from 75 upwards. The same construction works for any KPI with a minimum, a maximum and thresholds: on-time delivery rate, budget used, capacity utilisation. LibreOffice renders the result for checking.",[54,55,63,64,63,68,63,72,63,80,63,90,63,101,63,108,63,113,63,118,63,125,63,130,63,134,63,139,63,146,63,151],"svg",{"viewBox":56,"role":57,"ariaLabelledBy":58,"xmlns":61,"style":62},"44 0 672 331","img",[59,60],"gg-idea-t","gg-idea-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:672px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[65,66,67],"title",{"id":59},"A gauge is a doughnut with half of it hidden",[69,70,71],"desc",{"id":60},"Layers explaining the construction. The outer ring holds the red, amber and green bands whose sizes are the threshold widths; the inner ring holds the value arc and the remainder; each ring has a final slice equal to the full range that is made invisible, which turns the circle into a half circle.",[73,74],"rect",{"x":75,"y":76,"width":77,"height":78,"fill":79},"44","0","672","331","#ffffff",[73,81],{"x":82,"y":83,"width":84,"height":85,"rx":86,"fill":87,"stroke":88,"style":89},"60.0","16.0","640.0","93.0","12","#f0f4ff","var(--brand,#5b5cf0)","stroke-width:2px",[91,92,94],"g",{"transform":93},"translate(368.0,29.0) scale(1.000)",[95,96],"path",{"d":97,"fill":98,"stroke":99,"style":100},"M12 3l9 5-9 5-9-5z M3 13l9 5 9-5 M3 17l9 5 9-5","none","var(--brand-strong,#4338ca)","stroke-width:1.80px;stroke-linecap:round;stroke-linejoin:round",[102,103,107],"text",{"x":104,"y":105,"style":106},"380.0","75.5","font-size:13.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Outer ring — bands",[102,109,112],{"x":104,"y":110,"style":111},"95.0","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","red 0–50 · amber 50–75 · green 75–100 · hidden 100",[73,114],{"x":82,"y":115,"width":84,"height":85,"rx":86,"fill":116,"stroke":117,"style":89},"119.0","#d9f4f1","var(--teal,#0f9488)",[91,119,121],{"transform":120},"translate(368.0,132.0) scale(1.000)",[95,122],{"d":123,"fill":98,"stroke":124,"style":100},"M4 20h16 M7 17v-5 M12 17V7 M17 17v-8","var(--teal-ink,#0b6157)",[102,126,129],{"x":104,"y":127,"style":128},"178.5","font-size:13.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","Inner ring — value",[102,131,133],{"x":104,"y":132,"style":111},"198.0","value 72 · remainder 28 · hidden 100",[73,135],{"x":82,"y":136,"width":84,"height":85,"rx":86,"fill":137,"stroke":138,"style":89},"222.0","#e7ebef","var(--line,#cdd5e6)",[91,140,142],{"transform":141},"translate(368.0,235.0) scale(1.000)",[95,143],{"d":144,"fill":98,"stroke":145,"style":100},"M20 11a8 8 0 1 0-2.3 5.7 M20 4v7h-7","var(--text,#172033)",[102,147,150],{"x":104,"y":148,"style":149},"281.5","font-size:13.5px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","firstSliceAng = 270",[102,152,154],{"x":104,"y":153,"style":111},"301.0","starts at 9 o'clock, so the hidden half is the bottom",[20,156,158],{"id":157},"step-1-the-helper-table-with-live-formulas","Step 1 — The helper table with live formulas",[10,160,161],{},"The chart reads a small table. The KPI value and the thresholds are inputs; everything the rings need is calculated from them, so the gauge follows any change to the inputs:",[25,163,167],{"className":164,"code":165,"language":166,"meta":30,"style":30},"language-python shiki shiki-themes github-light github-dark-high-contrast","from openpyxl import Workbook\n\nwb = Workbook()\nws = wb.active\nws.title = \"Gauge\"\ninputs = {\"B1\": (\"KPI value\", 72), \"B2\": (\"Minimum\", 0), \"B3\": (\"Maximum\", 100),\n          \"B4\": (\"Amber from\", 50), \"B5\": (\"Green from\", 75)}\nfor ref, (label, value) in inputs.items():\n    ws[f\"A{ref[1:]}\"], ws[ref] = label, value\n\nws[\"A7\"], ws[\"B7\"], ws[\"C7\"] = \"Slice\", \"Bands\", \"Value\"\nrows = [\n    (\"Red\",    \"=B4-B2\",  \"=MIN(MAX(B1,B2),B3)-B2\"),\n    (\"Amber\",  \"=B5-B4\",  \"=B3-MIN(MAX(B1,B2),B3)\"),\n    (\"Green\",  \"=B3-B5\",  \"=0\"),\n    (\"Hidden\", \"=B3-B2\",  \"=B3-B2\"),\n]\nfor r, row in enumerate(rows, start=8):\n    for c, v in enumerate(row, start=1):\n        ws.cell(r, c, v)\nprint([[ws.cell(r, c).value for c in range(1, 4)] for r in range(7, 12)])\n","python",[32,168,169,185,192,204,215,226,286,320,335,374,379,417,428,451,471,491,510,516,544,568,574],{"__ignoreMap":30},[35,170,171,175,179,182],{"class":37,"line":38},[35,172,174],{"class":173},"s-kum","from",[35,176,178],{"class":177},"skGVy"," openpyxl ",[35,180,181],{"class":173},"import",[35,183,184],{"class":177}," Workbook\n",[35,186,188],{"class":37,"line":187},2,[35,189,191],{"emptyLinePlaceholder":190},true,"\n",[35,193,195,198,201],{"class":37,"line":194},3,[35,196,197],{"class":177},"wb ",[35,199,200],{"class":173},"=",[35,202,203],{"class":177}," Workbook()\n",[35,205,207,210,212],{"class":37,"line":206},4,[35,208,209],{"class":177},"ws ",[35,211,200],{"class":173},[35,213,214],{"class":177}," wb.active\n",[35,216,218,221,223],{"class":37,"line":217},5,[35,219,220],{"class":177},"ws.title ",[35,222,200],{"class":173},[35,224,225],{"class":45}," \"Gauge\"\n",[35,227,229,232,234,237,240,243,246,249,253,256,259,261,264,266,268,270,273,275,278,280,283],{"class":37,"line":228},6,[35,230,231],{"class":177},"inputs ",[35,233,200],{"class":173},[35,235,236],{"class":177}," {",[35,238,239],{"class":45},"\"B1\"",[35,241,242],{"class":177},": (",[35,244,245],{"class":45},"\"KPI value\"",[35,247,248],{"class":177},", ",[35,250,252],{"class":251},"sP0c6","72",[35,254,255],{"class":177},"), ",[35,257,258],{"class":45},"\"B2\"",[35,260,242],{"class":177},[35,262,263],{"class":45},"\"Minimum\"",[35,265,248],{"class":177},[35,267,76],{"class":251},[35,269,255],{"class":177},[35,271,272],{"class":45},"\"B3\"",[35,274,242],{"class":177},[35,276,277],{"class":45},"\"Maximum\"",[35,279,248],{"class":177},[35,281,282],{"class":251},"100",[35,284,285],{"class":177},"),\n",[35,287,289,292,294,297,299,302,304,307,309,312,314,317],{"class":37,"line":288},7,[35,290,291],{"class":45},"          \"B4\"",[35,293,242],{"class":177},[35,295,296],{"class":45},"\"Amber from\"",[35,298,248],{"class":177},[35,300,301],{"class":251},"50",[35,303,255],{"class":177},[35,305,306],{"class":45},"\"B5\"",[35,308,242],{"class":177},[35,310,311],{"class":45},"\"Green from\"",[35,313,248],{"class":177},[35,315,316],{"class":251},"75",[35,318,319],{"class":177},")}\n",[35,321,323,326,329,332],{"class":37,"line":322},8,[35,324,325],{"class":173},"for",[35,327,328],{"class":177}," ref, (label, value) ",[35,330,331],{"class":173},"in",[35,333,334],{"class":177}," inputs.items():\n",[35,336,338,341,344,347,351,354,357,360,363,366,369,371],{"class":37,"line":337},9,[35,339,340],{"class":177},"    ws[",[35,342,343],{"class":173},"f",[35,345,346],{"class":45},"\"A",[35,348,350],{"class":349},"sSjpA","{",[35,352,353],{"class":177},"ref[",[35,355,356],{"class":251},"1",[35,358,359],{"class":177},":]",[35,361,362],{"class":349},"}",[35,364,365],{"class":45},"\"",[35,367,368],{"class":177},"], ws[ref] ",[35,370,200],{"class":173},[35,372,373],{"class":177}," label, value\n",[35,375,377],{"class":37,"line":376},10,[35,378,191],{"emptyLinePlaceholder":190},[35,380,382,385,388,391,394,396,399,402,404,407,409,412,414],{"class":37,"line":381},11,[35,383,384],{"class":177},"ws[",[35,386,387],{"class":45},"\"A7\"",[35,389,390],{"class":177},"], ws[",[35,392,393],{"class":45},"\"B7\"",[35,395,390],{"class":177},[35,397,398],{"class":45},"\"C7\"",[35,400,401],{"class":177},"] ",[35,403,200],{"class":173},[35,405,406],{"class":45}," \"Slice\"",[35,408,248],{"class":177},[35,410,411],{"class":45},"\"Bands\"",[35,413,248],{"class":177},[35,415,416],{"class":45},"\"Value\"\n",[35,418,420,423,425],{"class":37,"line":419},12,[35,421,422],{"class":177},"rows ",[35,424,200],{"class":173},[35,426,427],{"class":177}," [\n",[35,429,431,434,437,440,443,446,449],{"class":37,"line":430},13,[35,432,433],{"class":177},"    (",[35,435,436],{"class":45},"\"Red\"",[35,438,439],{"class":177},",    ",[35,441,442],{"class":45},"\"=B4-B2\"",[35,444,445],{"class":177},",  ",[35,447,448],{"class":45},"\"=MIN(MAX(B1,B2),B3)-B2\"",[35,450,285],{"class":177},[35,452,454,456,459,461,464,466,469],{"class":37,"line":453},14,[35,455,433],{"class":177},[35,457,458],{"class":45},"\"Amber\"",[35,460,445],{"class":177},[35,462,463],{"class":45},"\"=B5-B4\"",[35,465,445],{"class":177},[35,467,468],{"class":45},"\"=B3-MIN(MAX(B1,B2),B3)\"",[35,470,285],{"class":177},[35,472,474,476,479,481,484,486,489],{"class":37,"line":473},15,[35,475,433],{"class":177},[35,477,478],{"class":45},"\"Green\"",[35,480,445],{"class":177},[35,482,483],{"class":45},"\"=B3-B5\"",[35,485,445],{"class":177},[35,487,488],{"class":45},"\"=0\"",[35,490,285],{"class":177},[35,492,494,496,499,501,504,506,508],{"class":37,"line":493},16,[35,495,433],{"class":177},[35,497,498],{"class":45},"\"Hidden\"",[35,500,248],{"class":177},[35,502,503],{"class":45},"\"=B3-B2\"",[35,505,445],{"class":177},[35,507,503],{"class":45},[35,509,285],{"class":177},[35,511,513],{"class":37,"line":512},17,[35,514,515],{"class":177},"]\n",[35,517,519,521,524,526,529,532,536,538,541],{"class":37,"line":518},18,[35,520,325],{"class":173},[35,522,523],{"class":177}," r, row ",[35,525,331],{"class":173},[35,527,528],{"class":251}," enumerate",[35,530,531],{"class":177},"(rows, ",[35,533,535],{"class":534},"sa561","start",[35,537,200],{"class":173},[35,539,540],{"class":251},"8",[35,542,543],{"class":177},"):\n",[35,545,547,550,553,555,557,560,562,564,566],{"class":37,"line":546},19,[35,548,549],{"class":173},"    for",[35,551,552],{"class":177}," c, v ",[35,554,331],{"class":173},[35,556,528],{"class":251},[35,558,559],{"class":177},"(row, ",[35,561,535],{"class":534},[35,563,200],{"class":173},[35,565,356],{"class":251},[35,567,543],{"class":177},[35,569,571],{"class":37,"line":570},20,[35,572,573],{"class":177},"        ws.cell(r, c, v)\n",[35,575,577,580,583,585,588,590,593,596,598,600,603,606,608,611,613,615,617,620,622,624],{"class":37,"line":576},21,[35,578,579],{"class":251},"print",[35,581,582],{"class":177},"([[ws.cell(r, c).value ",[35,584,325],{"class":173},[35,586,587],{"class":177}," c ",[35,589,331],{"class":173},[35,591,592],{"class":251}," range",[35,594,595],{"class":177},"(",[35,597,356],{"class":251},[35,599,248],{"class":177},[35,601,602],{"class":251},"4",[35,604,605],{"class":177},")] ",[35,607,325],{"class":173},[35,609,610],{"class":177}," r ",[35,612,331],{"class":173},[35,614,592],{"class":251},[35,616,595],{"class":177},[35,618,619],{"class":251},"7",[35,621,248],{"class":177},[35,623,86],{"class":251},[35,625,626],{"class":177},")])\n",[10,628,629,630,634,635,638,639,642,643,646],{},"The ",[631,632,633],"em",{},"Bands"," column holds the width of each band — red from the minimum to the amber threshold, and so on — plus a hidden slice equal to the whole range. The ",[631,636,637],{},"Value"," column holds the value arc (from the minimum to the value, clamped to the range with ",[32,640,641],{},"MIN"," and ",[32,644,645],{},"MAX"," so an out-of-range reading does not break the dial), the remainder up to the maximum, and the same hidden slice. Because each ring's visible slices add up to exactly the hidden one, the visible part is always a half circle.",[20,648,650],{"id":649},"step-2-build-the-two-ring-doughnut","Step 2 — Build the two-ring doughnut",[10,652,653],{},"Add both columns as series. The first series becomes the inner ring, the second the outer, so the value comes first and the bands second:",[25,655,657],{"className":164,"code":656,"language":166,"meta":30,"style":30},"from openpyxl.chart import DoughnutChart, Reference\nfrom openpyxl.chart.series import DataPoint\n\ngauge = DoughnutChart()\ngauge.firstSliceAng = 270\ngauge.holeSize = 45\ngauge.add_data(Reference(ws, min_col=3, min_row=7, max_row=11), titles_from_data=True)   # inner: value\ngauge.add_data(Reference(ws, min_col=2, min_row=7, max_row=11), titles_from_data=True)   # outer: bands\ngauge.set_categories(Reference(ws, min_col=1, min_row=8, max_row=11))\n\ndef paint(series, colours):\n    series.dPt = []\n    for idx, colour in enumerate(colours):\n        point = DataPoint(idx=idx)\n        if colour is None:\n            point.graphicalProperties.noFill = True\n            point.graphicalProperties.line.noFill = True\n        else:\n            point.graphicalProperties.solidFill = colour\n            point.graphicalProperties.line.solidFill = \"FFFFFF\"\n        series.dPt.append(point)\n\nvalue_ring, band_ring = gauge.series\npaint(value_ring, [\"4338CA\", \"E5E7EB\", None, None])\npaint(band_ring, [\"DC2626\", \"F59E0B\", \"0F9488\", None])\nprint(gauge.firstSliceAng, [len(s.dPt) for s in gauge.series])\n",[32,658,659,671,683,687,697,707,717,766,806,836,840,852,862,876,894,911,921,930,937,947,957,962,967,978,1004,1029],{"__ignoreMap":30},[35,660,661,663,666,668],{"class":37,"line":38},[35,662,174],{"class":173},[35,664,665],{"class":177}," openpyxl.chart ",[35,667,181],{"class":173},[35,669,670],{"class":177}," DoughnutChart, Reference\n",[35,672,673,675,678,680],{"class":37,"line":187},[35,674,174],{"class":173},[35,676,677],{"class":177}," openpyxl.chart.series ",[35,679,181],{"class":173},[35,681,682],{"class":177}," DataPoint\n",[35,684,685],{"class":37,"line":194},[35,686,191],{"emptyLinePlaceholder":190},[35,688,689,692,694],{"class":37,"line":206},[35,690,691],{"class":177},"gauge ",[35,693,200],{"class":173},[35,695,696],{"class":177}," DoughnutChart()\n",[35,698,699,702,704],{"class":37,"line":217},[35,700,701],{"class":177},"gauge.firstSliceAng ",[35,703,200],{"class":173},[35,705,706],{"class":251}," 270\n",[35,708,709,712,714],{"class":37,"line":228},[35,710,711],{"class":177},"gauge.holeSize ",[35,713,200],{"class":173},[35,715,716],{"class":251}," 45\n",[35,718,719,722,725,727,730,732,735,737,739,741,744,746,749,751,754,756,759,762],{"class":37,"line":288},[35,720,721],{"class":177},"gauge.add_data(Reference(ws, ",[35,723,724],{"class":534},"min_col",[35,726,200],{"class":173},[35,728,729],{"class":251},"3",[35,731,248],{"class":177},[35,733,734],{"class":534},"min_row",[35,736,200],{"class":173},[35,738,619],{"class":251},[35,740,248],{"class":177},[35,742,743],{"class":534},"max_row",[35,745,200],{"class":173},[35,747,748],{"class":251},"11",[35,750,255],{"class":177},[35,752,753],{"class":534},"titles_from_data",[35,755,200],{"class":173},[35,757,758],{"class":251},"True",[35,760,761],{"class":177},")   ",[35,763,765],{"class":764},"s-wDw","# inner: value\n",[35,767,768,770,772,774,777,779,781,783,785,787,789,791,793,795,797,799,801,803],{"class":37,"line":322},[35,769,721],{"class":177},[35,771,724],{"class":534},[35,773,200],{"class":173},[35,775,776],{"class":251},"2",[35,778,248],{"class":177},[35,780,734],{"class":534},[35,782,200],{"class":173},[35,784,619],{"class":251},[35,786,248],{"class":177},[35,788,743],{"class":534},[35,790,200],{"class":173},[35,792,748],{"class":251},[35,794,255],{"class":177},[35,796,753],{"class":534},[35,798,200],{"class":173},[35,800,758],{"class":251},[35,802,761],{"class":177},[35,804,805],{"class":764},"# outer: bands\n",[35,807,808,811,813,815,817,819,821,823,825,827,829,831,833],{"class":37,"line":337},[35,809,810],{"class":177},"gauge.set_categories(Reference(ws, ",[35,812,724],{"class":534},[35,814,200],{"class":173},[35,816,356],{"class":251},[35,818,248],{"class":177},[35,820,734],{"class":534},[35,822,200],{"class":173},[35,824,540],{"class":251},[35,826,248],{"class":177},[35,828,743],{"class":534},[35,830,200],{"class":173},[35,832,748],{"class":251},[35,834,835],{"class":177},"))\n",[35,837,838],{"class":37,"line":376},[35,839,191],{"emptyLinePlaceholder":190},[35,841,842,845,849],{"class":37,"line":381},[35,843,844],{"class":173},"def",[35,846,848],{"class":847},"s_Opv"," paint",[35,850,851],{"class":177},"(series, colours):\n",[35,853,854,857,859],{"class":37,"line":419},[35,855,856],{"class":177},"    series.dPt ",[35,858,200],{"class":173},[35,860,861],{"class":177}," []\n",[35,863,864,866,869,871,873],{"class":37,"line":430},[35,865,549],{"class":173},[35,867,868],{"class":177}," idx, colour ",[35,870,331],{"class":173},[35,872,528],{"class":251},[35,874,875],{"class":177},"(colours):\n",[35,877,878,881,883,886,889,891],{"class":37,"line":453},[35,879,880],{"class":177},"        point ",[35,882,200],{"class":173},[35,884,885],{"class":177}," DataPoint(",[35,887,888],{"class":534},"idx",[35,890,200],{"class":173},[35,892,893],{"class":177},"idx)\n",[35,895,896,899,902,905,908],{"class":37,"line":473},[35,897,898],{"class":173},"        if",[35,900,901],{"class":177}," colour ",[35,903,904],{"class":173},"is",[35,906,907],{"class":251}," None",[35,909,910],{"class":177},":\n",[35,912,913,916,918],{"class":37,"line":493},[35,914,915],{"class":177},"            point.graphicalProperties.noFill ",[35,917,200],{"class":173},[35,919,920],{"class":251}," True\n",[35,922,923,926,928],{"class":37,"line":512},[35,924,925],{"class":177},"            point.graphicalProperties.line.noFill ",[35,927,200],{"class":173},[35,929,920],{"class":251},[35,931,932,935],{"class":37,"line":518},[35,933,934],{"class":173},"        else",[35,936,910],{"class":177},[35,938,939,942,944],{"class":37,"line":546},[35,940,941],{"class":177},"            point.graphicalProperties.solidFill ",[35,943,200],{"class":173},[35,945,946],{"class":177}," colour\n",[35,948,949,952,954],{"class":37,"line":570},[35,950,951],{"class":177},"            point.graphicalProperties.line.solidFill ",[35,953,200],{"class":173},[35,955,956],{"class":45}," \"FFFFFF\"\n",[35,958,959],{"class":37,"line":576},[35,960,961],{"class":177},"        series.dPt.append(point)\n",[35,963,965],{"class":37,"line":964},22,[35,966,191],{"emptyLinePlaceholder":190},[35,968,970,973,975],{"class":37,"line":969},23,[35,971,972],{"class":177},"value_ring, band_ring ",[35,974,200],{"class":173},[35,976,977],{"class":177}," gauge.series\n",[35,979,981,984,987,989,992,994,997,999,1001],{"class":37,"line":980},24,[35,982,983],{"class":177},"paint(value_ring, [",[35,985,986],{"class":45},"\"4338CA\"",[35,988,248],{"class":177},[35,990,991],{"class":45},"\"E5E7EB\"",[35,993,248],{"class":177},[35,995,996],{"class":251},"None",[35,998,248],{"class":177},[35,1000,996],{"class":251},[35,1002,1003],{"class":177},"])\n",[35,1005,1007,1010,1013,1015,1018,1020,1023,1025,1027],{"class":37,"line":1006},25,[35,1008,1009],{"class":177},"paint(band_ring, [",[35,1011,1012],{"class":45},"\"DC2626\"",[35,1014,248],{"class":177},[35,1016,1017],{"class":45},"\"F59E0B\"",[35,1019,248],{"class":177},[35,1021,1022],{"class":45},"\"0F9488\"",[35,1024,248],{"class":177},[35,1026,996],{"class":251},[35,1028,1003],{"class":177},[35,1030,1032,1034,1037,1040,1043,1045,1048,1050],{"class":37,"line":1031},26,[35,1033,579],{"class":251},[35,1035,1036],{"class":177},"(gauge.firstSliceAng, [",[35,1038,1039],{"class":251},"len",[35,1041,1042],{"class":177},"(s.dPt) ",[35,1044,325],{"class":173},[35,1046,1047],{"class":177}," s ",[35,1049,331],{"class":173},[35,1051,1052],{"class":177}," gauge.series])\n",[10,1054,1055,1057,1058,1061],{},[32,1056,150],{}," starts the first slice at nine o'clock and runs clockwise, so the visible slices sweep across the top and the hidden slice fills the bottom half. The hidden slices have no fill ",[631,1059,1060],{},"and"," no outline — leaving the outline in draws a faint circle around the invisible half. On the inner ring, the value arc is indigo and the remainder light grey; its third slice is zero-width and its fourth hidden. On the outer ring, the band colours come from the thresholds.",[20,1063,1065],{"id":1064},"step-3-title-size-and-placement","Step 3 — Title, size and placement",[10,1067,1068],{},"The number itself belongs in the title, where it is always readable, since a doughnut has no text in its hole:",[25,1070,1072],{"className":164,"code":1071,"language":166,"meta":30,"style":30},"gauge.legend = None\ngauge.title = \"Customer satisfaction\"\ngauge.width, gauge.height = 11, 6.5\nws[\"E1\"] = '=\"Score: \"&B1&\" of \"&B3'\nws.add_chart(gauge, \"A14\")\nwb.save(\"kpi_gauge.xlsx\")\nprint(ws[\"E1\"].value)\n",[32,1073,1074,1084,1094,1109,1123,1134,1144],{"__ignoreMap":30},[35,1075,1076,1079,1081],{"class":37,"line":38},[35,1077,1078],{"class":177},"gauge.legend ",[35,1080,200],{"class":173},[35,1082,1083],{"class":251}," None\n",[35,1085,1086,1089,1091],{"class":37,"line":187},[35,1087,1088],{"class":177},"gauge.title ",[35,1090,200],{"class":173},[35,1092,1093],{"class":45}," \"Customer satisfaction\"\n",[35,1095,1096,1099,1101,1104,1106],{"class":37,"line":194},[35,1097,1098],{"class":177},"gauge.width, gauge.height ",[35,1100,200],{"class":173},[35,1102,1103],{"class":251}," 11",[35,1105,248],{"class":177},[35,1107,1108],{"class":251},"6.5\n",[35,1110,1111,1113,1116,1118,1120],{"class":37,"line":206},[35,1112,384],{"class":177},[35,1114,1115],{"class":45},"\"E1\"",[35,1117,401],{"class":177},[35,1119,200],{"class":173},[35,1121,1122],{"class":45}," '=\"Score: \"&B1&\" of \"&B3'\n",[35,1124,1125,1128,1131],{"class":37,"line":217},[35,1126,1127],{"class":177},"ws.add_chart(gauge, ",[35,1129,1130],{"class":45},"\"A14\"",[35,1132,1133],{"class":177},")\n",[35,1135,1136,1139,1142],{"class":37,"line":228},[35,1137,1138],{"class":177},"wb.save(",[35,1140,1141],{"class":45},"\"kpi_gauge.xlsx\"",[35,1143,1133],{"class":177},[35,1145,1146,1148,1151,1153],{"class":37,"line":288},[35,1147,579],{"class":251},[35,1149,1150],{"class":177},"(ws[",[35,1152,1115],{"class":45},[35,1154,1155],{"class":177},"].value)\n",[10,1157,1158,1159,1162],{},"The formula in ",[32,1160,1161],{},"E1"," gives a live text label — \"Score: 72 of 100\" — that can sit above or beside the chart in a dashboard layout; the chart title stays generic so it does not go stale. A height a little over half the width suits a half circle and leaves less empty space under it.",[54,1164,63,1170,63,1173,63,1176,63,1181,63,1187,63,1192,63,1199,63,1205,63,1211,63,1214,63,1220,63,1224,63,1228,63,1232,63,1236,63,1240,63,1244,63,1246,63,1250,63,1252,63,1254,63,1256,63,1258,63,1261,63,1264,63,1266,63,1270,63,1272,63,1274,63,1276,63,1278,63,1281,63,1285,63,1287,63,1290,63,1292,63,1295,63,1297,63,1300,63,1303,63,1307,63,1309,63,1312,63,1314,63,1316,63,1318,63,1320,63,1323,63,1326,63,1328,63,1332,63,1334,63,1336,63,1338,63,1340,63,1345,63,1350,63,1355,63,1361,63,1365],{"viewBox":1165,"role":57,"ariaLabelledBy":1166,"xmlns":61,"style":1169},"132 0 495 226",[1167,1168],"gg-table-t","gg-table-d","width:100%;max-width:495px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[65,1171,1172],{"id":1167},"The helper table the rings read",[69,1174,1175],{"id":1168},"A worksheet with the inputs and the calculated slice table. The Bands column has 50, 25, 25 and 100; the Value column has 72, 28, 0 and 100.",[73,1177],{"x":1178,"y":76,"width":1179,"height":1180,"fill":79},"132","495","226",[73,1182],{"x":1183,"y":83,"width":1184,"height":1185,"rx":540,"fill":137,"stroke":138,"style":1186},"148.7","222.1","30.0","stroke-width:1.5px",[73,1188],{"x":1183,"y":1189,"width":1184,"height":1190,"rx":76,"fill":137,"stroke":138,"style":1191},"38.0","8.0","stroke-width:0px",[91,1193,1195],{"transform":1194},"translate(158.7,23.0) scale(0.667)",[95,1196],{"d":1197,"fill":98,"stroke":124,"style":1198},"M6 3h9l4 4v14H6z M15 3v4h4 M9.5 11.5l4.5 6 M14 11.5l-4.5 6","stroke-width:2.70px;stroke-linecap:round;stroke-linejoin:round",[102,1200,1204],{"x":1201,"y":1202,"style":1203},"180.7","36.0","font-size:12px;font-weight:700;fill:var(--text,#172033);text-anchor:start","kpi_gauge.xlsx",[73,1206],{"x":1183,"y":1207,"width":1208,"height":1209,"rx":76,"fill":137,"stroke":138,"style":1210},"46.0","32.0","24.0","stroke-width:1px",[73,1212],{"x":1201,"y":1207,"width":1213,"height":1209,"rx":76,"fill":137,"stroke":138,"style":1210},"68.1",[102,1215,1219],{"x":1216,"y":1217,"style":1218},"214.7","63.0","font-size:11px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[73,1221],{"x":1222,"y":1207,"width":1223,"height":1209,"rx":76,"fill":137,"stroke":138,"style":1210},"248.7","62.5",[102,1225,1227],{"x":1226,"y":1217,"style":1218},"280.0","B",[73,1229],{"x":1230,"y":1207,"width":1231,"height":1209,"rx":76,"fill":137,"stroke":138,"style":1210},"311.2","59.5",[102,1233,1235],{"x":1234,"y":1217,"style":1218},"341.0","C",[73,1237],{"x":1183,"y":1238,"width":1208,"height":1239,"rx":76,"fill":137,"stroke":138,"style":1210},"70.0","28.0",[102,1241,619],{"x":1242,"y":1243,"style":1218},"164.7","89.0",[73,1245],{"x":1201,"y":1238,"width":1213,"height":1239,"rx":76,"fill":87,"stroke":88,"style":1186},[102,1247,1249],{"x":1216,"y":1243,"style":1248},"font-size:12px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Slice",[73,1251],{"x":1222,"y":1238,"width":1223,"height":1239,"rx":76,"fill":87,"stroke":88,"style":1186},[102,1253,633],{"x":1226,"y":1243,"style":1248},[73,1255],{"x":1230,"y":1238,"width":1231,"height":1239,"rx":76,"fill":87,"stroke":88,"style":1186},[102,1257,637],{"x":1234,"y":1243,"style":1248},[73,1259],{"x":1183,"y":1260,"width":1208,"height":1239,"rx":76,"fill":137,"stroke":138,"style":1210},"98.0",[102,1262,540],{"x":1242,"y":1263,"style":1218},"117.0",[73,1265],{"x":1201,"y":1260,"width":1213,"height":1239,"rx":76,"fill":79,"stroke":138,"style":1210},[102,1267,1269],{"x":1216,"y":1263,"style":1268},"font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","Red",[73,1271],{"x":1222,"y":1260,"width":1223,"height":1239,"rx":76,"fill":79,"stroke":138,"style":1210},[102,1273,301],{"x":1226,"y":1263,"style":1268},[73,1275],{"x":1230,"y":1260,"width":1231,"height":1239,"rx":76,"fill":79,"stroke":138,"style":1210},[102,1277,252],{"x":1234,"y":1263,"style":1268},[73,1279],{"x":1183,"y":1280,"width":1208,"height":1239,"rx":76,"fill":137,"stroke":138,"style":1210},"126.0",[102,1282,1284],{"x":1242,"y":1283,"style":1218},"145.0","9",[73,1286],{"x":1201,"y":1280,"width":1213,"height":1239,"rx":76,"fill":79,"stroke":138,"style":1210},[102,1288,1289],{"x":1216,"y":1283,"style":1268},"Amber",[73,1291],{"x":1222,"y":1280,"width":1223,"height":1239,"rx":76,"fill":79,"stroke":138,"style":1210},[102,1293,1294],{"x":1226,"y":1283,"style":1268},"25",[73,1296],{"x":1230,"y":1280,"width":1231,"height":1239,"rx":76,"fill":79,"stroke":138,"style":1210},[102,1298,1299],{"x":1234,"y":1283,"style":1268},"28",[73,1301],{"x":1183,"y":1302,"width":1208,"height":1239,"rx":76,"fill":137,"stroke":138,"style":1210},"154.0",[102,1304,1306],{"x":1242,"y":1305,"style":1218},"173.0","10",[73,1308],{"x":1201,"y":1302,"width":1213,"height":1239,"rx":76,"fill":79,"stroke":138,"style":1210},[102,1310,1311],{"x":1216,"y":1305,"style":1268},"Green",[73,1313],{"x":1222,"y":1302,"width":1223,"height":1239,"rx":76,"fill":79,"stroke":138,"style":1210},[102,1315,1294],{"x":1226,"y":1305,"style":1268},[73,1317],{"x":1230,"y":1302,"width":1231,"height":1239,"rx":76,"fill":79,"stroke":138,"style":1210},[102,1319,76],{"x":1234,"y":1305,"style":1268},[73,1321],{"x":1183,"y":1322,"width":1208,"height":1239,"rx":76,"fill":137,"stroke":138,"style":1210},"182.0",[102,1324,748],{"x":1242,"y":1325,"style":1218},"201.0",[73,1327],{"x":1201,"y":1322,"width":1213,"height":1239,"rx":76,"fill":137,"stroke":138,"style":1186},[102,1329,1331],{"x":1216,"y":1325,"style":1330},"font-size:12px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","Hidden",[73,1333],{"x":1222,"y":1322,"width":1223,"height":1239,"rx":76,"fill":137,"stroke":138,"style":1186},[102,1335,282],{"x":1226,"y":1325,"style":1330},[73,1337],{"x":1230,"y":1322,"width":1231,"height":1239,"rx":76,"fill":137,"stroke":138,"style":1186},[102,1339,282],{"x":1234,"y":1325,"style":1330},[37,1341],{"x1":1342,"y1":1343,"x2":1344,"y2":1343,"stroke":88,"style":89},"378.7","113.0","410.7",[1346,1347],"polygon",{"points":1348,"fill":1349},"414.7,113.0 405.7,118.0 405.7,108.0","#5b5cf0",[73,1351],{"x":1352,"y":1353,"width":1354,"height":85,"rx":86,"fill":116,"stroke":117,"style":89},"420.7","66.5","190.6",[91,1356,1358],{"transform":1357},"translate(504.0,79.5) scale(1.000)",[95,1359],{"d":1360,"fill":98,"stroke":124,"style":100},"M12 9a3 3 0 1 0 .01 0z M12 2.5v3 M12 18.5v3 M2.5 12h3 M18.5 12h3 M5.3 5.3l2.1 2.1 M16.6 16.6l2.1 2.1 M5.3 18.7l2.1-2.1 M16.6 7.4l2.1-2.1",[102,1362,1364],{"x":1363,"y":1280,"style":128},"516.0","Formulas",[102,1366,1368],{"x":1363,"y":1367,"style":111},"145.5","follow B1 and the thresholds",[20,1370,1372],{"id":1371},"step-4-check-the-rendering-and-the-formulas","Step 4 — Check the rendering and the formulas",[10,1374,1375],{},"Render the workbook with LibreOffice, which also calculates the helper formulas, and read the calculated values back to confirm the rings add up:",[25,1377,1379],{"className":27,"code":1378,"language":29,"meta":30,"style":30},"soffice -env:UserInstallation=file:\u002F\u002F$PWD\u002Flo_profile --headless --convert-to pdf kpi_gauge.xlsx > \u002Fdev\u002Fnull 2>&1\nsoffice -env:UserInstallation=file:\u002F\u002F$PWD\u002Flo_profile --headless --convert-to xlsx --outdir calc kpi_gauge.xlsx > \u002Fdev\u002Fnull 2>&1\npdftoppm -png -r 60 -f 1 -l 1 kpi_gauge.pdf preview && ls preview* calc\n",[32,1380,1381,1416,1447],{"__ignoreMap":30},[35,1382,1383,1386,1389,1392,1395,1398,1401,1404,1407,1410,1413],{"class":37,"line":38},[35,1384,1385],{"class":41},"soffice",[35,1387,1388],{"class":251}," -env:UserInstallation=file:\u002F\u002F",[35,1390,1391],{"class":177},"$PWD",[35,1393,1394],{"class":251},"\u002Flo_profile",[35,1396,1397],{"class":251}," --headless",[35,1399,1400],{"class":251}," --convert-to",[35,1402,1403],{"class":45}," pdf",[35,1405,1406],{"class":45}," kpi_gauge.xlsx",[35,1408,1409],{"class":173}," >",[35,1411,1412],{"class":45}," \u002Fdev\u002Fnull",[35,1414,1415],{"class":173}," 2>&1\n",[35,1417,1418,1420,1422,1424,1426,1428,1430,1433,1436,1439,1441,1443,1445],{"class":37,"line":187},[35,1419,1385],{"class":41},[35,1421,1388],{"class":251},[35,1423,1391],{"class":177},[35,1425,1394],{"class":251},[35,1427,1397],{"class":251},[35,1429,1400],{"class":251},[35,1431,1432],{"class":45}," xlsx",[35,1434,1435],{"class":251}," --outdir",[35,1437,1438],{"class":45}," calc",[35,1440,1406],{"class":45},[35,1442,1409],{"class":173},[35,1444,1412],{"class":45},[35,1446,1415],{"class":173},[35,1448,1449,1452,1455,1458,1461,1464,1467,1470,1472,1475,1478,1481,1484,1486,1489],{"class":37,"line":194},[35,1450,1451],{"class":41},"pdftoppm",[35,1453,1454],{"class":251}," -png",[35,1456,1457],{"class":251}," -r",[35,1459,1460],{"class":251}," 60",[35,1462,1463],{"class":251}," -f",[35,1465,1466],{"class":251}," 1",[35,1468,1469],{"class":251}," -l",[35,1471,1466],{"class":251},[35,1473,1474],{"class":45}," kpi_gauge.pdf",[35,1476,1477],{"class":45}," preview",[35,1479,1480],{"class":177}," && ",[35,1482,1483],{"class":41},"ls",[35,1485,1477],{"class":45},[35,1487,1488],{"class":251},"*",[35,1490,1491],{"class":45}," calc\n",[25,1493,1495],{"className":164,"code":1494,"language":166,"meta":30,"style":30},"from openpyxl import load_workbook\n\ncalc = load_workbook(\"calc\u002Fkpi_gauge.xlsx\", data_only=True)[\"Gauge\"]\nbands = [calc.cell(r, 2).value for r in range(8, 12)]\nvalues = [calc.cell(r, 3).value for r in range(8, 12)]\nprint(\"bands\", bands, \"visible\", sum(bands[:3]), \"= hidden\", bands[3])\nprint(\"value\", values, \"visible\", sum(values[:3]), \"= hidden\", values[3], \"|\", calc[\"E1\"].value)\n",[32,1496,1497,1508,1512,1542,1576,1607,1645],{"__ignoreMap":30},[35,1498,1499,1501,1503,1505],{"class":37,"line":38},[35,1500,174],{"class":173},[35,1502,178],{"class":177},[35,1504,181],{"class":173},[35,1506,1507],{"class":177}," load_workbook\n",[35,1509,1510],{"class":37,"line":187},[35,1511,191],{"emptyLinePlaceholder":190},[35,1513,1514,1517,1519,1522,1525,1527,1530,1532,1534,1537,1540],{"class":37,"line":194},[35,1515,1516],{"class":177},"calc ",[35,1518,200],{"class":173},[35,1520,1521],{"class":177}," load_workbook(",[35,1523,1524],{"class":45},"\"calc\u002Fkpi_gauge.xlsx\"",[35,1526,248],{"class":177},[35,1528,1529],{"class":534},"data_only",[35,1531,200],{"class":173},[35,1533,758],{"class":251},[35,1535,1536],{"class":177},")[",[35,1538,1539],{"class":45},"\"Gauge\"",[35,1541,515],{"class":177},[35,1543,1544,1547,1549,1552,1554,1557,1559,1561,1563,1565,1567,1569,1571,1573],{"class":37,"line":206},[35,1545,1546],{"class":177},"bands ",[35,1548,200],{"class":173},[35,1550,1551],{"class":177}," [calc.cell(r, ",[35,1553,776],{"class":251},[35,1555,1556],{"class":177},").value ",[35,1558,325],{"class":173},[35,1560,610],{"class":177},[35,1562,331],{"class":173},[35,1564,592],{"class":251},[35,1566,595],{"class":177},[35,1568,540],{"class":251},[35,1570,248],{"class":177},[35,1572,86],{"class":251},[35,1574,1575],{"class":177},")]\n",[35,1577,1578,1581,1583,1585,1587,1589,1591,1593,1595,1597,1599,1601,1603,1605],{"class":37,"line":217},[35,1579,1580],{"class":177},"values ",[35,1582,200],{"class":173},[35,1584,1551],{"class":177},[35,1586,729],{"class":251},[35,1588,1556],{"class":177},[35,1590,325],{"class":173},[35,1592,610],{"class":177},[35,1594,331],{"class":173},[35,1596,592],{"class":251},[35,1598,595],{"class":177},[35,1600,540],{"class":251},[35,1602,248],{"class":177},[35,1604,86],{"class":251},[35,1606,1575],{"class":177},[35,1608,1609,1611,1613,1616,1619,1622,1624,1627,1630,1632,1635,1638,1641,1643],{"class":37,"line":228},[35,1610,579],{"class":251},[35,1612,595],{"class":177},[35,1614,1615],{"class":45},"\"bands\"",[35,1617,1618],{"class":177},", bands, ",[35,1620,1621],{"class":45},"\"visible\"",[35,1623,248],{"class":177},[35,1625,1626],{"class":251},"sum",[35,1628,1629],{"class":177},"(bands[:",[35,1631,729],{"class":251},[35,1633,1634],{"class":177},"]), ",[35,1636,1637],{"class":45},"\"= hidden\"",[35,1639,1640],{"class":177},", bands[",[35,1642,729],{"class":251},[35,1644,1003],{"class":177},[35,1646,1647,1649,1651,1654,1657,1659,1661,1663,1666,1668,1670,1672,1675,1677,1680,1683,1686,1688],{"class":37,"line":288},[35,1648,579],{"class":251},[35,1650,595],{"class":177},[35,1652,1653],{"class":45},"\"value\"",[35,1655,1656],{"class":177},", values, ",[35,1658,1621],{"class":45},[35,1660,248],{"class":177},[35,1662,1626],{"class":251},[35,1664,1665],{"class":177},"(values[:",[35,1667,729],{"class":251},[35,1669,1634],{"class":177},[35,1671,1637],{"class":45},[35,1673,1674],{"class":177},", values[",[35,1676,729],{"class":251},[35,1678,1679],{"class":177},"], ",[35,1681,1682],{"class":45},"\"|\"",[35,1684,1685],{"class":177},", calc[",[35,1687,1115],{"class":45},[35,1689,1155],{"class":177},[10,1691,1692],{},"Both rings' visible slices add up to the hidden slice, so each is exactly a half circle, and the value arc ends at 72 — inside the amber band, just short of green. The rendered page shows the dial with the indigo arc three-quarters of the way round the inner ring, under the red, amber and green bands.",[20,1694,1696],{"id":1695},"step-5-several-gauges-on-one-dashboard","Step 5 — Several gauges on one dashboard",[10,1698,1699],{},"Dashboards usually show a few KPIs side by side. Wrap the construction in a function that writes its helper table in its own block of columns and anchors its chart:",[25,1701,1703],{"className":164,"code":1702,"language":166,"meta":30,"style":30},"def add_gauge(ws, col, title, value, lo, hi, amber, green, anchor, bands=(\"DC2626\", \"F59E0B\", \"0F9488\")):\n    c = col\n    ws.cell(1, c, title)\n    for i, v in enumerate([value, lo, hi, amber, green], start=2):\n        ws.cell(i, c + 1, v)\n    x = ws.cell(1, c + 1).column_letter\n    for k, head in enumerate([\"Slice\", \"Bands\", \"Value\"]):\n        ws.cell(8, c + k, head)\n    table = [(\"Red\", f\"={x}5-{x}3\", f\"=MIN(MAX({x}2,{x}3),{x}4)-{x}3\"),\n             (\"Amber\", f\"={x}6-{x}5\", f\"={x}4-MIN(MAX({x}2,{x}3),{x}4)\"),\n             (\"Green\", f\"={x}4-{x}6\", \"=0\"), (\"Hidden\", f\"={x}4-{x}3\", f\"={x}4-{x}3\")]\n    for r, row in enumerate(table, start=9):\n        for k, v in enumerate(row):\n            ws.cell(r, c + k, v)\n    g = DoughnutChart()\n    g.firstSliceAng, g.holeSize, g.legend, g.title = 270, 45, None, title\n    g.add_data(Reference(ws, min_col=c + 2, min_row=8, max_row=12), titles_from_data=True)\n    g.add_data(Reference(ws, min_col=c + 1, min_row=8, max_row=12), titles_from_data=True)\n    paint(g.series[0], [\"4338CA\", \"E5E7EB\", None, None])\n    paint(g.series[1], [*bands, None])\n    g.width, g.height = 8, 5\n    ws.add_chart(g, anchor)\n\ndash = wb.create_sheet(\"Dashboard\")\nadd_gauge(dash, 1, \"On-time delivery %\", 91, 0, 100, 85, 95, \"A15\")\nadd_gauge(dash, 5, \"Budget used %\", 64, 0, 100, 80, 95, \"F15\", bands=(\"0F9488\", \"F59E0B\", \"DC2626\"))\nwb.save(\"kpi_gauge.xlsx\")\nprint(len(dash._charts), \"gauges on the dashboard\")\n",[32,1704,1705,1732,1742,1752,1774,1787,1809,1838,1852,1934,2007,2092,2113,2128,2138,2147,2169,2212,2252,2278,2295,2310,2315,2319,2334,2376,2436,2445],{"__ignoreMap":30},[35,1706,1707,1709,1712,1715,1717,1719,1721,1723,1725,1727,1729],{"class":37,"line":38},[35,1708,844],{"class":173},[35,1710,1711],{"class":847}," add_gauge",[35,1713,1714],{"class":177},"(ws, col, title, value, lo, hi, amber, green, anchor, bands",[35,1716,200],{"class":173},[35,1718,595],{"class":177},[35,1720,1012],{"class":45},[35,1722,248],{"class":177},[35,1724,1017],{"class":45},[35,1726,248],{"class":177},[35,1728,1022],{"class":45},[35,1730,1731],{"class":177},")):\n",[35,1733,1734,1737,1739],{"class":37,"line":187},[35,1735,1736],{"class":177},"    c ",[35,1738,200],{"class":173},[35,1740,1741],{"class":177}," col\n",[35,1743,1744,1747,1749],{"class":37,"line":194},[35,1745,1746],{"class":177},"    ws.cell(",[35,1748,356],{"class":251},[35,1750,1751],{"class":177},", c, title)\n",[35,1753,1754,1756,1759,1761,1763,1766,1768,1770,1772],{"class":37,"line":206},[35,1755,549],{"class":173},[35,1757,1758],{"class":177}," i, v ",[35,1760,331],{"class":173},[35,1762,528],{"class":251},[35,1764,1765],{"class":177},"([value, lo, hi, amber, green], ",[35,1767,535],{"class":534},[35,1769,200],{"class":173},[35,1771,776],{"class":251},[35,1773,543],{"class":177},[35,1775,1776,1779,1782,1784],{"class":37,"line":217},[35,1777,1778],{"class":177},"        ws.cell(i, c ",[35,1780,1781],{"class":173},"+",[35,1783,1466],{"class":251},[35,1785,1786],{"class":177},", v)\n",[35,1788,1789,1792,1794,1797,1799,1802,1804,1806],{"class":37,"line":228},[35,1790,1791],{"class":177},"    x ",[35,1793,200],{"class":173},[35,1795,1796],{"class":177}," ws.cell(",[35,1798,356],{"class":251},[35,1800,1801],{"class":177},", c ",[35,1803,1781],{"class":173},[35,1805,1466],{"class":251},[35,1807,1808],{"class":177},").column_letter\n",[35,1810,1811,1813,1816,1818,1820,1823,1826,1828,1830,1832,1835],{"class":37,"line":288},[35,1812,549],{"class":173},[35,1814,1815],{"class":177}," k, head ",[35,1817,331],{"class":173},[35,1819,528],{"class":251},[35,1821,1822],{"class":177},"([",[35,1824,1825],{"class":45},"\"Slice\"",[35,1827,248],{"class":177},[35,1829,411],{"class":45},[35,1831,248],{"class":177},[35,1833,1834],{"class":45},"\"Value\"",[35,1836,1837],{"class":177},"]):\n",[35,1839,1840,1843,1845,1847,1849],{"class":37,"line":322},[35,1841,1842],{"class":177},"        ws.cell(",[35,1844,540],{"class":251},[35,1846,1801],{"class":177},[35,1848,1781],{"class":173},[35,1850,1851],{"class":177}," k, head)\n",[35,1853,1854,1857,1859,1862,1864,1866,1868,1871,1873,1876,1878,1881,1883,1885,1887,1890,1892,1894,1897,1899,1901,1903,1906,1908,1910,1912,1915,1917,1919,1921,1924,1926,1928,1930,1932],{"class":37,"line":337},[35,1855,1856],{"class":177},"    table ",[35,1858,200],{"class":173},[35,1860,1861],{"class":177}," [(",[35,1863,436],{"class":45},[35,1865,248],{"class":177},[35,1867,343],{"class":173},[35,1869,1870],{"class":45},"\"=",[35,1872,350],{"class":349},[35,1874,1875],{"class":177},"x",[35,1877,362],{"class":349},[35,1879,1880],{"class":45},"5-",[35,1882,350],{"class":349},[35,1884,1875],{"class":177},[35,1886,362],{"class":349},[35,1888,1889],{"class":45},"3\"",[35,1891,248],{"class":177},[35,1893,343],{"class":173},[35,1895,1896],{"class":45},"\"=MIN(MAX(",[35,1898,350],{"class":349},[35,1900,1875],{"class":177},[35,1902,362],{"class":349},[35,1904,1905],{"class":45},"2,",[35,1907,350],{"class":349},[35,1909,1875],{"class":177},[35,1911,362],{"class":349},[35,1913,1914],{"class":45},"3),",[35,1916,350],{"class":349},[35,1918,1875],{"class":177},[35,1920,362],{"class":349},[35,1922,1923],{"class":45},"4)-",[35,1925,350],{"class":349},[35,1927,1875],{"class":177},[35,1929,362],{"class":349},[35,1931,1889],{"class":45},[35,1933,285],{"class":177},[35,1935,1936,1939,1941,1943,1945,1947,1949,1951,1953,1956,1958,1960,1962,1965,1967,1969,1971,1973,1975,1977,1980,1982,1984,1986,1988,1990,1992,1994,1996,1998,2000,2002,2005],{"class":37,"line":376},[35,1937,1938],{"class":177},"             (",[35,1940,458],{"class":45},[35,1942,248],{"class":177},[35,1944,343],{"class":173},[35,1946,1870],{"class":45},[35,1948,350],{"class":349},[35,1950,1875],{"class":177},[35,1952,362],{"class":349},[35,1954,1955],{"class":45},"6-",[35,1957,350],{"class":349},[35,1959,1875],{"class":177},[35,1961,362],{"class":349},[35,1963,1964],{"class":45},"5\"",[35,1966,248],{"class":177},[35,1968,343],{"class":173},[35,1970,1870],{"class":45},[35,1972,350],{"class":349},[35,1974,1875],{"class":177},[35,1976,362],{"class":349},[35,1978,1979],{"class":45},"4-MIN(MAX(",[35,1981,350],{"class":349},[35,1983,1875],{"class":177},[35,1985,362],{"class":349},[35,1987,1905],{"class":45},[35,1989,350],{"class":349},[35,1991,1875],{"class":177},[35,1993,362],{"class":349},[35,1995,1914],{"class":45},[35,1997,350],{"class":349},[35,1999,1875],{"class":177},[35,2001,362],{"class":349},[35,2003,2004],{"class":45},"4)\"",[35,2006,285],{"class":177},[35,2008,2009,2011,2013,2015,2017,2019,2021,2023,2025,2028,2030,2032,2034,2037,2039,2041,2044,2046,2048,2050,2052,2054,2056,2058,2060,2062,2064,2066,2068,2070,2072,2074,2076,2078,2080,2082,2084,2086,2088,2090],{"class":37,"line":381},[35,2010,1938],{"class":177},[35,2012,478],{"class":45},[35,2014,248],{"class":177},[35,2016,343],{"class":173},[35,2018,1870],{"class":45},[35,2020,350],{"class":349},[35,2022,1875],{"class":177},[35,2024,362],{"class":349},[35,2026,2027],{"class":45},"4-",[35,2029,350],{"class":349},[35,2031,1875],{"class":177},[35,2033,362],{"class":349},[35,2035,2036],{"class":45},"6\"",[35,2038,248],{"class":177},[35,2040,488],{"class":45},[35,2042,2043],{"class":177},"), (",[35,2045,498],{"class":45},[35,2047,248],{"class":177},[35,2049,343],{"class":173},[35,2051,1870],{"class":45},[35,2053,350],{"class":349},[35,2055,1875],{"class":177},[35,2057,362],{"class":349},[35,2059,2027],{"class":45},[35,2061,350],{"class":349},[35,2063,1875],{"class":177},[35,2065,362],{"class":349},[35,2067,1889],{"class":45},[35,2069,248],{"class":177},[35,2071,343],{"class":173},[35,2073,1870],{"class":45},[35,2075,350],{"class":349},[35,2077,1875],{"class":177},[35,2079,362],{"class":349},[35,2081,2027],{"class":45},[35,2083,350],{"class":349},[35,2085,1875],{"class":177},[35,2087,362],{"class":349},[35,2089,1889],{"class":45},[35,2091,1575],{"class":177},[35,2093,2094,2096,2098,2100,2102,2105,2107,2109,2111],{"class":37,"line":419},[35,2095,549],{"class":173},[35,2097,523],{"class":177},[35,2099,331],{"class":173},[35,2101,528],{"class":251},[35,2103,2104],{"class":177},"(table, ",[35,2106,535],{"class":534},[35,2108,200],{"class":173},[35,2110,1284],{"class":251},[35,2112,543],{"class":177},[35,2114,2115,2118,2121,2123,2125],{"class":37,"line":430},[35,2116,2117],{"class":173},"        for",[35,2119,2120],{"class":177}," k, v ",[35,2122,331],{"class":173},[35,2124,528],{"class":251},[35,2126,2127],{"class":177},"(row):\n",[35,2129,2130,2133,2135],{"class":37,"line":453},[35,2131,2132],{"class":177},"            ws.cell(r, c ",[35,2134,1781],{"class":173},[35,2136,2137],{"class":177}," k, v)\n",[35,2139,2140,2143,2145],{"class":37,"line":473},[35,2141,2142],{"class":177},"    g ",[35,2144,200],{"class":173},[35,2146,696],{"class":177},[35,2148,2149,2152,2154,2157,2159,2162,2164,2166],{"class":37,"line":493},[35,2150,2151],{"class":177},"    g.firstSliceAng, g.holeSize, g.legend, g.title ",[35,2153,200],{"class":173},[35,2155,2156],{"class":251}," 270",[35,2158,248],{"class":177},[35,2160,2161],{"class":251},"45",[35,2163,248],{"class":177},[35,2165,996],{"class":251},[35,2167,2168],{"class":177},", title\n",[35,2170,2171,2174,2176,2178,2181,2183,2186,2188,2190,2192,2194,2196,2198,2200,2202,2204,2206,2208,2210],{"class":37,"line":512},[35,2172,2173],{"class":177},"    g.add_data(Reference(ws, ",[35,2175,724],{"class":534},[35,2177,200],{"class":173},[35,2179,2180],{"class":177},"c ",[35,2182,1781],{"class":173},[35,2184,2185],{"class":251}," 2",[35,2187,248],{"class":177},[35,2189,734],{"class":534},[35,2191,200],{"class":173},[35,2193,540],{"class":251},[35,2195,248],{"class":177},[35,2197,743],{"class":534},[35,2199,200],{"class":173},[35,2201,86],{"class":251},[35,2203,255],{"class":177},[35,2205,753],{"class":534},[35,2207,200],{"class":173},[35,2209,758],{"class":251},[35,2211,1133],{"class":177},[35,2213,2214,2216,2218,2220,2222,2224,2226,2228,2230,2232,2234,2236,2238,2240,2242,2244,2246,2248,2250],{"class":37,"line":518},[35,2215,2173],{"class":177},[35,2217,724],{"class":534},[35,2219,200],{"class":173},[35,2221,2180],{"class":177},[35,2223,1781],{"class":173},[35,2225,1466],{"class":251},[35,2227,248],{"class":177},[35,2229,734],{"class":534},[35,2231,200],{"class":173},[35,2233,540],{"class":251},[35,2235,248],{"class":177},[35,2237,743],{"class":534},[35,2239,200],{"class":173},[35,2241,86],{"class":251},[35,2243,255],{"class":177},[35,2245,753],{"class":534},[35,2247,200],{"class":173},[35,2249,758],{"class":251},[35,2251,1133],{"class":177},[35,2253,2254,2257,2259,2262,2264,2266,2268,2270,2272,2274,2276],{"class":37,"line":546},[35,2255,2256],{"class":177},"    paint(g.series[",[35,2258,76],{"class":251},[35,2260,2261],{"class":177},"], [",[35,2263,986],{"class":45},[35,2265,248],{"class":177},[35,2267,991],{"class":45},[35,2269,248],{"class":177},[35,2271,996],{"class":251},[35,2273,248],{"class":177},[35,2275,996],{"class":251},[35,2277,1003],{"class":177},[35,2279,2280,2282,2284,2286,2288,2291,2293],{"class":37,"line":570},[35,2281,2256],{"class":177},[35,2283,356],{"class":251},[35,2285,2261],{"class":177},[35,2287,1488],{"class":173},[35,2289,2290],{"class":177},"bands, ",[35,2292,996],{"class":251},[35,2294,1003],{"class":177},[35,2296,2297,2300,2302,2305,2307],{"class":37,"line":576},[35,2298,2299],{"class":177},"    g.width, g.height ",[35,2301,200],{"class":173},[35,2303,2304],{"class":251}," 8",[35,2306,248],{"class":177},[35,2308,2309],{"class":251},"5\n",[35,2311,2312],{"class":37,"line":964},[35,2313,2314],{"class":177},"    ws.add_chart(g, anchor)\n",[35,2316,2317],{"class":37,"line":969},[35,2318,191],{"emptyLinePlaceholder":190},[35,2320,2321,2324,2326,2329,2332],{"class":37,"line":980},[35,2322,2323],{"class":177},"dash ",[35,2325,200],{"class":173},[35,2327,2328],{"class":177}," wb.create_sheet(",[35,2330,2331],{"class":45},"\"Dashboard\"",[35,2333,1133],{"class":177},[35,2335,2336,2339,2341,2343,2346,2348,2351,2353,2355,2357,2359,2361,2364,2366,2369,2371,2374],{"class":37,"line":1006},[35,2337,2338],{"class":177},"add_gauge(dash, ",[35,2340,356],{"class":251},[35,2342,248],{"class":177},[35,2344,2345],{"class":45},"\"On-time delivery %\"",[35,2347,248],{"class":177},[35,2349,2350],{"class":251},"91",[35,2352,248],{"class":177},[35,2354,76],{"class":251},[35,2356,248],{"class":177},[35,2358,282],{"class":251},[35,2360,248],{"class":177},[35,2362,2363],{"class":251},"85",[35,2365,248],{"class":177},[35,2367,2368],{"class":251},"95",[35,2370,248],{"class":177},[35,2372,2373],{"class":45},"\"A15\"",[35,2375,1133],{"class":177},[35,2377,2378,2380,2383,2385,2388,2390,2393,2395,2397,2399,2401,2403,2406,2408,2410,2412,2415,2417,2420,2422,2424,2426,2428,2430,2432,2434],{"class":37,"line":1031},[35,2379,2338],{"class":177},[35,2381,2382],{"class":251},"5",[35,2384,248],{"class":177},[35,2386,2387],{"class":45},"\"Budget used %\"",[35,2389,248],{"class":177},[35,2391,2392],{"class":251},"64",[35,2394,248],{"class":177},[35,2396,76],{"class":251},[35,2398,248],{"class":177},[35,2400,282],{"class":251},[35,2402,248],{"class":177},[35,2404,2405],{"class":251},"80",[35,2407,248],{"class":177},[35,2409,2368],{"class":251},[35,2411,248],{"class":177},[35,2413,2414],{"class":45},"\"F15\"",[35,2416,248],{"class":177},[35,2418,2419],{"class":534},"bands",[35,2421,200],{"class":173},[35,2423,595],{"class":177},[35,2425,1022],{"class":45},[35,2427,248],{"class":177},[35,2429,1017],{"class":45},[35,2431,248],{"class":177},[35,2433,1012],{"class":45},[35,2435,835],{"class":177},[35,2437,2439,2441,2443],{"class":37,"line":2438},27,[35,2440,1138],{"class":177},[35,2442,1141],{"class":45},[35,2444,1133],{"class":177},[35,2446,2448,2450,2452,2454,2457,2460],{"class":37,"line":2447},28,[35,2449,579],{"class":251},[35,2451,595],{"class":177},[35,2453,1039],{"class":251},[35,2455,2456],{"class":177},"(dash._charts), ",[35,2458,2459],{"class":45},"\"gauges on the dashboard\"",[35,2461,1133],{"class":177},[10,2463,2464,2465,2468,2469,2471,2472,2476],{},"Each gauge owns a block of columns for its inputs and slices, so they cannot interfere. For a budget, where ",[631,2466,2467],{},"higher"," is worse, the ",[32,2470,2419],{}," argument reverses the colours — green first, red last — while the maths stays the same: 64% used sits in the green band, with amber from 80% and red from 95%. ",[14,2473,2475],{"href":2474},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-a-kpi-summary-block-to-an-excel-dashboard\u002F","Add a KPI Summary Block to an Excel Dashboard"," shows how to lay out a row of KPIs around charts like these.",[54,2478,63,2484,63,2487,63,2490,63,2494,63,2500,63,2507,63,2513,63,2517,63,2522,63,2528,63,2532,63,2537,63,2541,63,2546,63,2551,63,2558,63,2563,63,2567,63,2571,63,2578,63,2581,63,2586,63,2589],{"viewBox":2479,"role":57,"ariaLabelledBy":2480,"xmlns":61,"style":2483},"4 0 752 207",[2481,2482],"gg-when-t","gg-when-d","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[65,2485,2486],{"id":2481},"When a gauge helps and when it does not",[69,2488,2489],{"id":2482},"Two panels. A gauge helps for a single KPI with well-known thresholds shown on a dashboard. It does not help when comparing several values or showing change over time, where a bar or line chart is clearer and takes less space.",[73,2491],{"x":602,"y":76,"width":2492,"height":2493,"fill":79},"752","207",[73,2495],{"x":2496,"y":83,"width":2497,"height":2498,"rx":2499,"fill":116,"stroke":117,"style":89},"20.0","351.0","175.0","14",[91,2501,2503],{"transform":2502},"translate(182.5,29.0) scale(1.083)",[95,2504],{"d":2505,"fill":98,"stroke":124,"style":2506},"M5 12.5l4.5 4.5L19 7","stroke-width:1.66px;stroke-linecap:round;stroke-linejoin:round",[102,2508,2512],{"x":2509,"y":2510,"style":2511},"195.5","78.0","font-size:14px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","Gauge works",[37,2514],{"x1":1202,"y1":2515,"x2":2516,"y2":2515,"stroke":117,"style":1210},"91.0","355.0",[102,2518,2521],{"x":82,"y":2519,"style":2520},"111.0","font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:start","one KPI, one moment",[91,2523,2525],{"transform":2524},"translate(38.5,99.5) scale(0.625)",[95,2526],{"d":2505,"fill":98,"stroke":117,"style":2527},"stroke-width:2.88px;stroke-linecap:round;stroke-linejoin:round",[102,2529,2531],{"x":82,"y":2530,"style":2520},"137.0","thresholds everyone knows",[91,2533,2535],{"transform":2534},"translate(38.5,125.5) scale(0.625)",[95,2536],{"d":2505,"fill":98,"stroke":117,"style":2527},[102,2538,2540],{"x":82,"y":2539,"style":2520},"163.0","dashboard headline",[91,2542,2544],{"transform":2543},"translate(38.5,151.5) scale(0.625)",[95,2545],{"d":2505,"fill":98,"stroke":117,"style":2527},[73,2547],{"x":2548,"y":83,"width":2497,"height":2498,"rx":2499,"fill":2549,"stroke":2550,"style":89},"389.0","#fdefd8","var(--gold,#b4740a)",[91,2552,2554],{"transform":2553},"translate(551.5,29.0) scale(1.083)",[95,2555],{"d":2556,"fill":98,"stroke":2557,"style":2506},"M12 3.5l9.5 17h-19z M12 10v5 M12 17.8v.4","var(--gold-ink,#7a4e06)",[102,2559,2562],{"x":2560,"y":2510,"style":2561},"564.5","font-size:14px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","Use something else",[37,2564],{"x1":2565,"y1":2515,"x2":2566,"y2":2515,"stroke":2550,"style":1210},"405.0","724.0",[102,2568,2570],{"x":2569,"y":2519,"style":2520},"429.0","comparing many values",[91,2572,2574],{"transform":2573},"translate(407.5,99.5) scale(0.625)",[95,2575],{"d":2576,"fill":98,"stroke":2577,"style":2527},"M6 6l12 12 M18 6L6 18","var(--accent,#f43f8f)",[102,2579,2580],{"x":2569,"y":2530,"style":2520},"trends over time",[91,2582,2584],{"transform":2583},"translate(407.5,125.5) scale(0.625)",[95,2585],{"d":2576,"fill":98,"stroke":2577,"style":2527},[102,2587,2588],{"x":2569,"y":2539,"style":2520},"precise reading of the number",[91,2590,2592],{"transform":2591},"translate(407.5,151.5) scale(0.625)",[95,2593],{"d":2576,"fill":98,"stroke":2577,"style":2527},[20,2595,2597],{"id":2596},"common-pitfalls","Common pitfalls",[2599,2600,2601,2616,2622,2633,2639],"ul",{},[2602,2603,2604,2608,2609,642,2612,2615],"li",{},[2605,2606,2607],"strong",{},"Visible hidden slices."," Set both ",[32,2610,2611],{},"noFill",[32,2613,2614],{},"line.noFill",", or an outline shows the bottom half.",[2602,2617,2618,2621],{},[2605,2619,2620],{},"Rings in the wrong order."," The first series is the inner ring; add the value before the bands if the bands should be outside.",[2602,2623,2624,2627,2628,642,2630,2632],{},[2605,2625,2626],{},"Out-of-range values."," Clamp with ",[32,2629,641],{},[32,2631,645],{},", or a value above the maximum distorts the half circle.",[2602,2634,2635,2638],{},[2605,2636,2637],{},"Numbers only in the dial."," Put the value in a label or title; the arc alone is hard to read precisely.",[2602,2640,2641,2644],{},[2605,2642,2643],{},"Gauges everywhere."," They take a lot of space for one number; use them for headline KPIs only.",[20,2646,2648],{"id":2647},"conclusion","Conclusion",[10,2650,2651,2652,2655,2656,2658],{},"Build the gauge as a two-ring ",[32,2653,2654],{},"DoughnutChart"," over a helper table: bands for the thresholds on the outer ring, the value arc and remainder on the inner ring, and on each ring a hidden slice equal to the full range, with ",[32,2657,150],{}," so the hidden half is at the bottom. Drive the table with formulas from the KPI and threshold cells so the dial moves when they change, show the number in a label, check the rendering and the ring sums, and wrap it all in a function for a dashboard of several gauges.",[20,2660,2662],{"id":2661},"frequently-asked-questions","Frequently asked questions",[10,2664,2665,2668],{},[2605,2666,2667],{},"Does Excel have a gauge chart?","\nNo built-in type. The usual construction is a doughnut chart with a hidden half: slices for the bands and the value, plus a slice equal to the whole range that is made invisible and placed at the bottom with a first slice angle of 270 degrees.",[10,2670,2671,2674],{},[2605,2672,2673],{},"How do I make half of a doughnut chart invisible with openpyxl?","\nGive the ring a final slice equal to the sum of the visible ones and set that data point's graphicalProperties.noFill and line.noFill to True. Set chart.firstSliceAng = 270 so the visible half is at the top.",[10,2676,2677,2680],{},[2605,2678,2679],{},"How do I make the gauge update when the value changes?","\nPoint the chart at a helper table of formulas that compute the slice sizes from the KPI and threshold cells. Changing the KPI cell recalculates the table and the chart redraws.",[10,2682,2683,2686],{},[2605,2684,2685],{},"Can I add a needle to the gauge?","\nA needle needs a pie chart overlaid on the doughnut, which openpyxl cannot reliably combine. The value arc used here shows the same information and is simpler to build and maintain.",[20,2688,2690],{"id":2689},"related","Related",[2599,2692,2693,2699,2706,2713],{},[2602,2694,2695,2696,2698],{},"Up one level: ",[14,2697,17],{"href":16}," — every chart type openpyxl supports.",[2602,2700,2701,2705],{},[14,2702,2704],{"href":2703},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-doughnut-chart-with-openpyxl\u002F","Create a Doughnut Chart with openpyxl"," — the chart type underneath.",[2602,2707,2708,2712],{},[14,2709,2711],{"href":2710},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fbuild-a-dashboard-sheet-with-charts-from-multiple-tabs\u002F","Build a Dashboard Sheet with Charts from Multiple Tabs"," — placing gauges on a dashboard.",[2602,2714,2715,2719],{},[14,2716,2718],{"href":2717},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Flink-dashboard-cells-to-data-sheets-with-formulas\u002F","Link Dashboard Cells to Data Sheets with Formulas"," — feeding the KPI cell from data.",[2721,2722,2723],"style",{},"html pre.shiki code .sMTad, html code.shiki .sMTad{--shiki-default:#6F42C1;--shiki-dark:#FFB757}html pre.shiki code .srMev, html code.shiki .srMev{--shiki-default:#032F62;--shiki-dark:#ADDCFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}html pre.shiki code .skGVy, html code.shiki .skGVy{--shiki-default:#24292E;--shiki-dark:#F0F3F6}html pre.shiki code .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}html pre.shiki code .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}html pre.shiki code .s-wDw, html code.shiki .s-wDw{--shiki-default:#6A737D;--shiki-dark:#BDC4CC}html pre.shiki code .s_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}",{"title":30,"searchDepth":187,"depth":187,"links":2725},[2726,2727,2728,2729,2730,2731,2732,2733,2734,2735],{"id":22,"depth":187,"text":23},{"id":157,"depth":187,"text":158},{"id":649,"depth":187,"text":650},{"id":1064,"depth":187,"text":1065},{"id":1371,"depth":187,"text":1372},{"id":1695,"depth":187,"text":1696},{"id":2596,"depth":187,"text":2597},{"id":2647,"depth":187,"text":2648},{"id":2661,"depth":187,"text":2662},{"id":2689,"depth":187,"text":2690},"2026-09-29","Build a speedometer-style KPI gauge from Python with openpyxl: a half-circle doughnut made by hiding half of each ring, coloured red, amber and green bands from your thresholds, a value arc that moves when the KPI cell changes, a helper table of formulas behind it, several gauges on one dashboard, and a render check.","md",[2740,2742,2744,2746],{"q":2667,"a":2741},"No built-in type. The usual construction is a doughnut chart with a hidden half: slices for the bands and the value, plus a slice equal to the whole range that is made invisible and placed at the bottom with a first slice angle of 270 degrees.",{"q":2673,"a":2743},"Give the ring a final slice equal to the sum of the visible ones and set that data point's graphicalProperties.noFill and line.noFill to True. Set chart.firstSliceAng = 270 so the visible half is at the top.",{"q":2679,"a":2745},"Point the chart at a helper table of formulas that compute the slice sizes from the KPI and threshold cells. Changing the KPI cell recalculates the table and the chart redraws.",{"q":2685,"a":2747},"A needle needs a pie chart overlaid on the doughnut, which openpyxl cannot reliably combine. The value arc used here shows the same information and is simpler to build and maintain.","create a gauge chart in excel with python",null,{"breadcrumb":2751},[2752,2755,2758],{"name":2753,"item":2754},"Home","\u002F",{"name":2756,"item":2757},"Formatting and Charting Excel Reports with Python","\u002Fformatting-and-charting-excel-reports-with-python\u002F",{"name":17,"item":16},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-gauge-chart-in-excel-with-python",{"title":2761,"description":2762},"Excel Gauge (Speedometer) Chart with Python and openpyxl","Create a KPI gauge chart in Excel with openpyxl: a two-ring DoughnutChart with firstSliceAng=270 and a hidden half, red\u002Famber\u002Fgreen threshold bands, a value arc driven by formulas so it updates with the KPI cell, per-slice colours and multiple gauges on a dashboard.","create-a-gauge-chart-in-excel-with-python","formatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-gauge-chart-in-excel-with-python\u002Findex",[2766,2767],"charts-and-images","openpyxl","how-to","f5qw5I3BAelkohjFQw_sxaHkTbpLCuEt2A7lqrabOnk",[2771,2775],{"title":2772,"path":2773,"stem":2774,"children":-1},"Create a Gantt Chart in Excel with Python","\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-gantt-chart-in-excel-with-python","formatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-gantt-chart-in-excel-with-python\u002Findex",{"title":2776,"path":2777,"stem":2778,"children":-1},"Create a Histogram in Excel with Python","\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-histogram-in-excel-with-python","formatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-histogram-in-excel-with-python\u002Findex",[2780,2782],{"path":2781,"title":17},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl",{"path":2783,"title":2756},"\u002Fformatting-and-charting-excel-reports-with-python",[],[2786,2788,2791,2794,2797,2800],{"path":2787,"title":2711,"kind":2768},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fbuild-a-dashboard-sheet-with-charts-from-multiple-tabs",{"path":2789,"title":2790,"kind":2768},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fbuild-a-rolling-12-month-chart-on-an-excel-dashboard","Build a Rolling 12-Month Chart on an Excel Dashboard",{"path":2792,"title":2793,"kind":2768},"\u002Fautomating-reporting-workflows\u002Fgenerating-excel-reports-from-templates\u002Fkeep-charts-and-images-when-filling-an-excel-template","Keep Charts and Images When Filling an Excel Template",{"path":2795,"title":2796,"kind":2768},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Fadd-a-chart-to-an-excel-file-with-xlsxwriter","Add a Chart to an Excel File with xlsxwriter",{"path":2798,"title":2799,"kind":2768},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Fadd-sparklines-to-an-excel-report-with-xlsxwriter","Add Sparklines to an Excel Report with xlsxwriter",{"path":2801,"title":2802,"kind":2768},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Fbuild-a-waterfall-chart-in-excel-with-python","Build a Waterfall Chart in Excel with Python",1790972110981]