How to set border-shadow in migradoc? - c#

MigraDoc.DocumentObjectModel.Tables.Row myRow= myTable.AddRow();
//Fila Titulo
MigraDoc.DocumentObjectModel.Paragraph paraTitle= myRow[0].AddParagraph("Some text");
paraTitulo.Format.Alignment = MigraDoc.DocumentObjectModel.ParagraphAlignment.Center;
myRow.Format.Font.Size = 11;
myRow.Format.Font.Bold = true;
myRow.TopPadding = 3;
myRow.BottomPadding = 2;
myRow.Format.Borders.Bottom.Width = 2.5;
myRow.Format.Borders.Right.Visible = false;
myRow.Format.Borders.Left.Visible = false;
myRow.Format.Borders.Top.Visible = false;
myRow.Format.Borders.Color = MigraDoc.DocumentObjectModel.Colors.LightBlue;

Border shadows are not implemented in MigraDoc.
You could add a dummy column to the right and a dummy row at the bottom and use those to draw a shadow yourself. This will look good only if the table fits on a single page.

Related

How to add tooltips to a Box plot in TeeChart?

As the title says, I am using TeeChart to draw several boxplots within one chart object. Since, the number of boxplots can be quite big, I want to be able to click on a box and have information pertaining to that series to show up as a tooltip.
I am currently trying to do this with a MarksTip but for some reason, when I try to hover over the box, MarksTip will sometimes open and then immediately close (basically being visible for a split second). I have already tried setting the hide delay but it seems to be ignoring that.
Code snippet below:
seriesIndex = 0;
foreach (var seriesData in seriesDataList)
{
var series = new Box()
series.UseCustomValues = true;
series.Box.HorizSize = 5;
series.Box.Style = PointerStyles.Rectangle;
series.MildOut.Visible = true;
series.MildOut.HorizSize = 2;
series.MildOut.VertSize = 2;
series.ExtrOut.Visible = true;
series.ExtrOut.HorizSize = 2;
series.ExtrOut.VertSize = 2;
series.LinePen.Visible = _isLineVisible;
series.Pointer.Pen.Visible = true;
series.ShowInLegend = false;
series.Add(seriesIndex, seriesData);
series.Title = "tooltip text";
var tooltip = new MarksTip(Chart.Chart)
{
Series = series,
Style = MarksStyles.SeriesTitle,
HideDelay = 31000,
};
Chart.Series.Add(series);
seriesIndex++;
}
Credit to this other question for pointing me in the right direction.
I ended up using the GetSeriesMark event to modify the text of a single chart-bound MarksTip instead of creating multiple series-bound `MarksTip
seriesIndex = 0;
Chart.Tools.Add(new MarksTip());
foreach (var seriesData in seriesDataList)
{
var series = new Box()
series.UseCustomValues = true;
//Other series appearance stuff
series.Add(seriesIndex, seriesData);
series.Title = "tooltip text";
series.GetSeriesMark += (s, args) =>
{
args.MarkText = s.Title;
};
series.Marks.Visible = false;
Chart.Series.Add(series);
seriesIndex++;
}
One note about this method. The tooltip will only appear when hovering over actual datapoints and not the whole box. Not ideal but at least I can read the tooltip now.

How to show the marker points in line graph using c#

I am using Line graph in my application and is working fine. I tried to draw the marker points in line graph,but the marker points are not displaying.
In line chart marker properties, I have chosen markerSize as 5,markerStyle as Circle,MarkerColor as blue.Refer my code below.
series1.Name = "Series1";
series1.IsVisibleInLegend = false;
series1.IsXValueIndexed = true;
series1.XValueType = ChartValueType.Time;
series1.YAxisType = AxisType.Primary;
series1.ChartType = SeriesChartType.Line;
this.chart1.Series.Add(series1);
I don't see how the Markers can show up from your code.
You need to set a non-default MarkerStyle:
series1.MarkerStyle = MarkerStyle.Circle;
If you use the debugger on that line you can see how the default is None !
Of course you will want to play with all other marker relates series properties, which all inherited from the DataPointCustomProperties
You are using ChartType.Line which is fine. Note that FastLine does not display markers!
If you only want to show some Markers simply style them for each point:
S1.Points[8].MarkerStyle = MarkerStyle.Triangle;
S1.Points[8].MarkerSize = 22;
S1.Points[8].MarkerColor = Color.Red;
I suggest getting each of your points, looping through them and adding each one. I noticed you want to set a name so I just created a counter then appended an integer value to the end of 'ser', name how you please.
Dim counter as int = 0;
foreach (Series ser in chart.Series)
{
ser.Name = "ser" & counter + 1;
ser.IsVisibleInLegend = false;
ser.IsXValueIndexed = true;
ser.XValueType = ChartValueType.Time;
ser.YAxisType = AxisType.Primary;
ser.ChartType = SeriesChartType.Line;
this.chart1.Series.Add(ser);
counter += 1;
}

C# Scaling Axes of chart

I have a problem with charts in my application. I want to use charts to display histograms of pictures. I want to add a gradient rectangle under chart with colors from black to R/G/B/White, so I draw it as Background Image of each chart. When values on AxisY ar greater then 1k everything is fine, but when those values have less then 4 digits there is a problem screen. Anyone know how to prevent extension of AxisX?
Init charts:
for(int i = 0; i < 3; i++)
{
ca = new ChartArea();
ca.AxisX.Interval = 1D;
ca.AxisX.IntervalOffsetType = System.Windows.Forms.DataVisualization.Charting.DateTimeIntervalType.Number;
ca.AxisX.LabelAutoFitStyle = System.Windows.Forms.DataVisualization.Charting.LabelAutoFitStyles.WordWrap;
ca.AxisX.MajorGrid.Enabled = false;
ca.AxisY.MajorGrid.LineColor = System.Drawing.Color.DarkGray;
ca.BackColor = System.Drawing.Color.Transparent;
ca.BackSecondaryColor = System.Drawing.Color.Transparent;
ca.BorderWidth = 0;
ca.Name = "ChartArea" + i.ToString();
ca.AxisY.LabelAutoFitStyle = LabelAutoFitStyles.DecreaseFont;
ca.AxisX.Minimum = 0;
ca.AxisX.Interval = 256;
ca.AxisY.IntervalAutoMode = IntervalAutoMode.VariableCount;
s = new Series();
s.BorderWidth = 0;
s.ChartArea = "ChartArea" + i.ToString();
s.IsVisibleInLegend = false;
s.Name = "Series" + i.ToString(); ;
s.Color = Colors[i];
s["PointWidth"] = "1";
HistCharts[i] = new Chart();
HistCharts[i].Anchor = AnchorStyles.Top | AnchorStyles.Right;
HistCharts[i].BackColor = Color.Transparent;
HistCharts[i].BackgroundImageLayout = ImageLayout.None;
HistCharts[i].BorderlineWidth = 0;
HistCharts[i].ChartAreas.Add(ca);
HistCharts[i].Location = new System.Drawing.Point(405, (i + 3) * Form.Height / 6 - 28);
HistCharts[i].Name = "Chart" + i.ToString();
HistCharts[i].Series.Add(s);
HistCharts[i].Size = new System.Drawing.Size(297, Form.Height / 6 - 27);
HistCharts[i].TabIndex = 6;
HistCharts[i].Text = "chart" + i.ToString();
HistCharts[i].Visible = false;
HistCharts[i].SendToBack();
}
SetChartImage();
for(int i = 0; i < 3; i++)
HistCharts[i].BackgroundImage = HistImages[i];
Set new series and paint:
if(Hists == null)
{
HistCharts[0].Visible = false;
HistCharts[1].Visible = false;
HistCharts[2].Visible = false;
UpdateStatTimer(Time);
return;
}
HistCharts[0].BackgroundImage = HistImages[Hists.Length > 1 ? 1 : 0];
if(Hists[0].SequenceEqual(Hists[1]) && Hists[0].SequenceEqual(Hists[2]))
{
HistCharts[0].Series[0].Color = Color.Black;
HistCharts[0].BackgroundImage = HistImages[0];
HistCharts[0].Visible = true;
HistCharts[1].Visible = false;
HistCharts[2].Visible = false;
}
else
{
HistCharts[0].Series[0].Color = Color.Red;
HistCharts[0].BackgroundImage = HistImages[1];
HistCharts[0].Visible = true;
HistCharts[1].Visible = true;
HistCharts[2].Visible = true;
}
int Max = 0;
for(int i = 0; i < 3; i++)
{
HistCharts[i].Series[0].Points.Clear();
HistCharts[i].ChartAreas[0].AxisY.Maximum = Double.NaN;
for(int j = 0; j < Hists[i].Length; j++)
HistCharts[i].Series[0].Points.AddXY(j + 0.5, Hists[i][j]);
HistCharts[i].Update();
if(HistCharts[i].ChartAreas[0].AxisY.Maximum > Max)
Max = (int) HistCharts[i].ChartAreas[0].AxisY.Maximum;
}
if(StatisticsItemCheck.Checked == false)
{
for(int i = 0; i < 3; i++)
HistCharts[i].ChartAreas[0].AxisY.Maximum = Max;
}
if all Hists are equal Green and Blue histograms are invisible and Red Histogram becomes GrayScale Histogram
This is not really about scaling..:
The reason your images don't always align with the Y-Axis is that the Y-Axis legend takes more or less room in various cases. This make the inner plot area move to the right and your carefully aligned image doesn't fit anymore.
When the Y-Axis moves to the right the whole plotarea shrinks, at least if the default vlaues of Auto are still valid for the various elements..
The simplest workaround is to set the position from Auto to a fixed value that suits all your data:
chart1.ChartAreas[0].InnerPlotPosition.X = someValue;
Note that all element position values are in percent of the whole chart! So maybe you will want to modify it upon resizing the chart..? As you have noticed, you also have to resize you images..
To find a good value you can use the debugger to see which are the current ones in both of your cases and pick the larger one and then some extra for safety..
In the same veign you may want to get better control over the format, i.e. the number of digits on your y-axis label values, maybe like this..:
chart1.ChartAreas[0].AxisY.LabelStyle.Format = "0.00"; // some formatstring
Update:
To make use of the system's AutoScaling during(after a resize, you can use this workaround:
First set the Auto on and copy the resulting Elementposition. Then use those values to create a new one under control:
int LeftEdge = yourValue;
chart1.ChartAreas[0].InnerPlotPosition.Auto = true;
ElementPosition EP = chart1.ChartAreas[0].InnerPlotPosition;
chart1.ChartAreas[0].InnerPlotPosition =
new ElementPosition(LeftEdge, EP.Y, EP.Height, 100 - LeftEdge);

How to draw vertical line on mschart that fills graph but isn't infinite?

I am trying to draw a vertical line that is anchored to a point. I tried to use the height of my Y axis which is fixed to draw the line, but it wasn't centered correctly. So right now I have an infinite line, but that I want is the line to just fill the graph like so
VerticalLineAnnotation lineannot = new VerticalLineAnnotation();
lineannot.AnchorDataPoint = chart.Series[item].Points.Last();
lineannot.LineColor = Color.Red;
lineannot.Width = 3;
lineannot.Visible = true;
lineannot.IsInfinitive = true;
chart.Annotations.Add(lineannot);
IsInfinitive is complemented by ClipToChartArea; you can set the line to be clipped to a ChartArea like this:
lineannot.ClipToChartArea = chart.ChartAreas[item].Name;
assuming item is the right area name or index..
Note that ClipToChartArea takes the name of the chart area!
This is the simplest way to do it.
It is also possible to control an annotation's position and size directly:
// Note that directly after adding points this will return NaN:
double maxDataPoint = chart1.ChartAreas[0].AxisY.Maximum;
double minDataPoint = chart1.ChartAreas[0].AxisY.Minimum;
LineAnnotation annotation2 = new LineAnnotation();
annotation2.IsSizeAlwaysRelative = false;
annotation2.AxisX = chart1.ChartAreas[0].AxisX;
annotation2.AxisY = chart1.ChartAreas[0].AxisY;
annotation2.AnchorY = minDataPoint;
annotation2.Height = maxDataPoint - minDataPoint;;
annotation2.Width = 0;
annotation2.LineWidth = 2;
annotation2.StartCap = LineAnchorCapStyle.None;
annotation2.EndCap = LineAnchorCapStyle.None;
annotation2.AnchorX = 21; // <- your point
annotation2.LineColor = Color.Pink; // <- your color
chart1.Annotations.Add(annotation2);

winform mschart hittest not finding legend

I have a charting application that has an overlay function which reassigns the 'from' chart series to the 'to' chart using this code :
chTo.Series.Add(chFrom.Series[s]); //Reassign series to new chart
chTo.Legends.Add(chFrom.Legends[s]); //Reassign legend to new chart
Works great. However, I am trying to implement tooltips for the legends and am running into an issue where only the first legend in the chart will show tooltips. When I do a hittest only the first legend is recognized. All subsequent legends, while visible on the chart, aren't 'seen' to the hittest method. I'm thinking this is why the tooltips aren't showing as there is no object to trigger the mouseover event for the tooltip.
I have been unable to find a way to 'expand' the legend area (as detected by the hittest method) to make this work.
Does anyone have any ideas? Thanks!
Responding to King King --
The original legend is created in the same method as the chart thus:
//Create the series legend
chartSel.Series[ySeries.Name].ChartArea = "ChartArea1";
chartSel.Legends.Remove(chartSel.Legends.FindByName("Legend1"));
chartSel.Legends.Add(ySeries.Name);
chartSel.Legends[0].Name = ySeries.Name;
//Format the series legend
chartSel.Legends[ySeries.Name].Docking = Docking.Right;
chartSel.Legends[ySeries.Name].DockedToChartArea = "ChartArea1";
chartSel.Legends[ySeries.Name].Alignment = StringAlignment.Near;
chartSel.Legends[ySeries.Name].IsDockedInsideChartArea = false;
chartSel.Legends[ySeries.Name].LegendStyle = LegendStyle.Table; //.Row;
chartSel.Legends[ySeries.Name].TableStyle = LegendTableStyle.Tall;
chartSel.Legends[ySeries.Name].IsEquallySpacedItems = false;
chartSel.Legends[ySeries.Name].Font = new Font("Segoe UI", 7, FontStyle.Bold);
//chartSel.Legends[ySeries.Name].TextWrapThreshold = 17; // 19;
chartSel.Legends[ySeries.Name].Position.Auto = false;
chartSel.Legends[ySeries.Name].Position.X = 80;
chartSel.Legends[ySeries.Name].Position.Y = 2;
chartSel.Legends[ySeries.Name].Position.Width = 18;
chartSel.Legends[ySeries.Name].Position.Height = 12;
//Format series data point value cell
chartSel.Legends[ySeries.Name].CellColumns.Add(new LegendCellColumn("", LegendCellColumnType.Text, ""));
chartSel.Legends[ySeries.Name].CellColumns[0].Alignment = ContentAlignment.MiddleLeft; //.TopLeft;
chartSel.Legends[ySeries.Name].CellColumns[0].Margins = new System.Windows.Forms.DataVisualization.Charting.Margins(10, 10, 1, 1);
chartSel.Legends[ySeries.Name].CellColumns[0].MinimumWidth = 500;
chartSel.Legends[ySeries.Name].CellColumns[0].MaximumWidth = 500;
chartSel.Legends[ySeries.Name].CellColumns[0].BackColor = Color.FromArgb(120, chartSel.Series[ySeries.Name].Color);
//Format legend cell spacer
chartSel.Legends[ySeries.Name].CellColumns.Add(new LegendCellColumn("", LegendCellColumnType.Text, ""));
chartSel.Legends[ySeries.Name].CellColumns[1].Alignment = ContentAlignment.TopLeft;
chartSel.Legends[ySeries.Name].CellColumns[1].Margins = new System.Windows.Forms.DataVisualization.Charting.Margins(0, 0, 0, 0);
chartSel.Legends[ySeries.Name].CellColumns[1].MinimumWidth = 25;
chartSel.Legends[ySeries.Name].CellColumns[1].MaximumWidth = 25;
chartSel.Legends[ySeries.Name].CellColumns[1].BackColor = Color.Black;
//Format series title cell
chartSel.Legends[ySeries.Name].CellColumns.Add(new LegendCellColumn("", LegendCellColumnType.Text, ySeries.Name));
chartSel.Legends[ySeries.Name].CellColumns[2].Alignment = ContentAlignment.MiddleLeft;
chartSel.Legends[ySeries.Name].CellColumns[2].Margins = new System.Windows.Forms.DataVisualization.Charting.Margins(0, 0, 1, 1);
chartSel.Legends[ySeries.Name].CellColumns[2].MinimumWidth = 1475; //1500;
chartSel.Legends[ySeries.Name].CellColumns[2].MaximumWidth = 1475; //1500;
chartSel.Legends[ySeries.Name].CellColumns[2].ToolTip = ySeries.Name;
After the series and legends have been reassigned (using the code in my original post) I then set the legend values based on the cursor position located by the following hittest in response to a mouse-down event:
pt = activePanel.PointToClient(Control.MousePosition);
ch = activePanel.GetChildAtPoint(pt) as Chart;
if (ch != null)
{
HitTestResult ht = ch.HitTest(e.X, e.Y, false);
if (ht.ChartElementType == ChartElementType.PlottingArea)
{
SetLegendValueText(ht, ch);
}
}
private void SetLegendValueText(HitTestResult ht, Chart ch)
{
//Get the datapoint 'x' index value
int dpIndex = 0;
if (ht != null)
{
switch (ht.ChartElementType)
{
case ChartElementType.DataPoint: //Cursor is on a series line
DataPoint dp = ht.Object as DataPoint;
if (dp != null)
{
dpIndex = ht.PointIndex;
}
break;
case ChartElementType.PlottingArea: //Cursor is somewhere in the plot area of the chart
dpIndex = (int)ht.ChartArea.CursorX.Position;
break;
}
}
//Set legend value and legend tooltip
for (int x = 0; x < ch.Legends.Count; x++) //foreach (Series s in ch.Series)
{
if (dpIndex > 0)
{
ch.Legends[x].Name = "Legend_" + x;
ch.Legends[x].CellColumns[0].Text = ch.Series[x].Points[dpIndex - 1].YValues[0].ToString();
ch.Legends[x].CellColumns[0].ToolTip = ch.Legends[x].CellColumns[0].Text;
}
}
}
So, I end up with the legends looking the way I want them, but the tooltips only show for the first legend item. I've tried to do custom items as well. With them I get the tooltips, but I lose the formatting. This has been driving me crazy for weeks (off and on) and I would really like to move on to other issues. Clearly (to me anyway), I am not doing something right simply because I don't know everything there is to know about the charts, and the MSChart Samples are of very limited benefit.
I'd be most grateful if I could be pointed in the right direction.

Categories

Resources