Are there any working piemenu controls for WPF?
I've found this in my favorite , you can take a look at :
This
have a nice day.
This question is probably long dead, but just a note that the control Thomas M posted, while awesome, has a major issue: You need to mouse over and click on the actual item instead of the pie slice. This means that the pie slices are not completely adjacent and IMO defeats a lot of the clickability (Frits's law) advantages of the control. So while it looks like a pie menu, it really just positions everything radially.
I ended up doing this:
private static Path makeDeliciousKeyLimePieSlice(double innerRadius, double outerRadius,
double startAngle, double endAngle, Vector ofs)
{
Point p1 = new Point(Math.Cos(endAngle) * innerRadius, Math.Sin(endAngle) * innerRadius) + ofs;
Point p2 = new Point(Math.Cos(startAngle) * innerRadius, Math.Sin(startAngle) * innerRadius) + ofs;
Point p3 = new Point(Math.Cos(startAngle) * outerRadius, Math.Sin(startAngle) * outerRadius) + ofs;
Point p4 = new Point(Math.Cos(endAngle) * outerRadius, Math.Sin(endAngle) * outerRadius) + ofs;
PathFigure fig = new PathFigure(p1, new PathSegment[] {
new ArcSegment(p2, new Size(innerRadius, innerRadius), endAngle - startAngle, false, SweepDirection.Counterclockwise, true),
new LineSegment(p3, true),
new ArcSegment(p4, new Size(outerRadius, outerRadius), startAngle - endAngle, false, SweepDirection.Clockwise, true),
}, true).GetAsFrozen();
return new Path { Data = new PathGeometry(new[] { fig }).GetAsFrozen() };
}
This will create a "slice" of the pie. You can style this how you want if you want a true pie menu. Another option is to make it transparent (set the fill to Brushes.Transparent; it must have a fill to be hit-test visible), which looks good for radial context menus. Here's my WIP after about half an hour's work (I know the spacing sucks):
alt text http://public.blu.livefilestore.com/y1pdW5ibqWquKGosMSch9C5KmOTKkiZ35mAI7iFKKUKf3cm7TGSquXhO8hkkL9Ln6Z3tKn74u67C27Qb_AIWQxzhg/radial.png?psid=1
EDIT: ah; the cursor doesn't appear in the shot -- basically, if you use the path overlay, you can have the mouse outside the actual control but still have it highlighted.
This control needs a bit of work still but it's a great starting point and supports multiple levels of items. (ie: a hierarchy) Check it out here
Related
I need to show/hide some data points in oxyplot line series. Is it possible?
Though some markers are invisible, the line should go through the invisible markers.
You could make use of two series to achieve this. The first one would draw the complete points (and line) without the marker. The second series would draw the visible points(with marker,but with line style set to none). For Example
DataPoint[] points = new DataPoint[]
{
new DataPoint(1,12),
new DataPoint(2,10),
new DataPoint(3,9),
new DataPoint(4,13),
new DataPoint(5,14),
new DataPoint(6,10)
};
var seriesComplete = new OxyPlot.Series.LineSeries();
seriesComplete.Points.AddRange(points);
var seriesVisible = new OxyPlot.Series.LineSeries();
seriesVisible.Points.AddRange(points.Where(x => x.Y % 2 == 0));
seriesVisible.MarkerFill = OxyColors.Blue;
seriesVisible.MarkerType = MarkerType.Circle;
seriesVisible.MarkerSize = 10;
seriesVisible.LineStyle = LineStyle.None;
this.MyModel.Series.Add(seriesComplete);
this.MyModel.Series.Add(seriesVisible);
Result is attached as image
We are using TeeChart for .net (Version 4.1.2013.7302) in our forms application.
One of the charts in our product has Y Axis scrolling enabled. This makes some portion of chart visible at a given instance. To see other part of chart, user needs to use the scrollbar. A separate scrollbar is used instead of axis scrollbar, as there will be a adjoining grid control and; both chart & grid are expected to be scrolled using common scrollbar. Following is the sample form image depicting the scenario:
We are using TeeChart's export functionality to export this chart as an image. But since chart has scrolling enabled (i.e. minimum of chart is not visible by default); TeeChart is exporting only visible portion of Chart, and not the entire chart. Following is the image of chart exported:
Please suggest if there exists any way to export the entire chart as an image, and not just the visible portion of it?
Thanks in Advance.
Here's a fuller version of Yeray's code that fills out the exported image to the size of the full, mainly non-visible chart:
private void button11_Click(object sender, EventArgs e)
{
//get zoomed axis min maxes
double xtmpMin = tChart1.Axes.Bottom.Minimum;
double xtmpMax = tChart1.Axes.Bottom.Maximum;
double ytmpMin = tChart1.Axes.Left.Minimum;
double ytmpMax = tChart1.Axes.Left.Maximum;
//how many pixels are plotted for the axes' ranges
int yPixelRange = tChart1.Axes.Left.CalcPosValue(tChart1.Axes.Left.Minimum)-tChart1.Axes.Left.CalcPosValue(tChart1.Axes.Left.Maximum);
int xPixelRange = tChart1.Axes.Bottom.CalcPosValue(tChart1.Axes.Bottom.Maximum) - tChart1.Axes.Bottom.CalcPosValue(tChart1.Axes.Bottom.Minimum);
//get the chart header/footer space to re-apply to chart
int yMargins = tChart1.Bounds.Height - yPixelRange;
int xMargins = tChart1.Bounds.Width - xPixelRange;
//how many pixels are we getting per axis scale
double pixelsPerYAxisInt = yPixelRange / (ytmpMax - ytmpMin);
double pixelsPerXAxisInt = xPixelRange / (xtmpMax - xtmpMin);
//what increment are we at. Note. To get this back we may need to mod font size, min separation
double yInc = tChart1.Axes.Left.CalcIncrement;
double xInc = tChart1.Axes.Bottom.CalcIncrement;
//now reset auto axes before plotting full chart. Could use other criteria here
tChart1.Axes.Left.Automatic = true;
tChart1.Axes.Bottom.Automatic = true;
//Repaint full Chart (necessary for positioning calcs)
tChart1.Draw();
//set increments on full scales (note Chart will try to set them,
//but if it can't you have the last word with label separation, font size, etc)
tChart1.Axes.Left.Increment = yInc;
tChart1.Axes.Bottom.Increment = xInc;
//dimension chart for export
double fullYRange = tChart1.Axes.Left.Maximum - tChart1.Axes.Left.Minimum;
double fullXRange = tChart1.Axes.Bottom.Maximum - tChart1.Axes.Bottom.Minimum;
int fullYSize = (int)((pixelsPerYAxisInt * fullYRange) + yMargins);
int fullXSize = (int)((pixelsPerXAxisInt * fullXRange) + xMargins);
//setup and export image
tChart1.Export.Image.PNG.Width = fullXSize;
tChart1.Export.Image.PNG.Height = fullYSize;
tChart1.Export.Image.PNG.Save(#"c:\mypath\chart.png");
//reset screen chart to where it was
tChart1.Axes.Bottom.SetMinMax(xtmpMin, xtmpMax);
tChart1.Axes.Left.SetMinMax(ytmpMin, ytmpMax);
}
There are many ways to optimise that code, Axis does have an iRange that I haven't tried, and some of the steps can be brought together but I hope they are clear and useful and give you something of what you're looking for.
You can manually adjust your axis scale, export your chart and then restore your axis. Ie (if 0 - 4.25 in the bottom axis is the "entire chart"):
double tmpMin = tChart1.Axes.Bottom.Minimum;
double tmpMax = tChart1.Axes.Bottom.Maximum;
tChart1.Axes.Bottom.SetMinMax(0, 4.25);
tChart1.Export.Image.JPEG.Save(myFileName);
tChart1.Axes.Bottom.SetMinMax(tmpMin, tmpMax);
I need to calculate the intersection between two geometries to check if one is fully inside the other or not.
The Geometry "container", based on a System.Windows.Shapes.Polygon, is created as follows:
List<PathSegment> basePolygonSegments = new List<PathSegment> {
new PolyLineSegment(basePolygon.Points, true) };
PathGeometry baseGeometry = new PathGeometry();
baseGeometry.Figures.Add(
new PathFigure(basePolygon.Points[0], basePolygonSegments, true));
The Geometry "contained" can be:
another System.Windows.Shapes.Polygon
a System.Windows.Shapes.Polyline, that can have only one line or three lines (the shape is a |_|, or U)
The Polyline is created as follows:
Polyline bracketDrawingPolyline = new Polyline();
foreach(Point p in listOfPoints)
bracketDrawingPolyline.Points.Add(p);
LineGeometry lineGeometry =
new LineGeometry(
bracketDrawingPolyline.Points[0],
bracketDrawingPolyline.Points[bracketDrawingPolyline.Points.Count - 1]);
PathGeometry bracketGeometry = new PathGeometry();
bracketGeometry = lineGeometry.GetWidenedPathGeometry(
new Pen(Brushes.Black, 1.0));
To understand if the "contained" Geometry is contained in the "container", I do the following:
CombinedGeometry intersectionGeometry =
new CombinedGeometry(GeometryCombineMode.Intersect,
baseGeometry, bracketGeometry);
double intersectionArea =
intersectionGeometry.GetArea(0.0001, ToleranceType.Absolute);
double bracketArea = bracketGeometry.GetArea(0.0001, ToleranceType.Absolute);
if (intersectionArea < bracketArea)
{
//the second Geometry is not fully contained in the "container" Geometry
}
else
//it is fully contained
....
In case of Polygon or Polyline with only one line everything works as expected. But with Polyline U, intersectionArea and bracketArea are always the same.
I've also tried to perform the following checks:
bool result = baseGeometry.FillContains(bracketGeometry);
IntersectionDetail idtl =
baseGeometry.FillContainsWithDetail(bracketGeometry);
but I have the same results.
I've found a solution on my own, but I don't know if it is the best one.
Considered that with a single line everything works well, I just do the check for each line of the polyline, that is:
for (int i = 1; i < bracketDrawingPolyline.Points.Count; i++)
{
LineGeometry lineGeometry =
new LineGeometry(bracketDrawingPolyline.Points[i - 1],
bracketDrawingPolyline.Points[i]);
...//continue with the check of the line as described in the post...
}
I have a canvas with a background image:
var bi = new BitmapImage(new Uri(imgLocFull));
var ib = new ImageBrush(bi) {Stretch = Stretch.UniformToFill};
MyCanvas.Background = ib;
I am overlaying various shapes on the image, and want the position of the shapes relative to the background image to be fixed.
If my application window is resized, the amount of the image that is cropped, horizontally and vertically, changes, and when my shapes are redrawn, they do not appear in the same position on the background image.
How can I determine how much of the image has been cropped (to apply an adjustment factor to the overlaid objects' positions?) Or is there a better way of fixing the location of a shape relative to the background image?
Here is my present drawing code:
var l = new Ellipse();
var scb = new SolidColorBrush();
scb.Color = Color.FromRgb(rCol, gCol, bCol);
l.Fill = scb;
l.StrokeThickness = 0;
l.Width = 3;
l.Height = 3;
Canvas.SetBottom(l, point.Y); // * clipping factor here?
Canvas.SetLeft(l, point.X); // * clipping factor here?
MyCanvas.Children.Add(l);
EDIT: Further Clarification
Here's a concrete example of what I am trying to achieve. My image is an aerial photograph, and I want to mark a particular geographical feature (with, say, an ellipse.)
When the window is resized, the ellipse doesn't stay on the feature, it stays relative to the left and top of the canvas.
I can get it closer to the right place by moving it using a factor (newx = newheight/oldheight * oldx) but this doesn't quite work because of the UniformToFill stretch mode, which sees some of the image clipped off the canvas.
The Top and Left of the Canvas are 'anchored', while the Bottom and Right move when resizing... try setting the Canvas.Top Attached Property instead, along with the Canvas.Left Attached Property as you are:
var l = new Ellipse();
var scb = new SolidColorBrush();
scb.Color = Color.FromRgb(rCol, gCol, bCol);
l.Fill = scb;
l.StrokeThickness = 0;
l.Width = 3;
l.Height = 3;
Canvas.SetTop(l, point.Y); // * clipping factor here?
Canvas.SetLeft(l, point.X); // * clipping factor here?
MyCanvas.Children.Add(l);
UPDATE >>>
You asked Or is there a better way of fixing the location of a shape relative to the background image?
I answered this question, so I don't understand why you would need to do anything else... your objects will not move when the screen in resized *if you only set the Grid.Top and Grid.Left properties.
I have a grid within a grid and i want the content of the second to move about without encroaching on the first grid.
Much like the panorama view but can move left or right as well as up and down.
I can get this working but unfortunately when you move down the top overflows into the outer grid overlapping any controls within it.
Is there a way to hide the overflow almost like CSS overflow:hidden?
Any help would be really appropriated.
Thank you
Andrew
Possible solution:
var gridWidth = (this.tilesize * (this.gridSize - 1)) / 2;
var top = -(((-offsetY + tileY) * this.tilesize) - gridWidth);
var left = -(((-offsetX + tileX) * this.tilesize) - gridWidth);
this.Container.Margin = new Thickness(left, top, 0, 0);
var clipSection = new RectangleGeometry();
clipSection.Rect = new Rect(-1 * left, -1 * top, 480, 400);
this.Container.Clip = clipSection;
this.Container.Dispatcher.BeginInvoke(new ThreadStart(delegate
{
this.Container.Clip = clipSection;
}));
You could do this by putting something in the cells of the "outer" grid and seeing a higher ZIndex than the elements you are moving around. The elements with the higher ZIndex appear above the lower ones.