How do I render a Dundas bar chart from most to least? - mschart

How does one order the bar chart series to render from most to least? Ordering the data before binding does not seem to help.
My code:
chart.Series.Add("port");
chart.Series["port"].Type = SeriesChartType.Bar;
chart.Series["port"]["PointWidth"] = "0.6";
chart.Series["port"]["BarLabelStyle"] = "Center";
chart.Series["port"].ShowLabelAsValue = true;
chart.Series["port"].Points.DataBind(myData, "Key", "Value", "Label=Value{p2}");
chart.Series["port"].BorderStyle = ChartDashStyle.Solid;
chart.Series["port"].BorderColor = Color.White;
chart.Series["port"].BorderWidth = 1;
chart.Series["port"].ShowLabelAsValue = true;
chart.Series["port"].Font = myfont;
chart.ChartAreas.Add("Default");
chart.ChartAreas["Default"].BackColor = Color.Transparent;
foreach (var axis in chart.ChartAreas["Default"].Axes)
{
axis.LabelStyle.Font = myfont;
axis.MajorGrid.Enabled = false;
}
chart.ChartAreas["Default"].AxisX.Interval = 1;
chart.ChartAreas["Default"].AxisY.LabelStyle.Format = "p0";

You need to call Sort() on the series, see http://msdn.microsoft.com/en-us/library/dd455394.aspx. So to sort the points from most to least you'd do
chart.Series["port"].Sort(PointSortOrder.Descending);
There are two other sort methods incase you need to sort by something other than the point value.

Related

How can I apply conditional formatting in C++ MFC?

