Context : I want to display a donut chart using one SVG composed of two circles :
- Both circles are dynamically filled with a css variable (as a percent).
Everythings works fine on PC and Android (chrome).
When viewing with an iPhone, the green circle is fully filled hiding the grey circle.
Below is the result as seen with IOS phone (tried Safari and Chrome) :
Here is a snippet, took 45% for green and 75% for grey
Code :
:root {
--val: 0;
}
svg {
transform: rotate(135deg);
}
.percent {
stroke-dasharray: 100;
stroke-dashoffset: calc(100 - var(--val));
}
.white {
transform: rotate(135deg)
}
.forty-five{
--val: 45;
}
.complete {
--val: 75;
}
<div >
<svg width="250" height="250" viewBox="0 0 140 140">
<circle cx="70" cy="70" r="52" fill="none" stroke="#e6e6e6" strokeWidth="18" pathLength="100" />
<circle cx="70" cy="70" r="52" fill="none" stroke="#333" strokeWidth="18" pathLength="100" />
<circle cx="70" cy="70" r="52" fill="none" stroke="#6AA617" strokeWidth="18" pathLength="100" />
</svg>
</div>
Any suggestion or any other way to obtain this result ?
EDIT : I just found out that there is the same problem when using Firefox on pC
CodePudding user response:
As @A Haworth already pointed out:
css calc
support for svg properties is still rather spotty (might work in Chrome but not in Firefox – might also depend on the actual svg element and certain properties.
Probably fixed and negligible in the near future ... unless ie returns).
But you don't really need it anyway.
Since your horseshoe gauge should render only 270° of a 360° circle, you could instead tweak the pathLength
property:
The ideal pathLength
would be 133.333
360/270*100
(i.e. the 270° part of the circle will result in a computed circumference of 100 svg units)
Now you can use css-variable to display percentage based values:
:root {
--val: 100;
--dashGap: 133.333;
--offset: 0;
}
svg {
transform: rotate(135deg);
}
.percent {
stroke-dashoffset: var(--offset);
stroke-dasharray: var(--val) var(--dashGap)
}
<div >
<svg width="250" height="250" viewBox="0 0 140 140">
<defs>
<circle id="circle" cx="70" cy="70" r="52" fill="none" pathLength="133.333" stroke-width="18" />
</defs>
<!-- bg circle -->
<use href="#circle" stroke="#e6e6e6" />
<!-- percentage circles -->
<use href="#circle" stroke="green" style="--val:50"/>
<use href="#circle" stroke="pink" style="--val:25; --offset:-50" />
</svg>
</div>
If you need to render values progressively like 50% 25% (so a total of 75%) you can use a stroke-dahoffset
variable.
Each new segment needs to have a negative offset according the previous segments's percentage.