I am using Visual Studio 2010 along with Syncfusion Essential Studio 10.2.0.56.
I want to change the shape of open close symbols from horizontal lines to circle in hi low open close charttype in essential chart of syncfusion.
Can someone help me in achieving this????
I want to finally get this type of chart
Thanks
You can achieve this requirement by combination of Hilo and Scatter type chart. Please set the desired symbol in Hilo and scatter chart type for your requirements. Please refer the below code snippet to achieve this,
[C#]
// chart series for Hilo.
ChartSeries series1 = new ChartSeries("Series 1", ChartSeriesType.HiLo);
series1.Points.Add(1, new double[] { 8, 3 });
series1.Points.Add(2, new double[] { 10, 2 });
series1.Points.Add(3, new double[] { 16, 2 });
series1.Points.Add(4, new double[] { 7, 3 });
series1.Points.Add(5, new double[] { 12, 3 });
this.chartControl1.Series.Add(series1);
// symbol for Hilo chart type
series1.Style.Symbol.Shape = ChartSymbolShape.HorizLine;
series1.Style.Symbol.Color = Color.CadetBlue;
series1.Style.Interior = new BrushInfo(Color.Black);
// chart series for scatter.
ChartSeries series2 = new ChartSeries("Series 2", ChartSeriesType.Scatter);
for (int i = 0; i < 5; i++)
series2.Points.Add(i+1, (series1.Points[i].YValues[0] + series1.Points[i].YValues[1]) / 2);
this.chartControl1.Series.Add(series2);
// symbol for scatter chart type
series2.Style.Interior = new BrushInfo(Color.LightGreen);
series2.ZOrder = 0;
// chart series for scatter.
ChartSeries series3 = new ChartSeries("Series 3", ChartSeriesType.Scatter);
for (int i = 0; i < 5; i++)
series3.Points.Add(i + 1, (series1.Points[i].YValues[1]));
this.chartControl1.Series.Add(series3);
// symbol for scatter chart type
series3.Style.Symbol.Shape = ChartSymbolShape.HorizLine;
series3.Style.Symbol.Color = Color.Red;
Regards,
M. Balaji
Related
I'm trying to generate a Word document through my application coded in WPF. In that document, I also need to layout few images along with caption as shown in the image below.
All the images are stored in database as base64 string. I'm able to load the images as "BitmapImage" object in the document however not sure how to layout the images as shown in image. Code snippet to load the images in document is as below :
var bookmarks = wordDoc.Bookmarks;
var range = bookmarks["ExternalImage"].Range;
foreach (var image in ExternalImages) // here image is "BitmapImage" object
{
float scaleHeight = (float)250 / (float)image.Image.PixelHeight;
float scaleWidth = (float)250 / (float)image.Image.PixelWidth;
var min = Math.Min(scaleHeight, scaleWidth);
var bitmap = new TransformedBitmap(image, new ScaleTransform(min, min));
System.Windows.Clipboard.SetImage(bitmap);
range.Paste();
}
How can I lay out the images as shown in image above along with caption? Note that I'm not loading images from file but from memory object.
Based on the direction provided by #CindyMeister in comments, following is the working code snippet to layout the images using code :
imageTable = wordDoc.Tables.Add(sel.Range, rows, cols, ref oMissing, ref oMissing);
imageTable.AllowAutoFit = true;
row = 1; col = 1;
foreach (var image in Images)
{
float scaleHeight = (float)475 / (float)image.PixelHeight;
// here 475 is approx image size I want in word document
float scaleWidth = (float)475 / (float)image.PixelWidth;
var min = Math.Min(scaleHeight, scaleWidth);
var bitmap = new TransformedBitmap(image, new ScaleTransform(min, min));
System.Windows.Clipboard.SetImage(bitmap);
//more efficient/faster in C# if you don't "drill down" multiple times to get an object
Word.Cell cel = imageTable.Cell(row, col);
Word.Range rngCell = cel.Range;
Word.Range rngTable = imageTable.Range;
rngCell.Paste();
cel.VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalCenter;
rngCell.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
// set caption below image
rngTable.ParagraphFormat.SpaceAfter = 6;
rngCell.InsertAfter(image.Caption);
rngTable.Font.Name = "Arial Bold";
row++;
}
This code I have posted for reference, only, to let people have some starting point. Any suggestions welcome.
I'm having a Problem constructing a combined Candlestick Chart and Line Chart (both on the same plot). For the Candlesticks I use OHLCDataset and for the "moving average" linechart I use TimeSeries. However the Linecharts get drawn at the wrong timepoint along the axis. I have printed all DateTime Elements to make shure I did not set the wrong time or date but when printed they show exactly the date times they are supposed to. In the Chart however they start 6 hours too early. I first thought this would be a Timezone Issue but I'm setting the timezone on both to EST.
Here are the code snippets that create the dataset and assign it to the XYPlot
The OHLCDataset retrieving method (time[i] is a Date Object):
public OHLCDataset getOHLCDataset(){
OHLCSeries ohlcSeries = new OHLCSeries("Candlesticks");
for(int i=0; i<close.length; i++){
ohlcSeries.add(RegularTimePeriod.createInstance(Minute.class, time[i], TimeZone.getTimeZone("EST")), open[i], max[i], min[i], close[i]);
}
OHLCSeriesCollection ohlcCollection = new OHLCSeriesCollection();
ohlcCollection.addSeries(ohlcSeries);
return ohlcCollection;
}
The TimeSeries retrieving method (time[i] is a Date Object - the same as above):
public XYDataset getAverageXYDataset(int periods, int frame){
TimeSeries x = new TimeSeries("moving average " + periods + " periods");
if(frame>60){
for(int i=periods-1; i<close.length; i++){
double sum = 0;
for(int j=i; j>i-periods; j--){
sum += close[j];
}
x.add(RegularTimePeriod.createInstance(Hour.class, time[i], TimeZone.getTimeZone("EST")), sum/periods);
}
}else{
for(int i=periods-1; i<close.length; i++){
double sum = 0;
for(int j=i; j>i-periods; j--){
sum += close[j];
}
x.add(RegularTimePeriod.createInstance(Minute.class, time[i], TimeZone.getTimeZone("EST")), sum/periods);
}
}
return new TimeSeriesCollection(x);
}
The code that adds the datasets to the plot:
OHLCDataset dataset1 = dataset.getOHLCDataset();
XYDataset smallAverageDataset = dataset.getAverageXYDataset(20, period);
XYDataset bigAverageDataset = dataset.getAverageXYDataset(50, period);
// create the jfreechart - add candlestickdataset first
String title2 = dataset.getTime()[0] + " - " + dataset.getTime()[dataset.getTime().length-1];
JFreeChart chart = createChart(dataset1, title2);
// get the xyplot and set other datasets
chart.getXYPlot().setDataset(1, smallAverageDataset);
chart.getXYPlot().setDataset(2, bigAverageDataset);
Here is the method createChart:
private static JFreeChart createChart(final OHLCDataset dataset, String title) {
DateAxis xAxis = createXAxis();
NumberAxis yAxis = createYAxis();
MyCandlestickRenderer candlestickRenderer = createCandlestickRenderer();
plot = new XYPlot(dataset, xAxis, yAxis, candlestickRenderer);
JFreeChart chart = new JFreeChart(
title,
new Font("SansSerif", Font.BOLD, 24),
plot,
false
);
return chart;
}
And here is the createXAxis method:
private static DateAxis createXAxis(){
DateAxis domainAxis = new DateAxis();
domainAxis.setAutoRange(true);
domainAxis.setTickLabelsVisible(true);
domainAxis.setAutoTickUnitSelection(true);
return domainAxis;
}
I cannot figure out why there is such an offset on the linecharts but as you see I set the same Timezones for all Datasets.
Thanks in advance for the Help.
In JFreeChart's TimeSeries class, the x-values are time periods rather than specific points in time. The TimeSeriesCollection class presents this data via the XYDataset interface and has to choose a specific x-value for each data item. The setXPosition method (in TimeSeriesCollection) sets a flag that determines which point in the time period is used (start, middle or end).
I am using Jfreechart API 1.0.8 to generate the TimeSeriesChart(line chart).
when I am generating the chart, i am facing the problem of overlapping.
Here I am trying to display the rendered points(graph rendered points), by using XYLineAndShapeRenderer with StandardXYItemLabelGenerator.
When the points are displayed, the data-point is overlapping with the generated line chart (graph).
I am taking X-Axis as time, and y-Axis as revenue of organization, and i am using line chart here.
I'm displaying the points as discussed below.
By using "renderer.setBasePositiveItemLabelPosition" method, globally i am setting the position of graph points(data points) inside the xyplot rendered chart while considering the rendered "ItemLabelAnchor".
I am sending my sample code here:
chart = ChartFactory.createTimeSeriesChart("", "", "", newxyseries, false, true, false);
renderer = new XYLineAndShapeRenderer();
renderer = (XYLineAndShapeRenderer) chart.getXYPlot().getRenderer();
renderer.setBaseItemLabelGenerator(new StandardXYItemLabelGenerator("{2}", monthDate, formatSymbol));
renderer.setBaseItemLabelsVisible(true);
renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.OUTSIDE3, TextAnchor.TOP_RIGHT));
chart.getXYPlot().setRenderer(renderer);
But when I am generating the graph chart using Ms-office of Excel tools, there is no problem of overlapping of labels, the points are displayed in an effective manner without any overlapping.
JFreeChart doesn't do any overlap detection for item labels. It would be a great feature to have, but nobody has written the code to do it.
you have to refrain the labels to get overlap by define your own algo or logic because as the graph keep growing sooner the labels will start to get overlap.
the key is to make some or alternative labels transparent so that no overlapping occur
For example in the following P.O.C, only 35 labels will be drawn but the tick of graphs will remai same just the labels will reduce
CategoryAxis domainAxis = plot.getDomainAxis();
CategoryLabelPositions pos = domainAxis.getCategoryLabelPositions();
double size = plot.getCategories().size();
double occurence = Math.ceil(plot.getCategories().size() / 20);
double interval = Math.ceil(plot.getCategories().size() / 20);
for (int i = 1; i <= plot.getCategories().size(); i++) {
if (plot.getCategories().size() > 35) {
if(plot.getCategories().size()>35 && plot.getCategories().size()<250) {
if(i%8==0){
String cat_Name = (String) plot.getCategories().get(i-1);
} else{
String cat_Names = (String) plot.getCategories().get(i-1);
domainAxis.setTickLabelPaint(cat_Names, new Color(0,0,0,0));
}
}else if(plot.getCategories().size()>250){
[![enter image description here][1]][1]
if (i == occurence) {
String cat_Name = (String) plot.getCategories().get(i - 1);
if (occurence + interval >= size) {
// occurence=size;
} else {
occurence = occurence + interval;
}
} else {
String cat_Names = (String) plot.getCategories().get(i - 1);
domainAxis.setTickLabelPaint(cat_Names, new Color(0, 0, 0, 0));
}
}
}
Below line will make label transparent
domainAxis.setTickLabelPaint(cat_Names, new Color(0,0,0,0));
I have a 3D array, I want to plot it as a surface in ILNumerics. Here is my code:
ILArray<float> plot = ILMath.tosingle(hasil);
var scene = new ILScene();
ILColormap cm = new ILColormap(Colormaps.Jet);
ILArray<float> data = cm.Data;
scene.Add(
new ILPlotCube(twoDMode: false){
new ILSurface(plot[":;:;2"]){
Wireframe = { Color = Color.FromArgb(50, Color.LightGray)},
Colormap = new ILColormap(data),
Children = { new ILColorbar()}
}
}
);
ilPanel1.Scene = scene;
And here is the result:
Actually my array includes the x posisition (plot[":;:;0"]) and y position (plot[":;:;1"]). How to use that for ILSurface in order to get the correct grid positions and value? Rather than indexed value in the range 0-100?
Well, it was simply. I already got the answer.
new ILSurface(plot[":;:;2"],plot[":;:;0"],plot[":;:;1"])
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...
}