mpandroidchart, don't draw the line when there is not data for a period of time - mpandroidchart

mpandroidchart, I am reading data from a tool every second and I am drawing that data well, but when I turn off the tool a couple of minutes and again I turn the tool on, the chart draws a consecutive line instead of leaving a space before to start again to draw the values, How can I do that using this library?
I would like to have something like the second image

I think you can't do that all you can do is when stop the data you can insert few entries with 0 value on y-axis and when resume chart will start plotting values again but you can see two lines from the last value to zero and from 0 to the next value obtained.

I finally got to draw the line Data Set as I needed,
this library is awesome, it has a bunch of functionalities.
I saw this video https://www.youtube.com/watch?v=mA3-cz8EGWo and then I realized
I can change the line color between two dots by using .setColor(List colors), so I used a map with key = data set Index and value = array of colors for that dataset, and then I just changed to transparent color where I needed
Map<Integer, List<Integer>> colorsByDataSet = new HashMap<>();
save the color every time you create an entry
addNewEntry(x,y,color,1); //1 = dataset1
if (colorsByDataSet.containsKey(1)) {
List<Integer> colors = colorsByDataSet.get(1);
colors.add(color);
colorsByDataSet.put(1, colors);
} else {
List<Integer> colors = new ArrayList<>();
colors.add(color);
colorsByDataSet.put(1, colors);
}
//identify the position where you need to change the color and then update the List<Integer>
List<Integer> colors = colorsByDataSet.get(1);
colors.set(colors.size() - 1, Color.TRANSPARENT);
colorsByDataSet.put(i, colors);
//set the new colors
((LineDataSet) set).setColors(colorsByDataSet.get(1));
this the final result
if you know about a better way I am open to hear

Related

mpandroidchart the dot's color doesn't change in scatter chart

I'm using MPandroidchart to draw scatter chart.
I want to make a scatter chart that has a base line.
If value over the base line, in my case 0.2, its color change to red.
If not, it color is blue.
This is the codes i did.
if (d>=0.5)
{
colors.add(getBaseContext().getResources().getColor(R.color.color_red));
} else
{
colors.add(getBaseContext().getResources().getColor(R.color.color_blue));
}
value1.add(new Entry(k,d));
But it didn't change dot's color, but change squre's color next to label
I have tried
1)
if(index == specificIndex) colors.add(Color);
else colors.add(NormalColor);
2)
ArrayList<Integer> color = new ArrayList<>();
if (YOUR_CONDITION) {
color.add(ColorTemplate.rgb("#f8bf94"));
yVals1.add(new Entry(VALUE, COUNTER));
} else {
color.add(ColorTemplate.rgb("#e0e0e0"));
yVals1.add(new Entry(VALUE, COUNTER));
}
set1.setColors(color);
3)
color.add(Color.RED);
color.add(context.getResources().getColor(R.color.your_defined_color_in_colors_xml));
dataSet.setCircleColors(color);
But it didn't work.
How can i solve this?
After spending hours with this same issue, I have realized that it is the result of a bug in the MPAndroidChart project.
Basically, in the ScatterChartRenderer, the colors array is being treated such that only even colors are being applied to data points. For each Entry i, the color is set to colors[i / 2] meaning that the same color will be applied to two different entries due to integer division. This results in only half of the colors array being used.
To resolve this issue quickly, my solution was to add each entry to the DataSet twice. This means two points are drawn on top of each other, but both have the proper color set.
I am submitting a pull request to hopefully fix this issue in the next release, but for now this quick hack should work.

Photoshop CC eye dropper tool script

