Highstock step multiple data points on same x axis - highcharts

When the highstock chart data set has multiple points on the same axis ex:
data: [[0,0], [0, 100], [1, 100], [1,200], [4, 100], [4, 200]]
the point doesn't always choose the highest number by default. It looks like it randomly selects one of the numbers on the same axis.
Here's my fiddler example: http://jsfiddle.net/ceo1y97m/
As you can see when you hover over the different points, it's not always displaying the highest point's Y value. How do I get this to show only the highest point's value?
Edit: Here is the reason that I have multiple x values that are the same:
Let's say the line represents the amount of money you deposit into an account over time. In the line's legend I want to display the amount you've deposited over the period that you're viewing. This would be the furthest point right's Y value minus the furthest point left's Y value. If I don't include the duplicate Y values, this calculation is incorrect.
See updated fiddler to show this error on the legend value (zoom in and out to change the legend values): https://jsfiddle.net/LS384/822/
The two data sets look identical, but the legend values are different, because both points on the same axis aren't displayed.

I'm not sure that this is how the step chart was intended to be used, you should have just 1 value per axis point.
What you could do is filter your data to just keep the highest value for each point
data: [[0,0], [0, 100], [1, 100], [1,200], [4, 100], [4, 200]]
for (var i in data) {
if (filteredData[data[i][0]] == undefined) {
filteredData[data[i][0]] = data[i]
} else {
if (filteredData[data[i][0]][1] < data[i][1]) {
filteredData[data[i][0]] = data[i];
}
}
}
here is your edited filter with the chart looking the same and you desired behaviour http://jsfiddle.net/ceo1y97m/4/
Edit:
I made a workaround, i hid the unfiltered data, used the filtered data for display and gave it the same color as the unfiltered one, and in the function that calculates the difference i use the unfiltered data(ch.series[0].data])
Here is the fiddle with your expected behaviour https://jsfiddle.net/LS384/826/

I would process the data, so you have one point per x value with additional information - multiple values. I treat { x, y } as the information about how the point should be visualised plus add the array with all additional values which allow to make the proper calculations.
This:
[
[0, 0],
[0, 100],
[1, 100],
[1, 200],
[1, 300],
becomes this:
[{
x: 0,
y: 100,
values: [0, 100]
}, {
x: 1,
y: 300,
values: [100, 200, 300]
}]
With points defined as the above, you can access the values via point.options.values and calculate the difference.
example: http://jsfiddle.net/jqdh79vv/

Related

Deinterlace a vector using vDSP

Let's say I have a vector:
let input: [Float] = [1, 2, 3, 4, 5, 6, 7, 8, ...]
What I'd like to do is deinterlace this vector by selecting every other value to produce 2 new vectors as output, as follows:
[1, 3, 5, 7, ...]
[2, 4, 6, 8, ...]
What's the best way to do this in vDSP?
The tool you want here is vDSP.convert(interleavedComplexVector:toSplitComplexVector:). Don't let the "complex vector" confuse you. It doesn't matter if these are "complex" or not. An "interleaved complex vector" is just "a series of even and odd values." And a "split complex vector" is just "a struct containing a list of evens and a list of odds." These are sometimes interpreted as real and imaginary components, but that interpretation has nothing to do with how convert works (and often has nothing to do with how these values are used in practice).
So assuming a [Float] like:
let input: [Float] = [1, 2, 3, 4, 5, 6, 7, 8]
And two output lists ("vectors") like:
var evens: [Float] = Array(repeating: 0, count: input.count / 2)
var odds = evens
You can split them up this way:
evens.withUnsafeMutableBufferPointer { evenPtr in
odds.withUnsafeMutableBufferPointer { oddPtr in
var split = DSPSplitComplex(realp: evenPtr.baseAddress!,
imagp: oddPtr.baseAddress!)
input.withUnsafeBytes {
vDSP.convert(interleavedComplexVector: Array($0.bindMemory(to: DSPComplex.self)),
toSplitComplexVector: &split)
}
}
}
// At this point, evens and odds are filled in.
This is intentionally modeled closely on Apple's example code for setting up an FFT.
If you happen to need more values split up this way (particularly 4 values), take a look at vImageConvert_ARGBFFFFtoPlanarF and related functions. Just like "complex" really just means "two floats," "ARGBFFFF" just means "4 floats." Numbers are just numbers and sometimes the function you need happens to be named based on another use case.

Call on a String as an Array

I have been stuck on a problem for a couple days now and I'm not sure how to word it, so I haven't had much luck searching for an answer hoping you can help!
I have an array of 20 arrays which is the same as my array of 20 strings, when a button is clicked the array changes to the name of the selected button, I can change it to a string very easily with:
newArray = oldArray[0]
But cannot find a way to insert the string name as the new array name, if anyone has any advice I'd be glad, thanks!
newArray = [oldArray[0]]
Just creates an array with one string in, I have been looking for a function something like:
newArray = Array(named: oldArray [0])
but not sure if it exists.
If you want to insert on some specific index then use insert like this:
var newArr = [String]()
newArr.insert("jogendar", at: 0) /// Removes and returns the element at the specified position.
And if you want to add at the end then use append like this:
var newArr = [String]()
newArr.append("jogendar") ///Adds the elements of a sequence to the end of the array.
If you want to change the name of the button when selected then you don't need to maintain the array, you can set the title of button for states like this:
let btn = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 30))
btn.setTitle("jogendar_defautl", for: UIControlState.normal)
btn.setTitle("jogendar_selected", for: UIControlState.selected)
And when you want to select the button then button name auto change according to selected state:
btn.isSelected = !btn.isSelected
This is not an answer as such, you do not provide enough detail for that, but let's see if we can help you onto the right track. You wrote:
I have been looking for a function something like:
newArray = Array(named: oldArray [0])
This does not exist because arrays (and other values) do not have names. You appear to be confusing variable names and values, they are very different things. For example, the expression:
[0, 1, 8, 27, 64]
produces an array value containing five elements, it has no name it is just a value. The value could be assigned to a variable:
var cubes = [0, 1, 8, 27, 64]
Now we have a variable with the name cubes whose current value is the array. The above statement has both declared a variable, cubes, given it a type, [Int], and assigned it an initial value, [0, 1, 8, 27, 64]. It has not named the value, the value can be copied into another variable:
var anotherVariable = cubes
After the above you have two variables, cubes and anotherVariable, each which currently has the same value. Values are not shared, you can alter one of the values:
anotherVariable[0] = 42
and now anotherVariable contains the value [42, 1, 8, 27, 64] while cubes still contains the value [0, 1, 8, 27, 64].
OK, back to your question, you wrote:
I have an array of 20 arrays which is the same as my array of 20 strings...
What you appear to be describing is something along the lines of:
var myArrays = [ [0, 1, 4, 9, 16], [0, 1, 8, 27, 64] ]
var myNames = [ "squares", "cubes" ]
and you have buttons with labels squares and cubes. What you appear to be attempting is to go from a click on a button to an element of myArrays via the myNames array - which is where you "naming" of values is coming from.
To map a "name" to a "array" you should use a dictionary, which is a collection keys, your names, to values, your arrays:
let myCollection = [ "squares":[0, 1, 4, 9, 16], "cubes":[0, 1, 8, 27, 64] ]
This declares a constant (the use of let rather than var) dictionary whose keys are strings and values arrays. So you effectively have a collection of "named arrays".
You can now select an array for this collection by name using a statement along the lines of:
var currentArray = myCollection[currentButtonTitle]
where currentButtonTitle has previously been set to the title of the button you clicked.
HTH

