SciChart: ColumnChart - DataSeries.Append - scichart

A potential problem I noticed in SciChart for WPF
take the standard example for ColumnChart from SDK (2D Charts - Column Chart)
build and run; the result is as below:
make the following code changes (see (1) and (2))
private void ColumnChartExampleViewOnLoaded(object sender, RoutedEventArgs e)
{
var dataSeries = new XyDataSeries<double, double> {SeriesName = "Histogram"};
var yValues = new double[] { 0.1, 0.2, 0.4, 0.8, 1.1, 1.5, 2.4, 4.6, 8.1, 11.7, 14.4, 16.0, 13.7, 10.1, 6.4, 3.5, 2.5, 1.4, 0.4, 0.1};
using (this.sciChart.SuspendUpdates())
{
for (int i = 0; i < yValues.Length; i++)
{
// DataSeries for appending data
dataSeries.Append(i, yValues[i]);
}
this.columnSeries.DataSeries = dataSeries;
this.columnSeries.DataSeries.AcceptsUnsortedData = true; //(1)
}
dataSeries.Append(0, 1); //(2)
this.sciChart.ZoomExtents();
}
and here is the result:
I.e. if I use Append method for the X val which already exists - the UI bars are changing to the lines.
I do not know if it is expected behavior or not but for my case I'm updating the Histogram on fly and quite often same X value is having new Y value(s).
As a result - the UI behavior confuses...
I found workaround for my case (I'm using the Update method since X and index is the same for my case) so this is just a notice.
I'm not sure will you change the behavior or not - just sharing my experience for now...

SciChart's column series automatically calculates the width of the data-points based on the columns you have available.
If you have columns 0,1,2,3,4,5,6,7,8,9 ...then add a new column at position 0, this calculation goes haywire.
Ways of avoiding this side-effect are:
Update items rather than append new columns with overlapping values
Override column width calculation using the properties FastColumnRenderableSeries.UseUniformWidth and FastColumnRenderableSeries.DataPointWidth
(Advanced) Override column width calculation by overriding GetDataPointWidth() method.
Find out more how the Column series works at the SciChart WPF Documentation page.

Related

SciChart - ColumnRenderableSeries3D column diameter

I am trying to implement a chart with a ColumnRenderableSeries3D series, but with a small amount of data points (25x25) the columns are nearly invisible. At higher numbers of data points (100x100) with a wider range of values this problem becomes even worse and a Moiré pattern appears. What can be done to significantly increase the column's diameter, so they are easily seen and so the Moiré pattern disappears?
If it is relevant this is being rendered on a VM with a VMware ESXi 6.5 SVGA adapter on Windows Server 2016, over a RemoteDesktop connection. Surprisingly even though 3D support isnt enabled for the VM, SciChart.Examples.Demo.exe says DirectX hardware acceleration is enabled. The version of SciChart is 5.1.0.11405 and SharpDX is 4.0.1.
SciChart3DSurface SciChartSurface3d = new SciChart3DSurface();
XyzDataSeries3D<Double, Double, DateTime> MyXyzDataSeries = new XyzDataSeries3D<Double, Double, DateTime>();
SciChartSurface3d.XAxis = new NumericAxis3D();
SciChartSurface3d.YAxis = new NumericAxis3D();
SciChartSurface3d.ZAxis = new DateTimeAxis3D();
SciChartSurface3d.Camera = new Camera3D() { ZoomToFitOnAttach = true };
SciChartSurface3d.WorldDimensions = new Vector3(200, 100, 200);
SciChartSurface3d.RenderableSeries.Add(new ColumnRenderableSeries3D() { DataSeries= MyXyzDataSeries, ColumnShape = typeof(CubePointMarker3D), DataPointWidthX = 1.0, Opacity = 1.0 });
SciChartSurface3d.BorderThickness = new Thickness(0);`
SomeMethodToLoadTheDataSeries();
25x25
100x100
Edit
Changing DataPointWidthX to DataPointWidth doesn't help. With a width of 1.0:
There are two modes of the column width definition:
First and the default is called MaxNonOverlapping. In this mode, the maximum possible width is calculated where any column has enough space not to overlap others.
Second is called FixedSize. In this mode, the width of a column is defined by a value from the ColumnRenderableSeries3D.CoulmnFixedSize property.
Definition of the mode is performed over the ColumnRenderableSeries3D.ColumnSpacingMode property. Below is the example how to setup fixed size column chart:
var renderableSeries3D = new ColumnRenderableSeries3D();
renderableSeries3D.ColumnSpacingMode = ColumnSpacingMode.FixedSize;
renderableSeries3D.CoulmnFixedSize = 25;
Note, a value of the CoulmnFixedSize property represents coordinates space. Thus it is related to the SciChart3DSurface.WorldDimensions. You can find more information about the coordinates space here.

Node generation from json data for force layout

I'm trying to do a bubble chart similar to Mike Bostock's:
However, instead of randomly generating the nodes, I want them to be generated for a json. Suppose I have a dataset variable that is a valid JSON how do I generate a nodes variable from this that can be used for the force layout.
Mike's implementation (for randomly-generated circles) is:
var nodes = d3.range(n).map(function() {
var i = Math.floor(Math.random() * m),
v = (i + 1) / m * -Math.log(Math.random());
return {
radius: radius(v),
color: color(i),
cx: x(i),
cy: height / 2
};
});
Let's suppose my dataset JSON is something like:
{"nodes":[{"name": "node_name", "size": 18}, ... ]}
And I want the radius of each circle to be the size of each object in the JSON array.
nodes is an array of objects which each have radius, color, cx and cy attributes. All you need to do is create such an array from your data. How exactly to do this will depend on your data. Note that you don't need to create all the attributes -- if all the nodes can have the same color for example, you don't need to add the corresponding attribute (but also need to change the code that actually sets the color later on).

Swing JTable - Unable to repaint and change background of cells

Hy everyone,
I'm trying to do some calculations in a JTable after iteration and mark with different background the cells that I need.
However, I have 2 problems at the moment:
1) Cells are not painted immediately, but after the whole iteration cycle
2) Areas are not painted properly - if I need to paint table[3, 4] and table[6, 5] it draws a rectangular from [3,4] up to [6, 5] instead of drawing the singular cells only.
About problem 1: could I call repaint() with priority without the need to finish everything and the JVM to decide whenever to paint? I try to do fireTableCellUpdated() and fireTableDataChanged() but they don't get updated.
Here there is my custom cell renderer method that changes the BGcolor:
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row,int column) {
Component renderer = super.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
if(value instanceof Color) {
Color c = (Color) value;
renderer.setBackground(c);
System.out.println("BG change [" + row + ":" + column + "]");
}
return renderer;
}
Here there is the loop where I paint my cells on a button click:
for(int paintJ = startIndex; paintJ < endIndex; paintJ++) {
CrossCellRenderer rend = (CrossCellRenderer) jTable1.getCellRenderer(i, paintJ)
.getTableCellRendererComponent(jTable1, Color.blue, true, true, i, paintJ);
crossTableModel.fireTableCellUpdated(i, paintJ);
jTable1.revalidate();
jTable1.repaint();
try {
Thread.sleep(1000);
} catch(InterruptedException ie) {
System.err.println("Exception sleeping the thread.");
}
}
Any tips on that?
Hate to say: but you do it (whatever you want to reach) completely wrong ;-)
Never-ever do any direct manipulation/paint on a renderer, instead change the model data and the rest will happen automatically.
Never-ever call any of the fireXX methods on a model from outside the model, it's the exclusive responsibility of the model to notify
its listeners on change
Never-ever (or very very rarely, certainly not here ;-) there's a need to call revalidate and/or repaint dircectly, will happen
automatically if a model is well-behaved
....
Best to read Snoracle's tutorial on howto-use tables to fully understand the rendering mechanism
http://download.oracle.com/javase/tutorial/uiswing/components/table.html
Roughly:
// change the model, will notify its listeners
model.setValueAt(....)
// in a custom renderer, check the value and decorate as appropriate
public Component getTableCellRendererComponent(....) {
// ... normal config, f.i. done in super
Component comp = super.get...
if (myConditionForSpecialColor(table, value, ...) {
comp.setBackground(myColor);
} else {
comp.setBackground(normalColor);
}
}
// register the custom renderer
// per class
table.setDefaultRenderer(Object.class, myRenderer)
// or per column
table.getColumnModel().getColumn(myColumn).setCellRenderer(myRenderer)

ActionScript - Setter Parameters Within Constructor?

i've designed a custom class (or component?) that extends Sprite whose constructor has 15 parameters. only the first parameter is required, while the remaining 14 have default values assigned. all are necessary.
each of the parameters, except for the first required parameter are actually property setters. the class also contains public setter and getter functions, allowing for property changes at runtime after construction.
i've written the class on my desktop (27" screen) and realized i may have a problem when i was using the class on my 13" laptop - the code hinting was extending past the edges of the screen as it was too long.
is it normal/best practice to include optional setters as parameters in the constructor when setter functions are available, or should setters always be separate from the constructor?
In my opinion it comes down to ease of use at the class instantiating part of the code.
If you have 14 parameters that you either all set or all skip then it's probably the best solution.
var defaultRectangle:Rectangle = new Rectangle(); //square of 1 x 1)
var customRectangle:Rectangle = new Rectangle(0,0, 2,0 2,2, 0,2);
But if some of the 14 parameters are optional, it becomes a bit hard to read, then I think either the use of separate getter/setters is more readable, or a paramater object (mimicking named parameters)
//which parameter means what?
var girlfriend:Girl = new Girl("Blue", 0, 0, "", "", 1.8, 0, "", 140);
//named parameters
var girlfriend:Girl = new Girl({eyeColor: "Blue", height:1.8, iq:140});
//setters
var girlfriend:Girl = new Girl();
girlfriend.eyeColor = "Blue";
girlfriend.height = 1.8;
girlfriend.iq = 140;
I personally try to use Models as much as possible when working with "Views"
So if your object is a Sprite and thus a View. Maybe the best approach could be:
var friend:Person = new Person({name: "Ford Prefect"});
var profileView:ProfileView = new ProfileView(friend);
addChild(profileView);

swing: JSlider but with coarse/fine controls?

I have a JSlider with 65536 different values. It works great for coarse adjustments and for very fine adjustments (+/-1 using up/down arrow) but is very poor in the middle.
Is there anything out there that would be better? I can vaguely imagine taking 2 sliders one for coarse + fine adjustments, but can't really figure out how to get them to work together.
What about using a JSpinner instead of a JSlider? With a SpinnerNumberModel, you can set the step size and even change the step size dynamically.
If you're OK with having multiple controls, you could even have two spinners, one for setting your values and another for setting the step size that is used by the first spinner.
For an example of this, I took the SliderDemo code from the Swing slider tutorial and modified it instead to use two JSpinners instead of a single JSlider. Here's the most interesting part of the code that I changed:
//Create the slider^H^H^H^H^H^H spinners.
// JSlider framesPerSecond = new JSlider(JSlider.HORIZONTAL,
// FPS_MIN, FPS_MAX, FPS_INIT);
final int initStep = 1;
final SpinnerNumberModel animationModel = new SpinnerNumberModel(FPS_INIT,
FPS_MIN,
FPS_MAX,
initStep);
final SpinnerNumberModel stepSizeModel = new SpinnerNumberModel(initStep,
1,
10,
1);
final JSpinner framesSpinner = new JSpinner(animationModel);
framesSpinner.addChangeListener(this);
final JSpinner stepSpinner = new JSpinner(stepSizeModel);
stepSpinner.addChangeListener(new ChangeListener()
{
public void stateChanged(ChangeEvent arg0)
{
animationModel.setStepSize(stepSizeModel.getNumber());
}
});
I also had to make a bunch of less interesting changes, such as creating a label for the step size spinner, adding the new label and new spinner to the container, and changing the stateChanged() method on this to cast the source of the event to a JSpinner instead of casting it to a JSlider.
You could, of course, elaborate on this further, such as increasing the step size for the step size spinner (for example, so that you can change the step size from 1 to 101 in a single click). You could also use a different control instead of a JSpinner to set the step size, such as a combo box.
Finally, to make this all really easy to use, you would likely want to hook up some keystroke accelerators (possibly through a menu?) so that you could change the step size without actually moving the mouse or the keyboard focus from one spinner to another.
Edit: Given that you have to use a JSlider no matter what, are you aware that you can use PgUp/PgDn to move up and down by 1/10th of the total range?
If you want to change that 1/10th amount (such as making it dynamic), then you'll need to override the the method BasicSliderUI.scrollByBlock().
Here's an example where I just overrode the UI class of a JSlider to step by 1/4th of the range, instead of 1/10th:
//Create the slider.
JSlider framesPerSecond = new JSlider(JSlider.HORIZONTAL,
FPS_MIN, FPS_MAX, FPS_INIT);
framesPerSecond.setUI(new javax.swing.plaf.metal.MetalSliderUI() {
private static final int SLIDER_FRACTION = 4;
/**
* This code is cut, paste, and modified from
* {#link javax.swing.plaf.basic.BasicSliderUI#scrollByBlock(int).
* I should be ashamed of cutting and pasting, but whoever hardcoded the magic
* number "10" in the original code should be more ashamed than me. ;-)
*
* #param direction
* either +1 or -1
*/
#Override
public void scrollByBlock(final int direction) {
synchronized(slider) {
int oldValue = slider.getValue();
int blockIncrement = (slider.getMaximum() - slider.getMinimum()) / SLIDER_FRACTION;
if (blockIncrement <= 0 && slider.getMaximum() > slider.getMinimum()) {
blockIncrement = 1;
}
int delta = blockIncrement * ((direction > 0) ? POSITIVE_SCROLL : NEGATIVE_SCROLL);
slider.setValue(oldValue + delta);
}
}
});
From here, it wouldn't be too hard to replace that constant SLIDER_FRACTION with a variable that was set by another slider or by a spinner, would it?