I've spent a few days trying to bind my data model to a lineseries. I works fine; however, I want to change the line color. I knew where to change the color, yet the chart and series would ignore my binding (was a SolidColorBrush). If I hard-coded the color in XAML it would work; however, if I tried to bind the same property to the color property in my view model it would not work. After too much time was spent I gave up for 2 reasons.
It just wouldn't work
I realized I was going to need to bind 'x'
number of view models to the chart to show more than one line series
at a time.
I eventually just defined my line series in the code behind like so...
LineSeries BuildLine(DosePointsViewModel model)
{
LineSeries series = new LineSeries();
// styles
Style poly = new Style(typeof(Polyline));
poly.Setters.Add(new Setter(Polyline.StrokeProperty, model.LineColor));
poly.Setters.Add(new Setter(Polyline.StrokeThicknessProperty, 3d));
series.PolylineStyle = poly;
Style pointStyle = new Style(typeof(LineDataPoint));
pointStyle.Setters.Add(new Setter(LineDataPoint.BackgroundProperty, model.LineColor));
series.DataPointStyle = pointStyle;
// binding
series.IsSelectionEnabled = false;
series.IndependentValueBinding = new System.Windows.Data.Binding("Distance");
series.DependentValueBinding = new System.Windows.Data.Binding("Dose");
// X axis
LinearAxis xAxis = new LinearAxis();
xAxis.Title = "Distance";
xAxis.ShowGridLines = false;
xAxis.Interval = 1;
xAxis.Orientation = AxisOrientation.X;
series.IndependentAxis = xAxis;
// Y axis
LinearAxis yAxis = new LinearAxis(); //series.DependentRangeAxis as LinearAxis;
yAxis.Maximum = 5000d;
yAxis.Minimum = -100d;
yAxis.Minimum = model.Points.Min(d => d.Dose) - model.Points.Min(d => d.Dose) * 0.50;
yAxis.Maximum = model.Points.Max(d => d.Dose) + model.Points.Max(d => d.Dose) * 0.05;
yAxis.ShowGridLines = true;
yAxis.Orientation = AxisOrientation.Y;
yAxis.Title = "Dose";
Style s = new Style(typeof(Line));
s.Setters.Add(new Setter(Line.StrokeProperty, new SolidColorBrush(Colors.LightBlue)));
s.Setters.Add(new Setter(Line.StrokeThicknessProperty, 1d));
yAxis.GridLineStyle = s;
series.DependentRangeAxis = yAxis;
return series;
}
Now, the color for my line series works. Of course, the primary reason for this is that I'm directly setting the color via ...
poly.Setters.Add(new Setter(Polyline.StrokeProperty, model.LineColor));
pointStyle.Setters.Add(new Setter(LineDataPoint.BackgroundProperty, model.LineColor));
So, my question is this. I want to be able to add multiple line series to the chart; however, when I try to do this, only the last item is being bound. Inside the code, this is done for each line series being created. Only the last line series is added to the chart.
DosePointsViewModel model = new DosePointsViewModel(_snc, m.Id);
LineSeries series = BuildLine(model);
DoseChart.Series.Clear();
DoseChart.Series.Add(series);
Wow, as I'm reading my question I realize that I am calling
DoseChart.Series.Clear();
Well that was an interesting find.
Related
I'm using PdfSharp Charts and the chart container have a blue border and a gradient background. I looked for the property that sets those options but no success. I can change multiple things in the chart itself, but not for the container.
How can I remove the border and the background?
Thanks!
Again, I looked for the properties of the chart container but no success.
Here is the code I have so far:
public static Chart ColumnChart(PdfChartValues pdfChartValues)
{
Chart chart = new Chart(ChartType.Column2D);
chart.Font.Size = 7;
chart.PlotArea.FillFormat.Color = XColors.White;
chart.Legend.Docking = DockingType.Bottom;
XSeries xSeries = chart.XValues.AddXSeries();
xSeries.Add(pdfChartValues.XSeriesText);
Series series;
foreach (var item in pdfChartValues.ChartSeriesValues)
{
series = chart.SeriesCollection.AddSeries();
series.Name = item.SeriesName;
series.Add(item.SeriesValues);
series.FillFormat.Color = XColor.FromArgb(item.RedValue, item.GreenValue, item.BlueValue); // Bar color
}
chart.XAxis.HasMajorGridlines = false;
chart.XAxis.MajorTickMark = TickMarkType.None;
chart.XAxis.Title.Caption = pdfChartValues.TitleCaption;
chart.YAxis.MajorTickMark = TickMarkType.None;
chart.YAxis.MajorTick = pdfChartValues.YAxisMajorTick;
chart.YAxis.HasMajorGridlines = true;
chart.YAxis.MajorGridlines.LineFormat.Color = XColors.LightGray;
chart.PlotArea.LineFormat.Color = XColors.LightGray;
chart.PlotArea.LineFormat.Width = 1;
chart.PlotArea.LineFormat.Visible = true;
chart.DataLabel.Type = DataLabelType.Value;
chart.DataLabel.Position = DataLabelPosition.OutsideEnd;
chart.DataLabel.Format = pdfChartValues.SetMoneyFormat ? "$0" : "##,#";
return chart;
}
It seems the colours are hard-coded in ChartFrame.cs.
They cannot yet be set using properties.
Take the PDFsharp source code, change the colours there, and compile.
Im trying to make a graph like this:
https://www.google.com/finance?q=BCBA:PAMP
I have a line chart in chart.js, now I want to add labels (like the letters A, B, C) for certain dates.
Can't find a doc/example to start from. Any idea?
If its more simple to do with another library a recommendation is more than welcome.
Thanks!
Unfortunately, there is no native support in chart.js for what you are wanting. However, you can certainly add this capability using the plugin interface. This requires that you implement your own logic to draw the canvas pixels at the locations that you want them. It might sound challenging, but its easier than it sounds.
Here is an example plugin that will add a value above specific points in the chart (based upon configuration).
Chart.plugins.register({
afterDraw: function(chartInstance) {
if (chartInstance.config.options.showDatapoints || chartInstance.config.options.showDatapoints.display) {
var showOnly = chartInstance.config.options.showDatapoints.showOnly || [];
var helpers = Chart.helpers;
var ctx = chartInstance.chart.ctx;
var fontColor = helpers.getValueOrDefault(chartInstance.config.options.showDatapoints.fontColor, chartInstance.config.options.defaultFontColor);
// render the value of the chart above the bar
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize + 5, 'normal', Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
ctx.fillStyle = fontColor;
chartInstance.data.datasets.forEach(function (dataset) {
for (var i = 0; i < dataset.data.length; i++) {
if (showOnly.includes(dataset.data[i])) {
var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model;
var scaleMax = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._yScale.maxHeight;
var yPos = (scaleMax - model.y) / scaleMax >= 0.93 ? model.y + 20 : model.y - 5;
ctx.fillText(dataset.data[i], model.x, yPos);
}
}
});
}
}
});
It allows you to configure which points you want to annotate using this new configuration. The showOnly option contains the points that you want to label.
options: {
showDatapoints: {
display: true,
showOnly: [3, 10, 9]
},
}
Obviously, this only adds the datapoint value at the specified points, but you can just change the plugin to paint whatever you want to show instead. Simply replace ctx.fillText(dataset.data[i], model.x, yPos) with different code to render something different on the canvas.
Here is a codepen example to show you want it looks like.
I am trying to highlight area on Amcharts but unable to do so with help of guide. I referred an example from here below is the code which is not working however if I add a line guide it works.
Here is the JSFiddle code snippet
http://jsfiddle.net/GreyCells/d1ywab37/
var guide1 = new AmCharts.Guide();
guide1.category = "2007-01-01";
guide1.toCategory = "2008-01-01";
guide1.lineColor = "#CC0000";
guide1.lineAlpha = 1;
guide1.fillAlpha = 0.2;
guide1.fillColor = "#CC0000";
guide1.dashLength = 2;
guide1.inside = true;
guide1.labelRotation = 90;
guide1.label = "test";
guide1.above = true;
stockPanel1.categoryAxis.addGuide(guide1);
You have two problems - first, amstock.js is not included, and second, with stock chart, which is date-based you should use guide.date and guide.toDate instead of category and toCategory:
guide1.date = new Date(2007, 0, 1);
guide1.toDate = new Date(2008, 0, 1);
http://jsfiddle.net/d1ywab37/1/
Note, months are zero based in JS.
Is there a way to copy a chart control to a new form?
I have a Windows Form with a chart control on it, but the form is not allowed to be resizable. For that reason I have a button "Zoom" that opens the chart in a new form that is resizable. I have set a lot of chart properties in the "original" chart (axis color, axis intervalls etc.) and would like to just reuse this properties. I tried to call the constructor of the new form with the chart as parameter, but that didn't work.
public ZoomChartSeriesForm(Chart myChart)
My main problem is, that I allow zooming inside of the chart and that crashes, when I just copy the chart.
Here is the code of my "original chart" (example):
System.Drawing.Color color = System.Drawing.Color.Red;
//plot new doublelist
var series = new Series
{
Name = "Series2",
Color = color,
ChartType = SeriesChartType.Line,
ChartArea = "ChartArea1",
IsXValueIndexed = true,
};
this.chart1.Series.Add(series);
List<double> doubleList = new List<double>();
doubleList.Add(1.0);
doubleList.Add(5.0);
doubleList.Add(3.0);
doubleList.Add(1.0);
doubleList.Add(4.0);
series.Points.DataBindY(doubleList);
var chartArea = chart1.ChartAreas["ChartArea1"];
LabelStyle ls = new LabelStyle();
ls.ForeColor = color;
Axis a = chartArea.AxisY;
a.TitleForeColor = color; //color of axis title
a.MajorTickMark.LineColor = color; //color of ticks
a.LabelStyle = ls; //color of tick labels
chartArea.Visible = true;
chartArea.AxisY.Title = "TEST";
chartArea.RecalculateAxesScale();
chartArea.AxisX.Minimum = 1;
chartArea.AxisX.Maximum = doubleList.Count;
// Set automatic scrolling
chartArea.CursorX.AutoScroll = true;
chartArea.CursorY.AutoScroll = true;
// Allow user to select area for zooming
chartArea.CursorX.IsUserEnabled = true;
chartArea.CursorX.IsUserSelectionEnabled = true;
chartArea.CursorY.IsUserEnabled = true;
chartArea.CursorY.IsUserSelectionEnabled = true;
// Set automatic zooming
chartArea.AxisX.ScaleView.Zoomable = true;
chartArea.AxisY.ScaleView.Zoomable = true;
chartArea.AxisX.ScrollBar.IsPositionedInside = true;
chartArea.AxisY.ScrollBar.IsPositionedInside = true;
//reset zoom
chartArea.AxisX.ScaleView.ZoomReset();
chartArea.AxisY.ScaleView.ZoomReset();
chart1.Invalidate();
Copy as in deep copying the object?
I ran into this exact problem recently myself. Unfortunately, MS Chart has no method to clone their chart object and their class is not marked as serializable so you can't use the method suggested here.
If you want to do this the right way, you'll have to introduce a third party control such as Copyable or handle the reflection yourself, but this won't be easy.
A really nice workaround I found is to use the built-in serialization inside MS Chart control. The idea is to serialize the chart using memorystream, create a new instance of the chart and deserialize the chart.
private Chart CloneChart(Chart chart)
{
MemoryStream stream = new MemoryStream();
Chart clonedChart = chart;
clonedChart.Serializer.Save(stream);
clonedChart = new Chart();
clonedChart.Serializer.Load(stream);
return clonedChart;
}
Not exactly an efficient solution, but if performance isn't your priority, this works like a charm.
How can I disable/remove the legend area when using FusionCharts? I'll be using a very small chart, so the legend area is not necessary.
Adding a showLegend='0' tag should disable it. Use it like this:
<chart showLegend='0'...>
Check out FusionCharts Legend API for more help on legends.
How to set Show legend property to my Fusion Graph.My code like this.
public Pie2DChart GetServiceEsclationChart(DataTable BarChartdt, string CaseType)
{
Pie2DChart oChart3 = new Pie2DChart();
// Set properties
oChart3.Background.BgColor = "ffffff";
oChart3.Background.BgAlpha = 50;
oChart3.ChartTitles.Caption = "Case Type Count";
oChart3.ChartTitles.Caption = CaseType;
// oChart.ChartTitles.SubCaption = "2013-2014 Year";
// Set a template
oChart3.Template = new Libero.FusionCharts.Template.OfficeTemplate();
// Set data
oChart3.DataSource = BarChartdt;
oChart3.DataTextField = "Name";
oChart3.DataValueField = "Value";
//Load it into ViewData.
// ViewData["SREsclation"] = oChart3;
return oChart3;
}