|
For some reason I am unable to find the .dll in order to reference it...can anybody help? Where do I download it from?
|
|
|
|
|
I have a requirement to make this dial as hyperlink , so if user clicks on this dial needs to navigate to other page.Plz help me.
|
|
|
|
|
I think the live demo link needs updating? Possibly linking to the SL3 runtime? Controls look nice, will give them a run.
Best wishes
Jerry
|
|
|
|
|
Binding to CurrentValue (or just setting any value to it) does not work in my application. Upon debugging, I found out that the needle does not move because the pointer object is null when the code reaches AnimatePointer:
void AnimatePointer(double oldcurrentvalueAngle, double newcurrentvalueAngle)
{
if (pointer != null)
Also, I found out that OnApplyTemplate (where the pointer object is created) only fires after the AnimatePointer method is called (which explains why pointer was null?).
Other than that, the control looks very nice!
maybe one other thing to improve is to use default values for the dependencyproperties, so the control does not crash if you do not provide them and you do not have to specify so much in xaml.
|
|
|
|
|
Hi, fisrt very good work, very nice result!
i would like to know how to rezie a gauge?
|
|
|
|
|
I found that you need to adjust the radius and related values in the Gauge.xaml
Thanks
|
|
|
|
|
can you be more specific please? I have tried to modified those but the result is... weird...
what are the properties I have to change and should I change them in proportion or in delta difference? meaning if I reduce the radius from 150 to 100 do I reduce the other with 50 or with 30%?
|
|
|
|
|
Hello, contratulations for this sample.
With below scenario the RangeIndicator Bellow Optimal and Above Optimal lines are drawn wrong.
<gauge:CircularGaugeControl x:Name="myGauge2" Grid.Column="1" Grid.Row="0"<br />
Radius="150" <br />
ScaleRadius="100" <br />
ScaleStartAngle="140" <br />
ScaleSweepAngle="270"<br />
PointerLength="90" <br />
PointerCapRadius="35" <br />
<big>MinValue="30"</big> <br />
<big>MaxValue="35"</big> <br />
MajorDivisionsCount="10" <br />
MinorDivisionsCount="5" <br />
<big>OptimalRangeEndValue="32"</big><br />
<big>OptimalRangeStartValue="31"</big><br />
CurrentValue="{Binding Score}"<br />
ImageSource="windowslogo.png"<br />
ImageSize="40,50"<br />
RangeIndicatorThickness="9"<br />
RangeIndicatorRadius="80"<br />
RangeIndicatorLightRadius="10"<br />
RangeIndicatorLightOffset="80"<br />
ScaleLabelRadius="115"<br />
ScaleLabelSize="40,20"<br />
ScaleLabelFontSize="10"<br />
ScaleLabelForeground="White"<br />
MajorTickSize="10,3"<br />
MinorTickSize="3,1"<br />
MajorTickColor="White"<br />
MinorTickColor="LightGray"<br />
ImageOffset="-50"<br />
GaugeBackgroundColor="CornflowerBlue"<br />
PointerThickness ="5"<br />
DialTextOffset="40"<br />
DialText="Aqua Blue"<br />
DialTextColor="DarkBlue"<br />
<br />
/><br />
Here is the result image: http://dl.dropbox.com/u/3763901/gaugeError.PNG[^]
Any way how to solve this?
|
|
|
|
|
Did you have any luck resolving the drawing problem?
|
|
|
|
|
No
|
|
|
|
|
hi,
This is a quick solution that has been tested with the test cases listed below. The approach is to make calculations as if the Min value is always zero. Add/Modify the following code segment on this function:
CircularGauge.CircularGaugeControl.DrawRangeIndicator
Double tmpMaxValue = (MaxValue - MinValue);
Double tmpStartValue = Math.Abs(OptimalRangeStartValue - MinValue);
Double tmpEndValue = Math.Abs(OptimalRangeEndValue - MinValue);
Double realworldunit = (ScaleSweepAngle / tmpMaxValue);
Double optimalStartAngle = ((double)(tmpStartValue * realworldunit));
Double optimalEndAngle = ((double)(tmpEndValue * realworldunit));
Test Cases:<br />
min,max,optimalStart, OptimalEnd<br />
-10,10,2,4<br />
-10,10,-5,-2<br />
32,41,33,35<br />
22000,38000,31600,34800
I hope this help.
|
|
|
|
|
Thank you for your help, but I cant put it working, maybe I missed something...
I get the same result gauge.
My result code is:
private void DrawRangeIndicator()
{
Double tmpMaxValue = (MaxValue - MinValue);
Double tmpStartValue = Math.Abs(OptimalRangeStartValue - MinValue);
Double tmpEndValue = Math.Abs(OptimalRangeEndValue - MinValue);
Double realworldunit = (ScaleSweepAngle / tmpMaxValue);
Double optimalStartAngle = ((double)(tmpStartValue * realworldunit));
Double optimalEndAngle = ((double)(tmpEndValue * realworldunit));
double db;
if (OptimalRangeStartValue < 0)
{
db = MinValue + Math.Abs(OptimalRangeStartValue);
optimalStartAngle = ((double)(Math.Abs(db * realworldunit)));
}
else
{
db = Math.Abs(MinValue) + OptimalRangeStartValue;
optimalStartAngle = ((double)(db * realworldunit));
}
if (OptimalRangeEndValue < 0)
{
db = MinValue + Math.Abs(OptimalRangeEndValue);
optimalEndAngle = ((double)(Math.Abs(db * realworldunit)));
}
else
{
db = Math.Abs(MinValue) + OptimalRangeEndValue;
optimalEndAngle = ((double)(db * realworldunit));
}
Double optimalStartAngleFromStart = (ScaleStartAngle + optimalStartAngle);
Double optimalEndAngleFromStart = (ScaleStartAngle + optimalEndAngle);
arcradius1 = (RangeIndicatorRadius + RangeIndicatorThickness);
arcradius2 = RangeIndicatorRadius;
double endAngle = ScaleStartAngle + ScaleSweepAngle;
Point A = GetCircumferencePoint(ScaleStartAngle, arcradius1);
Point B = GetCircumferencePoint(ScaleStartAngle, arcradius2);
Point C = GetCircumferencePoint(optimalStartAngleFromStart, arcradius2);
Point D = GetCircumferencePoint(optimalStartAngleFromStart, arcradius1);
bool isReflexAngle = Math.Abs(optimalStartAngleFromStart - ScaleStartAngle) > 180.0;
DrawSegment(A, B, C, D, isReflexAngle, BelowOptimalRangeColor);
Point A1 = GetCircumferencePoint(optimalStartAngleFromStart, arcradius1);
Point B1 = GetCircumferencePoint(optimalStartAngleFromStart, arcradius2);
Point C1 = GetCircumferencePoint(optimalEndAngleFromStart, arcradius2);
Point D1 = GetCircumferencePoint(optimalEndAngleFromStart, arcradius1);
bool isReflexAngle1 = Math.Abs(optimalEndAngleFromStart - optimalStartAngleFromStart) > 180.0;
DrawSegment(A1, B1, C1, D1, isReflexAngle1, OptimalRangeColor);
Point A2 = GetCircumferencePoint(optimalEndAngleFromStart, arcradius1);
Point B2 = GetCircumferencePoint(optimalEndAngleFromStart, arcradius2);
Point C2 = GetCircumferencePoint(endAngle, arcradius2);
Point D2 = GetCircumferencePoint(endAngle, arcradius1);
bool isReflexAngle2 = Math.Abs(endAngle - optimalEndAngleFromStart) > 180.0;
DrawSegment(A2, B2, C2, D2, isReflexAngle2, AboveOptimalRangeColor);
}
maybe I missed something? where is the Min reset to zero?
|
|
|
|
|
The DrawRangeIndicator() function, that works for me is included below. I commented out the original code.
private void DrawRangeIndicator()
{
Double realworldunit = (ScaleSweepAngle / (MaxValue - MinValue));
Double optimalStartAngle;
Double optimalEndAngle;
optimalStartAngle = realworldunit * (OptimalRangeStartValue - MinValue);
optimalEndAngle = realworldunit * (OptimalRangeEndValue - MinValue);
Double optimalStartAngleFromStart = (ScaleStartAngle + optimalStartAngle);
Double optimalEndAngleFromStart = (ScaleStartAngle + optimalEndAngle);
arcradius1 = (RangeIndicatorRadius + RangeIndicatorThickness);
arcradius2 = RangeIndicatorRadius;
double endAngle = ScaleStartAngle + ScaleSweepAngle;
Point A = GetCircumferencePoint(ScaleStartAngle, arcradius1);
Point B = GetCircumferencePoint(ScaleStartAngle, arcradius2);
Point C = GetCircumferencePoint(optimalStartAngleFromStart, arcradius2);
Point D = GetCircumferencePoint(optimalStartAngleFromStart, arcradius1);
bool isReflexAngle = Math.Abs(optimalStartAngleFromStart - ScaleStartAngle) > 180.0;
DrawSegment(A, B, C, D, isReflexAngle, BelowOptimalRangeColor);
Point A1 = GetCircumferencePoint(optimalStartAngleFromStart, arcradius1);
Point B1 = GetCircumferencePoint(optimalStartAngleFromStart, arcradius2);
Point C1 = GetCircumferencePoint(optimalEndAngleFromStart, arcradius2);
Point D1 = GetCircumferencePoint(optimalEndAngleFromStart, arcradius1);
bool isReflexAngle1 = Math.Abs(optimalEndAngleFromStart - optimalStartAngleFromStart) > 180.0;
DrawSegment(A1, B1, C1, D1, isReflexAngle1, OptimalRangeColor);
Point A2 = GetCircumferencePoint(optimalEndAngleFromStart, arcradius1);
Point B2 = GetCircumferencePoint(optimalEndAngleFromStart, arcradius2);
Point C2 = GetCircumferencePoint(endAngle, arcradius2);
Point D2 = GetCircumferencePoint(endAngle, arcradius1);
bool isReflexAngle2 = Math.Abs(endAngle - optimalEndAngleFromStart) > 180.0;
DrawSegment(A2, B2, C2, D2, isReflexAngle2, AboveOptimalRangeColor);
}
|
|
|
|
|
I want to modify the Min, Max and optimal range values at runtime using bindings; aim is to allow user to modify these values. Is it possible to do this? Has anyone tried doing this?
Any ideas, suggestions, comments...
|
|
|
|
|
I will also have to do modify them. I'll post my experiences here after I have a look at this. I'm new to WPF but my idea is that they can be modified but the gauge isn't redrawn, because there are no change handlers for these dependency properties.
|
|
|
|
|
Binding at build time in Silverlight 4 works (all code is from the downloadable sample), where I'm binding to a Parameter class that contains the referenced fields:
<gauge:CircularGaugeControl x:Name="myGauge1" Grid.Column="0" Grid.Row="0" Margin="5"
Radius="75"
: :
PointerCapRadius="10"
MinValue="{Binding Minimum}"
MaxValue="{Binding Maximum}"
MajorDivisionsCount="10"
: :
PointerThickness ="10"
OptimalRangeStartValue="{Binding OptimalRangeStart}"
OptimalRangeEndValue="{Binding OptimalRangeEnd}"
DialTextOffset="20"
DialText="{Binding Units}"
DialTextColor="Black"
></gauge:CircularGaugeControl>
There does seem to be a display problem in Silverlight 4 with this binding when the minimum value is not zero: both the range bands and pointer movement start getting strange. (You can see the new current value for each gauge in the demo by adding the line
DialText = newValue.ToString();
in OnCurrentValueChanged just after newValue is set.)
I'd like to suggest some small changes to CircularGaugeControl.cs to see what people think of them. They work nicely with the demo code as well as with my project, where I'm using ranges such as 1906..1980, -2..2, 65..300, etc.
There's a shared converter routine that the changes use. It involves redundant calculations, but it makes the changes clearer.
private double ValueToAngle(double value)
{
Double realworldunit = (ScaleSweepAngle / (MaxValue - MinValue));
double equivalentAngle = ScaleStartAngle + (value - MinValue) * realworldunit;
return equivalentAngle;
}
In OnCurrentValueChanged(), change the if (pointer != null) block to:
if (pointer != null)
{
AnimatePointer(ValueToAngle(oldValue), ValueToAngle(newValue));
}
Change the start of DrawRangeIndicator() to
private void DrawRangeIndicator()
{
Double optimalStartAngleFromStart = ValueToAngle(OptimalRangeStartValue);
Double optimalEndAngleFromStart = ValueToAngle(OptimalRangeEndValue);
arcradius1 = (RangeIndicatorRadius + RangeIndicatorThickness);
: :
On the purely stylistic side, I also changed OnApplyTemplate() so that the gauges start their display with their current value.
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
: :
Canvas.SetZIndex(pointerCap, 100001);
MovePointer(ScaleStartAngle);
AnimatePointer(ScaleStartAngle, ValueToAngle(CurrentValue));
}
modified on Sunday, August 15, 2010 5:17 PM
|
|
|
|
|
The solution to the strange RangeIndicator behaviour may be in my reply above to the post "problem with RangeIndicator".
For the binding part: if I remember well, I have solved the binding issue with WPF in .NET 3.5, but I have switched to another gauge, so I'll have to make a diff to see what changes I have made to the original code. When I have some time to do this, I'll share my enhacements.
|
|
|
|
|
Hi,
Has anyone else found this to consume huge amounts of CPU time ?? If so is there a way to fix it ?
I have this deployed on a test site and when the gauge is displayed, my CPU cycles goes to 100%. If I remove this control - I'm back down at a couple of % again.
Regards
Graham
|
|
|
|
|
This is really great, exactly what i was looking for.
I noticed a very small bug for the DialTextFontSize:
DependencyProperty.Register("DialTextFontSize", typeof(int)...
Should be a double:
DependencyProperty.Register("DialTextFontSize", typeof(double)...
(Also change the public property int DialTextFontSize to a double)
Thanks for this great control.
Greetings,
Patrick
|
|
|
|
|
Very good!! Thanks a lot to share with us!!
Gustavo Malheiros.
|
|
|
|
|
Hi,
The control is really excellent, but I need to apply different themes during run time. Is it possible?
Thanks in advance,
Matías
|
|
|
|
|
Yes. Remove the template, assign another one. Have onApplyTemplate() invoked. Worked for me. Actually, reassign the original template to have the whole control redrawn when I change the scale at run time (using a range slider).
|
|
|
|
|
Hi, thanks for this very cool control, I'm going to give it a try for my dashboard project.
cheers
sushibite
|
|
|
|
|
Hi EvelynT,
I found your control very use full but I would like add it from code behind but unable to do so.
I am getting emtpy gage with no MinValue or MaxValue and needle is always set to minValue.
here is my code.
this.myStackPanel.Children.Add(new CircularGaugeControl()
{
Radius = Convert.ToDouble(150),
ScaleRadius = Convert.ToDouble(110),
ScaleStartAngle = Convert.ToDouble(120),
ScaleSweepAngle = Convert.ToDouble(300),
PointerLength = Convert.ToDouble(85),
PointerCapRadius = Convert.ToDouble(35),
MinValue = Convert.ToDouble(0),
MaxValue = Convert.ToDouble(1000),
MajorDivisionsCount = Convert.ToDouble(10),
MinorDivisionsCount = Convert.ToDouble(5),
CurrentValue = Convert.ToDouble(50),
RangeIndicatorThickness = Convert.ToDouble(8),
RangeIndicatorRadius = Convert.ToDouble(120),
RangeIndicatorLightRadius = Convert.ToDouble(10),
RangeIndicatorLightOffset = Convert.ToDouble(80),
ScaleLabelRadius = Convert.ToDouble(90),
ScaleLabelSize = new Size(40, 20),
ScaleLabelFontSize = Convert.ToDouble(10),
ScaleLabelForeground = Colors.LightGray,
MajorTickSize = new Size(10, 3),
MinorTickSize = new Size(3, 1),
MajorTickColor = Colors.LightGray,
MinorTickColor = Colors.LightGray,
ImageOffset = Convert.ToDouble(-50),
GaugeBackgroundColor = Colors.LightGray,
PointerThickness = Convert.ToDouble(16),
OptimalRangeStartValue = Convert.ToDouble(300),
OptimalRangeEndValue = Convert.ToDouble(700),
DialTextOffset = Convert.ToDouble(40),
DialText = "Breach",
DialTextColor = Colors.Black
});
|
|
|
|
|
Please try changing the GaugeBackgroundColor to Colors.Black(any Dark Colors ) or
change the ScaleLabelForeground = Colors.Black,
MajorTickColor = Colors.Gray,
MinorTickColor = Colors.Gray,
also the needle or the pointer value is changed by the currentValue.
Thanks
|
|
|
|
|