Logarithmic Axis on Visiblox - logarithm

I'm having trouble setting the range of an axis so that the minimum is below 1. I understand that no value less than 0 can be plotted by I don't understand why values below 1 cannot be viewed unless I can pan to them.
Is there any reason for this? Or a way of resolving it?

While this may be as designed, you could still achieve the affect you're looking for by scaling your data up into the valid range for the logarithmic axis. Then you could override the label function to set the labels you want. It's hacky, but it might work for your needs.
class MyLogarithmicAxis : LogarithmicAxis
{
protected override string GetFormattedDataValueInternal(double dataValue, string formatString)
{
if (dataValue == 1)
{
dataValue = .1;
}
if (dataValue == 100)
{
dataValue = 10;
}
if (dataValue == 1000)
{
dataValue = 100;
}
return base.GetFormattedDataValueInternal(dataValue, formatString);
}
}

Related

Mirth - iterate over insurance HL7 segments

working with an ADT message template in Mirth, having issues with the IN1 and IN2 segments, the IN2 specifically.
Here's a sample message that I'm working with, removed almost all the segments.
MSH|^~&|EPIC|AMB||99|20220403165344|RELEASEAUTO|ADT^A04|367476|T|2.5|||AL|NE
IN1|1|10500201|105^Test|BCBS NC BLUE CARE^Test1|PO BOX 35^^DURHAM^NC^27702^||
IN2|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||first iteration IN1-62||
IN1|1|10500201|106^Test|BCBS NC BLUE CARE^Test1|PO BOX 35^^DURHAM^NC^27702^||
IN2|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||second iteration IN1-62||
So far I've built the following to iterate over the IN1 segment:
//IN1 Segments
var IN1count=0;
for each (seg in msg.IN1) {
createSegment('IN1',output,IN1count);
output.IN1[IN1count]['IN1.2'] = seg['IN1.2'];
output.IN1[IN1count]['IN1.3'] = seg['IN1.3'];
output.IN1[IN1count]['IN1.4'] = seg['IN1.4'];
output.IN1[IN1count]['IN1.8'] = seg['IN1.8'];
output.IN1[IN1count]['IN1.9'] = seg['IN1.9'];
output.IN1[IN1count]['IN1.10'] = seg['IN1.10'];
output.IN1[IN1count]['IN1.12'] = seg['IN1.12'];
output.IN1[IN1count]['IN1.13'] = seg['IN1.13'];
output.IN1[IN1count]['IN1.22'] = seg['IN1.22'];
output.IN1[IN1count]['IN1.36'] = seg['IN1.36'];
IN1count++;
}
I'm struggling to map the IN2 segment correctly on the outbound, I've read about getSegmentsAfter but I can't find that function online... how do I write the correct JS code to look for whether the given IN1 has an IN2 after, specifically if it has IN2-61, and only then create the IN2 segment?
Hope that makes sense :)
You'll find code for createSegmentAfter here; it is JavaScript inserted before your transformer: https://github.com/nextgenhealthcare/connect/blob/2f3740db44c8d42aa6fafffd991b9c1fde940ea0/server/src/com/mirth/connect/server/builders/JavaScriptBuilder.java
One approach to keeping track of whether you just passed an IN1 would be to loop over all segments with something like this:
var was_in1 = false;
var last_in1;
for each ( seg in msg.children() ){
if (was_in1) {
if (seg.name() == "IN2") {
// existing IN2 follows IN1
} else {
// insert new IN2
}
if (seg.name() == "IN1") {
was_in1 = true;
last_in1 = seg;
} else {
was_in1 = false;
}
}
It'd be nice if there was a "nextSibling()" method for messages, but there isn't. Luckily, we can simulate it by:
Getting the current object's childIndex
Getting all children from the current object's parent
Access the next child with the index childIndex + 1
It'd look like this:
for each (seg in msg.IN1) {
// Do your IN1 stuff ...
var nextSeg = seg.parent().children()[ seg.childIndex() + 1];
if(nextSeg != null && nextSeg.name() == 'IN2' && nextSeg['IN2-61'].toString() != '') {
// Do yourIN2 stuff ...
}
}

How do I add polyline length to a Bing Maps polygon

I am trying to recreate a tax map within my system using Bing Maps. My problem is in listing the length, in feet, of the sides of the polygons I am creating. I have a good idea of how to get the length of polylines I am creating from the MSSQL 2012 geometry or geography items in my database. I cannot figure out how to present it to the user effectively though. I have two ideas for how I would like to do this.
Place the lengths directly on or adjacent to the polyline in question.
Create an emphasized point on the full polygon and list to the side of the map, the lengths of the sides of the polygon based on a clockwise order.
Either of the 2 options would work as an acceptable solution. I used this tutorial to create my current environment so I would be looking to integrate the solution into it in some way:
How to create a spatial web service that connects a database to Bing Maps using EF5
Note that my implementation only uses the countries part of the code so I do not need to deal with single points like cities that are in that tutorial.
The relevant piece of code that handles drawing on the map that I would need to edit can be found here:
Bing Maps v7 WellKnowTextModule
If you want to get the perimeter of a polygon in SQL2012 you can grab the exterior ring of it. The exterior ring will be a LineString i.e. "#g.STExteriorRing()". Then measure the length along that line. i.e. "#g.STExteriorRing().STLength()". However, countries are usually not just single Polygons, they can be MultiPpolygons, or GeometryCollections. So to calculate these lengths we have to do a bit more work. Here is a helper method you can add to the service to calculate the perimeters of these shapes:
private double CalculateLength(SqlGeometry geom)
{
double length = 0;
if(string.Compare(geom.STGeometryType().Value, "polygon", true) == 0)
{
}
else if (string.Compare(geom.STGeometryType().Value, "multipolygon", true) == 0)
{
int numPolygon = geom.STNumGeometries().Value;
for(int i = 1; i <= numPolygon; i++){
length += geom.STGeometryN(i).STExteriorRing().STLength().Value;
}
}
else if (string.Compare(geom.STGeometryType().Value, "geometrycollection", true) == 0)
{
int numGeom = geom.STNumGeometries().Value;
for (int i = 1; i <= numGeom; i++)
{
length += CalculateLength(geom.STGeometryN(i));
}
}
return length;
}
To get the length info from the server side to the client add a property to the Country or BaseEntity class like this:
[DataMember]
public double Perimeter { get; set; }
From here you can populate this value after the linq query is used to get the response results using a simple loop that calls the helper method from earlier:
for (int i = 0; i < r.Results.Count;i++)
{
var geom = SqlGeometry.STGeomFromText(new System.Data.SqlTypes.SqlChars(r.Results[i].WKT), 4326);
r.Results[i].Perimeter = CalculateLength(geom);
}
As for displaying the information on the map. An easy way to place the information on a polyline is to choose a coordinate along the line, perhaps the middle one, just get the # or coordinates in the line and find the middle index and use that coordinate for a pushpin. You can then create a custom push using either a background image with text, or using custom HTML:
http://www.bingmapsportal.com/ISDK/AjaxV7#Pushpins4
http://www.bingmapsportal.com/ISDK/AjaxV7#Pushpins15
Wanted to add an addendum to the answer I accepted as I feel it changes it a bit.
While working on this I found that I was not actually able to get each line segment's length via entity framework. This is due to the fact that the query required changing the geography I had back to a geometry then parse it to its base line segments and then change those line segments back to geographies. The query, even in SQL, would take minutes so it was not an option to run dynamically in EF.
I ended up creating another table in my database containing the parsed line segments for each side of each polygon I had. Then I could use the centroids of the line segments as faux cities. I then added this logic into the DisplayData javascript function from the tutorial mentioned in the question after the for loop in the method.
if (shape.getLength) {
} else {
var chkPolygon = data.Results[0].WKT.substring(0, data.Results[0].WKT.indexOf('(', 0));
chkPolygon = chkPolygon.replace(/\s/g, '');
switch (chkPolygon.toLowerCase()) {
case 'point':
case 'polygon':
var latlonCheck = map.getCenter();
var setSides = window.location.origin + "/SpatialService.svc/FindNearBy?latitude=" +
latlonCheck.latitude + "&longitude=" + latlonCheck.longitude +
"&radius=" + data.Results[0].ID + "&layerName=" + "city" + "&callback=?";
CallRESTService(setSides, DisplaySides);
default:
break;
}
}
the data.Results[0].ID would find all the line segments in the new table for that specific country. Then the DisplaySides function is used to overlay the html pushpins as "cities" over the appropriate points for each side on the map
function DisplaySides(getSides) {
infobox.setOptions({ visible: false });
if (getSides && getSides.Results != null) {
for (var i = 0; i < getSides.Results.length; i++) {
var sideLenFtShort = Math.round(getSides.Results[i].LengthFeet * 100) / 100;
var htmlLenString = "<div style='font-size:14px;border:thin solid black;background-color:white;font-weight:bold;color:black;'>" + sideLenFtShort.toString(); + "</div>";
var testString = {
pushpinOptions: { width: null, height: null, htmlContent: htmlLenString }
};
var sideCtr = WKTModule.Read(getSides.Results[i].WKT, testString);
dataLayer.push(sideCtr);
}
}
else if (getSides && getSides.Error != null) {
alert("Error: " + getSides.Error);
}
}

Why isn't my score recording on the playerprefs is there GetFloat method?

Why isn't my score recording on the playerprefs ? is there GetFloat method? Can anyone help me to post the least score of my game it just like the most least seconds will get the best time record ever
var myTimer: float = 0;
var GUITimer: GUIText;
function Start() {
}
function Update() {
GUITimer.text = "Time: " + myTimer;
if (myTimer > -1) {
myTimer += Time.deltaTime;
}
}
function OnTriggerEnter(other: Collider) {
if (other.tag == "FinishLine") {
SaveTime();
}
}
function OnGUI() {
GUI.Label(Rect(10, 10, 500, 200), myTimer.ToString());
}
function SaveTime() {
if (myTimer < PlayerPrefs.GetInt("JeepneyScore3")) {
PlayerPrefs.SetInt("JeepneyScore3", myTimer);
}
Application.LoadLevel("Levels");
}
I see three problems:
First, you're tracking a float, but calling GetInt() and SetInt(). Keep your data types consistent. You should either round/floor/etc, or call GetFloat() and SetFloat().
Second, you're not calling Save(), which means your changes will never write to disk. You might consider something like this:
PlayerPrefs.SetFloat("JeepneyScore3", myTimer);
PlayerPrefs.Save();
Third, you're not handling the case where no data exists. You could check for existing data with HasKey(), but in this case it's simpler to rely on the second form of GetFloat(). The default form, which you're calling, returns zero if the requested key isn't set:
//returns value of "foo", or zero if no such value
var prevBest = PlayerPrefs.GetFloat("foo");
If you're looking for a time below the player's previous best, but the default "best" is already 0.0, you're going to have a hard time beating that time.
You can instead provide your own default value:
//returns value of "foo", or ten thousand if no such value
var prevBest = PlayerPrefs.GetFloat("foo", 10000.0);
Finally, you should make sure that SaveTime() is actually being called at the appropriate time. You could add a simple debug line, like this:
Debug.Log("SaveTime was called");
And then make sure that's showing up. If not, you need to fix your collision check.

Unity3D: Automatic target according to price

I've been working on a simulator in Unity3D and i need a customer object to be able to automatically find the shop object with the lowest price.
I've done a little testing on this myself and found it to be rather difficult to achive. So i was hoping someone could help me tweak my code a bit further in the right direction? :)
Here's the code i've got so far:
var cityName : String;
var shopScript : MarketScript;
function FindShopPlace () : GameObject //Make a queueing system
{
var max : float;
var target : GameObject;
var gos : GameObject[];
var goScript : MarketScript;
gos = GameObject.FindGameObjectsWithTag("market");
for (var go : GameObject in gos)
{
goScript = go.GetComponent(MarketScript);
if (goScript.cityName == cityName)
{
if (goScript.resalePrice >= max && goScript.cityName == cityName)
{
max = goScript.resalePrice;
}
if (goScript.resalePrice < max && goScript.cityName == cityName)
{
print ("test");
target = go;
}
}
}
shopScript = target.GetComponent(MarketScript);
return target;
}
Currently with this code, the target is never found and assigned. I get the following NullReferenceException from line number 3 from the bottom:
NullReferenceException: Object reference not set to an instance of an
object ConsumerScript.FindShopPlace () (at
Assets/_MyAssets/_Scripts/ConsumerScript.js:268) ConsumerScript.Update
() (at Assets/_MyAssets/_Scripts/ConsumerScript.js:96)
You get a NullReferenceException because target was never set to any object.
What you are doing in your loop is (1) finding the maximum price and (2) finding the last Object after maximum that is smaller than the maximum.
So if your prices in order are 1, 2, 3 target will never be set because in each step you are setting the maximum to the new value and are never setting target. Even when set its not necessarily the cheapest. Consider the prices 1, 3, 2.
First Step: Set maximum to 1
Second Step: Set maximum to 3
Third Step: Set target to the GameObject with price 2
If you get errors like this try out simple examples like this to get to the bottom of things. Also you are using the variable maximum(comparing the first time) without ever setting it to anything, not sure if this works in Javascript(it might) but its bad practice
What you really want isnt finding the maximum price or minimum price but the GameObject with the lowest resalePrice.
var min : float;
var success : boolean;
var firstHit : boolean;
...
success = false;
firstHit = true;
for (var go : GameObject in gos)
{
goScript = go.GetComponent(MarketScript);
if (goScript.cityName == cityName)
{
success = true;
if(firstHit) // alternatively to this would be to set minimum to a value that is higher than every possible price ( thats also what i meant with you shouldnt use max without setting it to anything)
{
min = goScript.resalePrice;
target = go;
}
else
{
if (goScript.resalePrice < min )
{
min = goScript.resalePrice;
target = go;
}
}
}
}
if(success)
{
shopScript = target.GetComponent(MarketScript);
return target;
}
else
{
// TODO: handle the case that there isnt a shop in the city.
// Maybe give an error Message with Debug.Log if this isnt supposed to happen
return null;
}

Peculiar Map/Reduce result from CouchDB

I have been using CouchDB for quite sometime without any issues. That is up until now. I recently saw something in my map/reduce results which I had overlooked!
This is before performing a sum on the "avgs" variable. I'm basically trying to find the average of all values pertaining to a particular key. Nothing fancy. The result is as expected.
Note the result for timestamp 1308474660000 (4th row in the table):
Now I sum the "avgs" array. Now here is something that is peculiar about the result. The sum for the key with timestamp 1308474660000 is a null!! Why is CouchDB spitting out nulls for a simple sum? I tried with a custom addition function and its the same problem.
Can someone explain to me why is there this issue with my map/reduce result?
CouchDB version: 1.0.1
UPDATE:
After doing a rereduce I get a reduce overflow error!
Error: reduce_overflow_error
Reduce output must shrink more rapidly: Current output: '["001,1,1,1,1,1,11,1,1,1,1,1,1,11,1,1,1,1,1,1,11,1,1,1,1,1,1,11,1,1,1,1,1,101,1,1,1,1,1,1,11,1,1,1,1'... (first 100 of 396 bytes)
This is my modified reduce function:
function (key, values, rereduce) {
if(!rereduce) {
var avgs = [];
for(var i=values.length-1; i>=0 ; i--) {
avgs.push(Number(values[i][0])/Number(values[i][1]));
}
return avgs;
} else {
return sum(values);
};
}
UPDATE 2:
Well now it has gotten worse. Its selectively rereducing. Also, the ones it has rereduced show wrong results. The length of the value in 4th row for timestamp (1308474660000) should be 2 and not 3.
UPDATE 3:
I finally got it to work. I hadn't understood the specifics of rereduce properly. AFAIK, Couchdb itself decides how to/when to rereduce. In this example, whenever the array was long enough to process, Couchdb would send it to rereduce. So I basically had to sum twice. Once in reduce, and again in rereduce.
function (key, values, rereduce) {
if(!rereduce) {
var avgs = [];
for(var i=values.length-1; i>=0 ; i--) {
avgs.push(Number(values[i][0])/Number(values[i][1]));
}
return sum(avgs);
} else {
return sum(values); //If my understanding of rereduce is correct, it only receives only the avgs that are large enough to not be processed by reduce.
}
}
Your for loop in the reduce function is probably not doing what you think it is. For example, it might be throwing an exception that you did not expect.
You are expecting an array of 2-tuples:
// Expectation
values = [ [value1, total1]
, [value2, total2]
, [value3, total3]
];
During a re-reduce, the function will get old results from itself before.
// Re-reduce values
values = [ avg1
, avg2
, avg3
]
Therefore I would begin by examining how your code works if and when rereduce is true. Perhaps something simple will fix it (although often I have to log() things until I find the problem.)
function(keys, values, rereduce) {
if(rereduce)
return sum(values);
// ... then the same code as before.
}
I will elaborate on my count/sum comment, just in case you are curious.
This code is not tested, but hopefully you will get the idea. The end result is always a simple object {"count":C, "sum":S} and you know the average by computing S / C.
function (key, values, rereduce) {
// Reduce function
var count = 0;
var sum = 0;
var i;
if(!rereduce) {
// `values` stores actual map output
for(i = 0; i < values.length; i++) {
count += Number(values[i][1]);
sum += Number(values[i][0]);
}
return {"count":count, "sum":sum};
}
else {
// `values` stores count/sum objects returned previously.
for(i = 0; i < values.length; i++) {
count += values[i].count;
sum += values[i].sum;
}
return {"count":count, "sum":sum};
}
}
I use the following code to do average. Hope it helps.
function (key, values) {
return sum(values)/values.length;
}