How could we plot graphical representation using High Charts where one x-axis value have multiple y-axis value

How could we plot graphical representation using High Charts where one x-axis value have multiple y-axis value
and for each x-axis value number of y-axis value differs.
I have date on x-axis and on y-axis the readings.
Now, i have data for each date, but the number of reading may differ for different dates. Like for today i have 5 readings and yesterday it was 10 readings.
So i have the data Date vise. and i want to plot it on graph with positive and negative values. I do some RnD for high charts for this, but highcharts dont show the reading receptive with this scenario, or may be i didnt get it. Can anybody help me in this.
Data I have:
1) Date: 1/8/2017
Values:[12,56,-14,35,8]
2) Date: 2/8/2017
Values:[3,9,-4]
3) Date: 3/8/2017
Values:[8,-6,45]
Thank you for the help
You can use the scatter series: https://www.highcharts.com/docs/chart-and-series-types/scatter-chart
Live demo adjusted to your problem: http://jsfiddle.net/kkulig/c6w79bd0/
If you have data composed similarly to this:
var data = [{
date: Date.UTC(2017, 0, 1),
values: [4, 5, 6, -2]
}, {
date: Date.UTC(2017, 0, 2),
values: [3, -7]
}, {
date: Date.UTC(2017, 0, 3),
values: [0, 11]
}];
You can prepare it this way:
var series = {
data: []
};
data.forEach(function(day) {
day.values.forEach(function (value){
series.data.push([day.date, value]);
});
});

Highchart heatmap unable to display array of data

Not able to display data in heat map coming from JSON. Only X and Y axis are shown.
var data1=[
["2016-01-01", 0, 20.0],
["2016-01-01", 1, 9.0],
["2016-01-01", 2, 10.0]
]
[Fidlele link][1]
http://jsfiddle.net/nxgzeo34/2/
Please advise

highcharts 3 addPoint Point order

In Highcharts 2, it was easy to add a point using series.addPoint(p) where the x value of that point fell between the x-values of two existing points.
Example: Let's say you wanted to create a chart with one series containing two points:
var p1 = {x: 100, y: 50};
var p2 = {x: 200, y: 40};
var data = [];
data.push(p1);
data.push(p1);
var c = new Highcharts.Chart({
...//code omitted
type: 'line',
data: data,
...//code omitted
});
In version two you could call add a point between those two by going:
var p3 = {x: 150, y: 60};
c.series[0].addPoint(p3, true);
For 'line' charts, highcharts 2 would automatically determine that the x value of p3 falls between the x values of p1 and p2 and so the line would be plotted through the points in the order: p1, p3, p2.
We are finding that in highcharts 3, the line gets plotted through the points in the order p1, p2, p3 - which implies that it "turns back on itself".
I have prepared the following jsFiddle examples, which add 50 points to an existing series with randomized x and y value.:
Highcharts 2.1.9: http://jsfiddle.net/HdNh2/4/
Highcharts 3.0.0: http://jsfiddle.net/HdNh2/5/
Is this something that could be fixed or do we need to try and circumvent the issue?
Thanks in advance...
H
So just to close this issue: Highcharts has confirmed that the logic changed since 2.2.x.
In our case it was simple enough to just re-render the entire chart, but I suspect series.setData() would also have been an option.
Here's a workaround. This will sort points on their x-values as they're added manually. This events object is in the chart object options block.
events: {
click: function(e) {
// find the clicked values and the series
var series = this.series[DIA.currentSeriesIndex],
x = parseFloat(e.xAxis[0].value),
y = parseFloat(e.yAxis[0].value);
// Add it
series.addPoint([x, y]);
if ( series.data.length > 1) {
// grab last point object in array
var point = series.data[series.data.length-1];
// sort the point objects on their x values
series.data.sort(function (a, b)
{
//Compare "a" and "b" and return -1, 0, or 1
return (a.x - b.x);
});
// force a redraw
point.update();
}
}
}

Resources