I have a batch action to place a pure white background behind an image. I want to be able to select the color from a fixed pixel position on each photo. When I record the eye dropper in actions it only records the color i picked, not the action of picking the color. I have looked into scripting and tried various solutions on the web.
This is the script I have tried:
var docRef = app.activeDocument;
var pixelLoc = [32,42];
var colorSamplerRef = docRef.colorSamplers.add(pixelLoc);
app.foregroundColor = colorSamplerRef.color;
It doesn't perform the action I need though. Which is select - > color range -> eye dropper tool on fixed position
To achieve this you can create a custom function which invokes the Color Range generated selection, (named selectColorRange in the example gist below).
The selectColorRange function utilizes new ActionDescripter() to configure the properties, which are akin to the settings options shown in the dialog box when you manually choose Select -> Color Range from the Menu bar. This function is invoked after adding the colorSampler at a given x/y coordinate as follows:
selectColorRange(sampledColor, 80); // <-- Specify the fuzziness as required.
Note how we pass in the previous sampledColor value, and a fuzziness value of 80, (which is the default value used in Photoshop).
Example gist:
var docRef = app.activeDocument; // Assumes a document is active.
// Remove any Color Samplers that may already exist.
docRef.colorSamplers.removeAll();
// deselct any selection that may already exist.
docRef.selection.deselect();
// Get color sample from a given x,y coordinate.
var pixelLoc = [32,42];
var colorSampleRef = docRef.colorSamplers.add(pixelLoc);
var sampledColor = colorSampleRef.color;
// Set the foreground color to the sampled color.
app.foregroundColor = sampledColor;
/**
* Invokes and configures `Select > Color Range` from menu bar.
* #param {Object} color - The sampled color object.
* #param {Number} [fuzziness=80] - The Fuziness value (between 0-200).
*/
function selectColorRange(color, fuzziness) {
fuzziness = (typeof fuzziness !== 'undefined') ? fuzziness : 80;
var d1 = new ActionDescriptor();
// Set the amount of Fuzziness.
d1.putInteger(charIDToTypeID('Fzns'), fuzziness);
// Set invert option to false.
d1.putBoolean(charIDToTypeID('Invr'), false);
d1.putInteger(stringIDToTypeID('colorModel'), 0);
// Set the lAB value for Minimum.
var d2 = new ActionDescriptor();
d2.putDouble(charIDToTypeID('Lmnc'), color.lab.l);
d2.putDouble(charIDToTypeID('A '), color.lab.a);
d2.putDouble(charIDToTypeID('B '), color.lab.b);
d1.putObject(charIDToTypeID('Mnm '), charIDToTypeID('LbCl'), d2);
// Set the lAB value for Maximum.
var d3 = new ActionDescriptor();
d3.putDouble(charIDToTypeID('Lmnc'), color.lab.l);
d3.putDouble(charIDToTypeID('A '), color.lab.a);
d3.putDouble(charIDToTypeID('B '), color.lab.b);
d1.putObject(charIDToTypeID('Mxm '), charIDToTypeID('LbCl'), d3);
// Run the Color Range command without showing dialog.
executeAction(charIDToTypeID('ClrR'), d1, DialogModes.NO);
}
// Invoke the function passing in the sample
// color and default fuzziness value.
selectColorRange(sampledColor, 80);
//docRef.selection.clear();
//docRef.selection.fill(app.foregroundColor);
// Remove the Color Sampler.
colorSampleRef.remove();
Additional notes:
Photoshop allows a maximum of four color samplers to be added. If the document already included four color samplers then we'd get an error when attempting to add another one. To avoid the potential of this happening we invoke docRef.colorSamplers.removeAll(); to remove them all first.
Also, to ensure the resultant selection (i.e. the selection created after invoking the selectColorRange function), is not affected by any existing selection(s) we deselect them all first by invoking docRef.selection.deselect();
Finally, the color sampler that we initially added is removed by calling colorSampleRef.remove();
I'm unsure from your question what you intend to to with the selection once it's been created. As an example;
Lets say you wanted to clear the contents of the selection then you'd invoke docRef.selection.clear();.
If you wanted to fill the resultant selection with the previously sampled color then call docRef.selection.fill(app.foregroundColor);

DateTime as ordering key in oxyplot LineSeries