https://learn.microsoft.com/en-us/previous-versions/office/developer/office-2007/bb404903(v=office.12)?redirectedfrom=MSDN
Microsoft provides example codes in C# and Visual Basic.
For example C# code as follows.
ApplicationClass excelApplication = null;
Workbook newWorkbook = null;
Worksheet targetSheet = null;
ColorScale cfColorScale = null;
IconSetCondition cfIconSet = null;
string paramWorkbookPath = #"C:\Temp\Test.xlsx";
object paramMissing = Type.Missing;
excelApplication = new ApplicationClass();
newWorkbook = excelApplication.Workbooks.Add(XlWBATemplate.xlWBATWorksheet);
targetSheet = (Worksheet)(newWorkbook.Worksheets[1]);
targetSheet.Name = "Conditional Formatting";
// Fill cells A1:A10 with sample data.
targetSheet.get_Range("A1", paramMissing).set_Value(XlRangeValueDataType.xlRangeValueDefault, 1);
targetSheet.get_Range("A2", paramMissing).set_Value(XlRangeValueDataType.xlRangeValueDefault, 2);
targetSheet.get_Range("A1:A2",
paramMissing).AutoFill(targetSheet.get_Range("A1:A10", paramMissing), XlAutoFillType.xlFillSeries);
// Create a two-color ColorScale object for the created sample data
// range.
cfColorScale = (ColorScale)(targetSheet.get_Range("A1:A10",
Type.Missing).FormatConditions.AddColorScale(2));
// Set the minimum threshold to red (0x000000FF) and maximum threshold
// to blue (0x00FF0000).
cfColorScale.ColorScaleCriteria[1].FormatColor.Color = 0x000000FF;
cfColorScale.ColorScaleCriteria[2].FormatColor.Color = 0x00FF0000;
How can we apply conditional formatting in C++ MFC?
range = ws.get_Range(COleVariant(_T("A1"), COleVariant(_T("A10")));
CFormatCondition fc;
fc = range.get_FormatConditions();

How to show all tooltip Text where line series circle bullets intersect Amcharts 4?

I am using a Amcharts4 Line series with valueX and valueY instead of categoryX.
Currently I am able to see the tooltip on a hover of bullet/bubble but I also want to see the tooltip of all bullets if they are intersecting and overlapping with each other.
It shows the tooltip if i hover on a single bullet/bubble but if you see the red and green line intersecting each other, it shows the tooltip of green bullet/bubble only, not the other which is hidden at its back.
Click here to see Line Series graph with ValueX and ValueY
This is my code where I am having 3 series and setup a tooltip for each bullet :
let series1 = chart.series.push(new am4charts.LineSeries());
series1.cursorTooltipEnabled = true;
series1.showTooltipOn = 'hover';
series1.dataFields.valueY = "compressorCap";
// series1.dataFields.categoryX = "evapDegC"; // If X-Axis is Category Axis
series1.dataFields.valueX = "evapDegC"; // If X-Axis is Value Axis
series1.name = "Compressor capacity";
let series1toolTip = series1.bullets.push(new am4charts.CircleBullet());
series1toolTip.tooltipText = "{name} in {valueX}°C => {valueY}";
series1.tooltip.getFillFromObject = false;
series1.tooltip.background.fill = am4core.color("#b9a9e6");
series1.legendSettings.valueText = "{valueY}";
series1.visible = false;
series1.stroke = am4core.color("#b9a9e6");
let series2 = chart.series.push(new am4charts.LineSeries());
series2.cursorTooltipEnabled = true;
series2.showTooltipOn = 'hover';
series2.dataFields.valueY = "evapCoilCap";
// series2.dataFields.categoryX = "evapDegC"; // If X-Axis is Category Axis
series2.dataFields.valueX = "evapDegC"; // If X-Axis is Value Axis
series2.name = 'Evaporator coil capacity';
let series2toolTip = series2.bullets.push(new am4charts.CircleBullet());
series2toolTip.tooltipText = "{name} in {valueX}°C => {valueY}";
series2.tooltip.getFillFromObject = false;
series2.tooltip.background.fill = am4core.color("red");
series2.legendSettings.valueText = "{valueY}";
series2.stroke = am4core.color("red");
let series3 = chart.series.push(new am4charts.LineSeries());
series3.cursorTooltipEnabled = true;
series3.showTooltipOn = 'hover';
series3.dataFields.valueY = "evapCoilSensibleCap";
// series3.dataFields.categoryX = "evapDegC"; // If X-Axis is Category Axis
series3.dataFields.valueX = "evapDegC"; // If X-Axis is Value Axis
series3.name = 'Evaporator sensible cooling capacity ';
let series3toolTip = series3.bullets.push(new am4charts.CircleBullet());
series3toolTip.tooltipText = "{name} in {valueX}°C => {valueY}";
series3.tooltip.getFillFromObject = false;
series3.tooltip.background.fill = am4core.color("#13bb37");
series3.legendSettings.valueText = "{valueY}";
series3.stroke = am4core.color("#13bb37");
// Add chart cursor
chart.cursor = new am4charts.XYCursor();
chart.cursor.behavior = "zoomY";
In order to display multiple tooltips, you need to set tooltipText directly on series, not on a bullet.
series.tooltipText = "{name} in {valueX}°C => {valueY}";
That's the first step, though. Since you are using all-ValueAxis scenario, you will also need to apply a workaround as stated in this tutorial.
am4charts.ValueAxis.prototype.getSeriesDataItem = function(series, position) {
var key = this.axisFieldName + this.axisLetter;
var value = this.positionToValue(position);
var dataItem = series.dataItems.getIndex(series.dataItems.findClosestIndex(value, function(x) {
return x[key] ? x[key] : undefined;
}, "any"));
return dataItem;
}
This will enable multi-cursors across all charts.
Or if you want to enable for just for a single axis:
valueAxisX.getSeriesDataItem = function(series, position) {
var key = this.axisFieldName + this.axisLetter;
var value = this.positionToValue(position);
var dataItem = series.dataItems.getIndex(series.dataItems.findClosestIndex(value, function(x) {
return x[key] ? x[key] : undefined;
}, "any"));
return dataItem;
}
If you don't want to show all tooltips for all the series all the time, you can set cursor's maxTooltipDistance to a small number so that multiple tooltips are shown only if target items are closely packged together, e.g.:
chart.cursor.maxTooltipDistance = 10;

Color by point in ChartJS.Blazor

I'm using Chartjs.Blazor, and I haven't been able to do the same as described here : How to change the color of Chart.js points depending on the label
I've got a list of colors (rgba, or color name, I can choose) under the form of List<String>.
colors = ["rgba(255,0,0,1)", "rgba(0,255,0,1)", "rgba(0,0,255,1)", "rgba(255,0,0,1)", "rgba(0,255,0,1)"];
I tried to specify colors using the LineDataset.PointBackgroundColor property :
var _linebarDataSet = new ChartJs.Blazor.ChartJS.LineChart.LineDataset<ChartJs.Blazor.ChartJS.Common.Point>
{
Label = lineSet.Title,
Hidden = false,
Fill = false,
PointBackgroundColor = colors,
BorderWidth = 3,
PointBorderWidth = 0,
LineTension = 0,
PointRadius = 0,
};
for (int i = 0; i < lineSet.XAxisData.Count; i++)
{
_linebarDataSet.Add(new ChartJs.Blazor.ChartJS.Common.Point(i, lineSet.YAxisData[i]));
}
and tried to pass RGB values as in the example or colors name. It seems only the first definition is applied to all points.
I also tried to use javascript as :
await JSRuntime.InvokeAsync<string>("colorizePoints.HideOtherDatasetsFunc", valuesPoints, this.m_ValuesDataset.Colors);
and this code :
HideOtherDatasetsFunc: function (reference, colors, barchart) {
let colorsCode = []
for (var i = 0, len = colors.length; i < len; i++) {
colorsCode.push(colors[i]);
}
for (var i = 1; i <= reference.data.length - 1; i++) {
reference.pointBackgroundColor[i] = colorsCode[i];
}
}
And think Javascript like this would interfer with the Blazor server side rendering.
My problem using the javascript is to get the 2d context, as it's done in the link using :
var ctx = document.getElementById('lineChart').getContext('2d');
I can't set a fixed id as the CharJS, and retrieve it from javascript, because blazor components cannot stand id properties.
Has anybody an idea how to achieve this goal ?
Thank you for your reading-
This bug concerned 1.0 version.
The problem has been solved using IndexedOptions of the 2.0 version, which has just been released.

How to Add Image/Shape with chart data label in ASPOSE Slide

Can we add any shape/image with chart data labels in ASPOSE .I need to show one arrow with different colors according to certain values with each data labels in the chart. i am using ASPOSE to generate my ppt. Or there is any way to find the data label positions in ASPOSE.
I have observed your requirements and like to share that MS PowerPoint supports LineWithMarker chart that can display different predefined or custom marker symbols(in the form of image) for different series data points. Please try using following sample code for possible options using Aspose.Slides and MSO charts.
public static void TestScatter()
{
var location = System.Reflection.Assembly.GetExecutingAssembly().Location;
//Open a presentation
Presentation pres = new Presentation();
IChart chart = pres.Slides[0].Shapes.AddChart(ChartType.StackedLineWithMarkers, 10, 10, 400, 400);
//populating cycle
var serie = chart.ChartData.Series[0];
var wbk = chart.ChartData.ChartDataWorkbook;
chart.ChartData.Series.RemoveAt(1);
chart.ChartData.Series.RemoveAt(1);
serie.Marker.Format.Fill.FillType = FillType.Picture;
serie.Marker.Size = 20;
// Set the picture
System.Drawing.Image img = (System.Drawing.Image)new Bitmap(#"C:\Users\Public\Pictures\Sample Pictures\Tulips.jpg");
IPPImage imgx = pres.Images.AddImage(img);
serie.Marker.Format.Fill.PictureFillFormat.Picture.Image = imgx;
//For individual data point
serie.DataPoints[0].Marker.Format.Fill.FillType = FillType.Solid;
serie.DataPoints[0].Marker.Format.Fill.SolidFillColor.Color = Color.Red;
serie.DataPoints[0].Marker.Size = 20;
serie.DataPoints[0].Marker.Symbol = MarkerStyleType.Triangle;
serie.DataPoints[0].Label.DataLabelFormat.ShowValue = true;
serie.DataPoints[1].Label.DataLabelFormat.ShowValue = true;
serie.DataPoints[2].Label.DataLabelFormat.ShowValue = true;
serie.DataPoints[3].Label.DataLabelFormat.ShowValue = true;
pres.Save(Path.Combine(Path.GetDirectoryName(location), "Result2.pptx"), SaveFormat.Pptx);
}
I am working as Support developer/ Evangelist at Aspose.
Many Thanks,
I have further observed your requirements and have observed that you have also posted the similar requirements in Aspose.Slides official support forum as well. Please try using following sample code on your end to serve the purpose.
public static void TestLineChart()
{
var location = System.Reflection.Assembly.GetExecutingAssembly().Location;
//Open a presentation
Presentation pres = new Presentation();
IChart chart = pres.Slides[0].Shapes.AddChart(ChartType.StackedLineWithMarkers, 10, 10, 400, 400);
//populating cycle
var serie = chart.ChartData.Series[0];
var wbk = chart.ChartData.ChartDataWorkbook;
chart.ChartData.Series.RemoveAt(1);
chart.ChartData.Series.RemoveAt(1);
serie.Marker.Format.Fill.FillType = FillType.Picture;
serie.Marker.Size = 20;
serie.Marker.Symbol = MarkerStyleType.Diamond;
serie.Marker.Format.Fill.FillType = FillType.Solid;
serie.Marker.Format.Fill.SolidFillColor.Color=Color.Orange;
serie.Marker.Format.Line.FillFormat.FillType = FillType.Solid;
serie.Marker.Format.Line.FillFormat.SolidFillColor.Color=Color.Red;
serie.Marker.Format.Line.Width=1.0F;
serie.Format.Line.Width = 3.0f;
serie.Format.Line.FillFormat.FillType=FillType.Solid;
serie.Format.Line.FillFormat.SolidFillColor.Color = Color.FromArgb(209,225,91) ;
for(int i=0;i<serie.DataPoints.Count;i++)
{
serie.DataPoints[i].Label.DataLabelFormat.ShowValue = true;
IDataLabel label=serie.Labels[i];
chart.ValidateChartLayout();
IAutoShape ashp=chart.UserShapes.Shapes.AddAutoShape(ShapeType.Triangle,chart.X + label.ActualX + 5, chart.Y + label.ActualY + 5, 20,20);
ashp.FillFormat.FillType = FillType.Solid;
ashp.LineFormat.FillFormat.FillType = FillType.NoFill;
if (i % 2 == 0)//even data points
{
ashp.FillFormat.SolidFillColor.Color = Color.Green;
}
else
{
ashp.Rotation = 180;
ashp.FillFormat.SolidFillColor.Color = Color.Red;
}
}
pres.Save(Path.Combine(Path.GetDirectoryName(location), "Result2.pptx"), Aspose.Slides.Export.SaveFormat.Pptx);
}
I am working as Support developer/ Evangelist at Aspose.
Many Thanks,

Get 3d object boundaries

How do applications figure out the boundaries (just a box) of a 3d object?
Here's an example
I need this info for collision detection.
This is how you can compute the minimum and maximum (bounding box) of a 3D object.
void BBox(GLpoint *p, int n_vert, GLpoint& p_max, GLpoint& p_min)
{
p_min.x = p[0].x;
p_min.y = p[0].y;
p_min.z = p[0].z;
p_max.x = p[0].x;
p_max.y = p[0].y;
p_max.z = p[0].z;
for (int i=1; i<n_vert; i++)
{
p_min.x = MIN(p_min.x, p[i].x);
p_min.y = MIN(p_min.y, p[i].y);
p_min.z = MIN(p_min.z, p[i].z);
p_max.x = MAX(p_max.x, p[i].x);
p_max.y = MAX(p_max.y, p[i].y);
p_max.z = MAX(p_max.z, p[i].z);
}
}