Code: Select all
values[0] = new BarSeriesValue3D(0, 50f + 50f * Math.Sin(m_dX), 0, "");
m_dX += 0.025f;
Thank you.
Moderator: Queue Moderators
Code: Select all
values[0] = new BarSeriesValue3D(0, 50f + 50f * Math.Sin(m_dX), 0, "");
m_dX += 0.025f;
Code: Select all
//Add a bar series with one random value
BarSeries3D barSeries = new BarSeries3D(chart.View3D, Axis3DBinding.Primary, Axis3DBinding.Primary, Axis3DBinding.Primary);
barSeries.Material.DiffuseColor = Colors.Lime;
barSeries.BarWidth = 10;
barSeries.Shape = BarShape3D.RoundedCylinder;
BarSeriesValue3D[] values = new BarSeriesValue3D[1];
Random rand = new Random();
values[0] = new BarSeriesValue3D(50, rand.NextDouble() * -140.0, 50, "random value");
barSeries.Values = values;
chart.View3D.BarSeries3D.Add(barSeries);
//Set proper Y axis range
chart.View3D.YAxisPrimary3D.SetRange(-140, 0);
Code: Select all
void AddGradientBarMesh(double xMin, double xMax, double yMin, double yMax, double zMin, double zMax, bool colorful)
{
SurfaceMeshSeries3D barMesh = new SurfaceMeshSeries3D(m_chart.View3D, Axis3DBinding.Primary, Axis3DBinding.Primary, Axis3DBinding.Primary);
SurfacePoint[,] data = new SurfacePoint[4,5];
Color c = Color.Aqua; //set any color because it's not used
data[0, 0] = new SurfacePoint(xMax, yMax, zMin, c);
data[0, 1] = new SurfacePoint(xMin, yMax, zMin, c);
data[0, 2] = new SurfacePoint(xMin, yMax, zMax, c);
data[0, 3] = new SurfacePoint(xMin, yMin, zMax, c);
data[0, 4] = new SurfacePoint(xMin, yMin, zMin, c);
data[1, 0] = new SurfacePoint(xMin, yMin, zMax, c);
data[1, 1] = new SurfacePoint(xMin, yMax, zMax, c);
data[1, 2] = new SurfacePoint(xMin, yMax, zMin, c);
data[1, 3] = new SurfacePoint(xMin, yMin, zMin, c);
data[1, 4] = new SurfacePoint(xMin, yMin, zMax, c);
data[2, 0] = new SurfacePoint(xMax, yMin, zMax, c);
data[2, 1] = new SurfacePoint(xMax, yMax, zMax, c);
data[2, 2] = new SurfacePoint(xMax, yMax, zMin, c);
data[2, 3] = new SurfacePoint(xMax, yMin, zMin, c);
data[2, 4] = new SurfacePoint(xMax, yMin, zMax, c);
data[3, 0] = new SurfacePoint(xMin, yMax, zMin, c);
data[3, 1] = new SurfacePoint(xMax, yMax, zMin, c);
data[3, 2] = new SurfacePoint(xMax, yMax, zMax, c);
data[3, 3] = new SurfacePoint(xMax, yMin, zMax, c);
data[3, 4] = new SurfacePoint(xMax, yMin, zMin, c);
barMesh.Data = data;
barMesh.WireframeType = SurfaceWireframeType.None;
barMesh.ContourLineType = ContourLineType.None;
barMesh.LightedSurface = LightedSurfaceSide.Bottom;
barMesh.ColorSaturation = 90;
barMesh.Title.ShowInLegendBox = false;
if (colorful)
{
barMesh.ContourPalette = CreateColorfulPalette(barMesh, yMin, yMax);
}
else
{
barMesh.ContourPalette = CreateGrayscalePalette(barMesh, yMin, yMax);
}
m_chart.View3D.SurfaceMeshSeries3D.Add(barMesh);
}
ValueRangePalette CreateColorfulPalette(SeriesBase3D ownerSeries, double yMin, double yMax)
{
ValueRangePalette palette = new ValueRangePalette(ownerSeries);
palette.Steps.Clear();
palette.MinValue = yMin;
palette.Type = PaletteType.Gradient;
palette.Steps.Add(new PaletteStep(palette, Color.Blue, yMin));
palette.Steps.Add(new PaletteStep(palette, Color.Lime, yMin + 30.0 * (yMax - yMin) / 100.0));
palette.Steps.Add(new PaletteStep(palette, Color.Yellow, yMin + 60.0 * (yMax - yMin) / 100.0));
palette.Steps.Add(new PaletteStep(palette, Color.Red, yMin + 100.0 * (yMax - yMin) / 100.0));
return palette;
}
ValueRangePalette CreateGrayscalePalette(SeriesBase3D ownerSeries, double yMin, double yMax)
{
ValueRangePalette palette = new ValueRangePalette(ownerSeries);
palette.Steps.Clear();
palette.MinValue = yMin;
palette.Type = PaletteType.Gradient;
palette.Steps.Add(new PaletteStep(palette, Color.Black, yMin));
palette.Steps.Add(new PaletteStep(palette, Color.White, yMin + 100.0 * (yMax - yMin) / 100.0));
return palette;
}
Code: Select all
AddGradientBarMesh(40, 60, 0, 100, 40, 60, true);
AddGradientBarMesh(70, 80, 10, 90, 30, 40, false);
Code: Select all
barMesh.Data = data;
Code: Select all
m_chart.View3D.YAxisPrimary3D.SetRange(-100, 0); -> The bottom of the chart will be -100, top chart will be 0
m_chart.View3D.YAxisPrimary3D.SetRange(0, -100); -> The bottom of the chart will be -100, top chart will be 0
m_chart.View3D.YAxisPrimary3D.SetRange(100, 0); -> The bottom of the chart will be 0, top chart will be 100
m_chart.View3D.YAxisPrimary3D.SetRange(0, 100); -> The bottom of the chart will be 0, top chart will be 100
Code: Select all
//Chart
private LightningChartUltimate m_chart = null;
//Bar count in X dimension
private int m_iColumnCount;
//Bar count in Z dimension
private int m_iRowCount;
const double XRangeMin = 0;
const double XRangeMax = 500;
const double YRangeMin = 0;
const double YRangeMax = 1000;
const double ZRangeMin = 0;
const double ZRangeMax = 30;
Random m_rand = new Random();
//Bars array. One SurfaceMeshSeries3D for each bar.
private SurfaceMeshSeries3D[,] m_bars;
private double[,] m_barYValues;
/// <summary>
/// Create chart.
/// </summary>
private void CreateChart()
{
//Create new chart
m_chart = new LightningChartUltimate(LicenseKeys.LicenseKeyStrings.LightningChartUltimate);
//Disable rendering, strongly recommended before updating chart properties
m_chart.BeginUpdate();
//Set 3D as active view
m_chart.ActiveView = ActiveView.View3D;
//Chart parent must be set
m_chart.Parent = splitContainer1.Panel1;
//Fill parent area with chart
m_chart.Dock = DockStyle.Fill;
//Chart name
m_chart.Name = "Gradient bars chart";
m_chart.View3D.XAxisPrimary3D.SetRange(XRangeMin, XRangeMax);
m_chart.View3D.YAxisPrimary3D.SetRange(YRangeMin, YRangeMax);
m_chart.View3D.ZAxisPrimary3D.SetRange(ZRangeMin, ZRangeMax);
m_chart.View3D.Dimensions.X = 150;
m_chart.View3D.Dimensions.Z = 215;
m_chart.View3D.Camera.RotationX = 40;
m_chart.View3D.Camera.ViewDistance = 300;
m_chart.View3D.Camera.Target.X = -15;
m_chart.View3D.Camera.Target.Y = -40;
//Allow chart rendering
m_chart.EndUpdate();
}
/// <summary>
/// Set column and row count of bars
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonApplyNewSize_Click(object sender, EventArgs e)
{
m_iColumnCount = (int)numericUpDownColumns.Value;
m_iRowCount = (int)numericUpDownRows.Value;
m_chart.BeginUpdate();
//Get rid of old bars
m_chart.View3D.SurfaceMeshSeries3D.Clear();
//Create array for bars
m_bars = new SurfaceMeshSeries3D[m_iColumnCount, m_iRowCount];
//Create array for Y values
m_barYValues = new double[m_iColumnCount, m_iRowCount];
for (int iCol = 0; iCol < m_iColumnCount; iCol++)
{
for (int iRow = 0; iRow < m_iRowCount; iRow++)
{
SurfaceMeshSeries3D bar = new SurfaceMeshSeries3D(m_chart.View3D, Axis3DBinding.Primary, Axis3DBinding.Primary, Axis3DBinding.Primary);
bar.ContourLineType = ContourLineType.None;
bar.ColorSaturation = 80;
bar.WireframeType = SurfaceWireframeType.None;
bar.ContourPalette = CreatePalette(bar, YRangeMin, YRangeMax);
bar.LightedSurface = LightedSurfaceSide.Bottom;
bar.SmoothShading = false; //correct lights
m_chart.View3D.SurfaceMeshSeries3D.Add(bar);
m_bars[iCol, iRow] = bar;
m_barYValues[iCol, iRow] = RandomizeValue();
//Only show first bar's palette in the legend box.
if (iCol == 0 && iRow == 0)
{
bar.Title.ShowInLegendBox = true;
bar.Title.Text = "Bar value";
}
else
bar.Title.ShowInLegendBox = false;
}
}
m_chart.EndUpdate();
}
/// <summary>
/// Create surface mesh data from given bar coordinates
/// </summary>
/// <param name="xMin">X minimum</param>
/// <param name="xMax">X maximum</param>
/// <param name="yMin">Y minimum</param>
/// <param name="yMax">Y maximum</param>
/// <param name="zMin">Z minimum</param>
/// <param name="zMax">Z maximum</param>
/// <returns>Surface mesh data</returns>
SurfacePoint[,] CreateBarMeshData(double xMin, double xMax, double yMin, double yMax, double zMin, double zMax)
{
SurfacePoint[,] aMeshPoints = new SurfacePoint[4, 5];
Color c = Color.Aqua; //set any color because it's not used
aMeshPoints[0, 0] = new SurfacePoint(xMin, yMax, zMin, c);
aMeshPoints[0, 1] = new SurfacePoint(xMin, yMax, zMax, c);
aMeshPoints[0, 2] = new SurfacePoint(xMin, yMin, zMax, c);
aMeshPoints[0, 3] = new SurfacePoint(xMin, yMin, zMin, c);
aMeshPoints[0, 4] = new SurfacePoint(xMin, yMax, zMax, c);
aMeshPoints[1, 0] = new SurfacePoint(xMin, yMax, zMax, c);
aMeshPoints[1, 1] = new SurfacePoint(xMin, yMax, zMin, c);
aMeshPoints[1, 2] = new SurfacePoint(xMin, yMin, zMin, c);
aMeshPoints[1, 3] = new SurfacePoint(xMin, yMin, zMax, c);
aMeshPoints[1, 4] = new SurfacePoint(xMin, yMax, zMax, c);
aMeshPoints[2, 0] = new SurfacePoint(xMax, yMax, zMax, c);
aMeshPoints[2, 1] = new SurfacePoint(xMax, yMax, zMin, c);
aMeshPoints[2, 2] = new SurfacePoint(xMax, yMin, zMin, c);
aMeshPoints[2, 3] = new SurfacePoint(xMax, yMin, zMax, c);
aMeshPoints[2, 4] = new SurfacePoint(xMax, yMax, zMax, c);
aMeshPoints[3, 0] = new SurfacePoint(xMax, yMax, zMin, c);
aMeshPoints[3, 1] = new SurfacePoint(xMax, yMax, zMax, c);
aMeshPoints[3, 2] = new SurfacePoint(xMax, yMin, zMax, c);
aMeshPoints[3, 3] = new SurfacePoint(xMax, yMin, zMin, c);
aMeshPoints[3, 4] = new SurfacePoint(xMax, yMax, zMax, c);
return aMeshPoints;
}
/// <summary>
/// Create a palette for a bar
/// </summary>
/// <param name="ownerSeries">Owner series</param>
/// <param name="yMin">Y minimum</param>
/// <param name="yMax">Y maximum</param>
/// <returns>Palette containing values equivalent colors</returns>
ValueRangePalette CreatePalette(SeriesBase3D ownerSeries, double yMin, double yMax)
{
ValueRangePalette palette = new ValueRangePalette(ownerSeries);
palette.Steps.Clear();
palette.MinValue = yMin;
palette.Type = PaletteType.Gradient;
palette.Steps.Add(new PaletteStep(palette, Color.Blue, yMin));
palette.Steps.Add(new PaletteStep(palette, Color.Lime, yMin + 30.0 * (yMax - yMin) / 100.0));
palette.Steps.Add(new PaletteStep(palette, Color.Yellow, yMin + 60.0 * (yMax - yMin) / 100.0));
palette.Steps.Add(new PaletteStep(palette, Color.Red, yMin + 100.0 * (yMax - yMin) / 100.0));
return palette;
}
/// <summary>
/// Generate new data
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void timerDataUpdater_Tick(object sender, EventArgs e)
{
//Generate new data for bars, and update bar meshes
m_chart.BeginUpdate();
//Move old data one row towards Z max
for (int iRow = m_iRowCount - 1; iRow > 0; iRow--)
{
for (int iCol = 0; iCol < m_iColumnCount; iCol++)
{
m_barYValues[iCol, iRow] = m_barYValues[iCol, iRow-1];
}
}
//Set new random data for last row
for (int iCol = 0; iCol < m_iColumnCount; iCol++)
{
m_barYValues[iCol, 0] = RandomizeValue();
}
//Bar spacing and margins
double dBarMinY, dBarMaxY, dBarMinX, dBarMaxX, dBarMinZ, dBarMaxZ;
double dBarSizeX = (XRangeMax - XRangeMin)/(double)m_iColumnCount;
double dBarMarginX = dBarSizeX * 0.2;
double dBarSizeZ = (ZRangeMax - ZRangeMin)/(double)m_iRowCount;
double dBarMarginZ = dBarSizeZ * 0.2;
for (int iCol = 0; iCol < m_iColumnCount; iCol++)
{
dBarMinX = XRangeMin + (double)iCol * dBarSizeX;
dBarMaxX = dBarMinX + dBarSizeX;
for (int iRow = 0; iRow < m_iRowCount; iRow++)
{
dBarMinZ = ZRangeMin + (double)iRow * dBarSizeZ;
dBarMaxZ = dBarMinZ + dBarSizeZ;
dBarMinY = 0;
dBarMaxY = m_barYValues[iCol, iRow];
//Create bar mesh data from given X, Y, Z values
m_bars[iCol, iRow].Data = CreateBarMeshData(dBarMinX + dBarMarginX, dBarMaxX - dBarMarginX,
dBarMinY, dBarMaxY, dBarMinZ + dBarMarginZ, dBarMaxZ - dBarMarginZ);
}
}
m_chart.EndUpdate();
}
/// <summary>
/// Randomize a value
/// </summary>
/// <returns>Random value</returns>
double RandomizeValue()
{
return (YRangeMax - YRangeMin) / 2.0 + m_rand.NextDouble() * (YRangeMax - YRangeMin) / 2.0;
}
pct wrote:In the meanwhile,
I added a LineSeriesCursors to a ViewXY, I can click on the cursor and move it.
I wanted to do the same thing in a PointLineSeries3D , but I cannot click directly on PointLineSeries3D , I just click on the chart, it does not seem possible.