Is there a way to tell oxyplot to use the x value as the connect/draw order for a line plot instead of the order that the points are added?
Let's assume I have this huge amount of points (2Gb in RAM) of a time series. At a higher level I am only adding a small percentage of those points and as the user zooms into a more specific region I add more points to the series so he can see more detail. Almost like a texture mimap. I can add all the points at once but then oxy becomes really slow when I tries to render all those points in a single window in WPF Maybe there is another solution here?
The problem that I am facing is that oxy draws a line from the last point in the graph to the first one of the new batch because it uses the series points list as the draw order not the X value. Is there a way to change this?
Here is a tiny example based on the 'WPF Simple Example':
var plotModel = new PlotModel { Title = "Simple example", Subtitle = "using OxyPlot" };
var timeAxis = new DateTimeAxis
{
Position = AxisPosition.Bottom,
StringFormat = "hh:mm:ss",
};
plotModel.Axes.Add(timeAxis);
var now = DateTime.UtcNow;
// Create two line series (markers are hidden by default)
var series1 = new LineSeries { Title = "Series 1", MarkerType = MarkerType.Circle };
series1.Points.Add(new DataPoint(DateTimeAxis.ToDouble(now), 5));
series1.Points.Add(new DataPoint(DateTimeAxis.ToDouble(now.AddMinutes(1)), 7));
series1.Points.Add(new DataPoint(DateTimeAxis.ToDouble(now.AddMinutes(2)), 8));
series1.Points.Add(new DataPoint(DateTimeAxis.ToDouble(now.AddMinutes(0.5)), 10));
// Add the series to the plot model
plotModel.Series.Add(series1);
// Set the Model property, the INotifyPropertyChanged event will make the WPF Plot control update its content
this.Model = plotModel;
Here is the output, note that the line draws "back in time":
Is there a solution that does not involves me sorting the points list (not even sure if this works)?
Or maybe I am doing this extra points for details thing completely wrong :)

Add flat amount to canvas size

I want to have some automated process (either action or script) that will copy selection(assumes something has already been selected), place in new canvas, increase canvas size by exactly 10 pixels in height & width, then save it to the desktop.
I'm currently using an action and it works correctly with the exception of the 10 pixels part. I can do something like 10% by using the percentage adjustment in the canvas size menu, but I can't figure out how to do exactly 10 pixels. During the recording, if I just increase the canvas size by 10 pixels it'll record that exact amount (say it was 100x100, it records that I resized canvas to 110x100). So when I play that action on a selection that's of size 50x50 it resizes it to 110x110.... So the problem is that the action records the literal value of the canvas resize and not the add 10 pixels part...
Any ideas here?
This can be scripted as well, but if you've already got an action set up, try modifying your action to do the following:
paste the selection into new document larger than you expect to ever require
expand the selection by 10 px
crop the document to the selection
save
Or, to script it you can tweak the following sample. It assumes you have already copied your image to the clipboard:
#target photoshop
app.preferences.rulerUnits = Units.PIXELS;
app.preferences.typeUnits = TypeUnits.PIXELS;
var doc = app.documents.add('1000px');
var lyr = doc.artLayers.add();
doc.activeLayer = lyr;
doc.paste ();
var bnds = lyr.bounds;
var unitsToAdd = new UnitValue(10, 'px');
bnds[0] = bnds[0] - unitsToAdd;
bnds[1] = bnds[1] - unitsToAdd;
bnds[2] = bnds[2] + unitsToAdd;
bnds[3] = bnds[3] + unitsToAdd;
doc.crop(bnds) ;
doc.saveAs(new File('/c/temp/temp.psd'));

Fix series order

I am producing a graph using the following code:
var svg = dimple.newSvg("#p_m", 1200, 200+(data.f_c_c*20));
var chrt_participants = new dimple.chart(svg, data.result);
chrt_participants.setBounds(200, 50, 900, 100+(data.f_c_c*20));
var y = chrt_participants.addCategoryAxis("y", ["title", "name"]);
var x = chrt_participants.addLogAxis("x", "Activity");
var s = chrt_participants.addSeries(["cid_id","cid","action"], dimple.plot.bar);
chrt_participants.addLegend(800, 0, 400, 40, "left");
chrt_participants.draw();
It draws the following graph:
Everything is as expected, except that the series (the coloured chunks of the bars) don't seem to be put in any particular order. As you can see, for two bars, for some reason unbeknownst to me, the red value is placed before the blue.
Is there a way to fix the order of the series?
The default order is descending by value but you can easily override using series.addOrderRule(). The documentation explains how:
https://github.com/PMSI-AlignAlytics/dimple/wiki/dimple.series#addOrderRule
On a side issue, be careful using a log axis for a stacked bar, it's very misleading. It's not immediately apparent that red and blue have about a 50/50 split of bars. You might be better using a grouped bar instead so that both categories receive comparable scaling.