更新到0.6.0.2

This commit is contained in:
2026-07-06 08:47:33 +08:00
parent e29a5178b7
commit 97d41a1385
473 changed files with 156342 additions and 5 deletions
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4c54010832fc72f4b9268b6b98d10778
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,886 @@
namespace DrawXXL
{
using UnityEngine;
using System.Collections.Generic;
public class ChartAxis
{
public enum Scaling
{
dynamic_encapsulateAllValues_includingThoseOutsideOfOtherAxisDisplay,
dynamic_encapsulateAllValues_butOnlyThoseInsideOfOtherAxisDisplay,
fixed_relativeToHighestValue,
fixed_relativeToLowestValue,
fixed_relativeToMostCurrentValue,
fixed_absolute
}
public enum SourceOfAutomaticValues
{
fixedStepForEachValueAdding,
fixedStep_followingTheManualIncrementFunction,
frameCount,
fixedTime,
fixedUnscaledTime,
realtimeSinceStartup,
time,
timeSinceLevelLoad,
unscaledTime,
editorTimeSinceStartup
}
public float lineWidth_relToChartHeight = 0.0f;
ChartDrawing chart_thisAxisIsPartOf;
UtilitiesDXXL_Math.Dimension cartesianDimension;
public ChartAxis theOtherAxis;
private string name = null;
public string Name
{
get { return name; }
set
{
name = value;
nameHasBeenManuallySet = true;
}
}
bool nameHasBeenManuallySet = false;
public float nameText_scaleFactor = 1.0f;
public Scaling scaling = Scaling.dynamic_encapsulateAllValues_butOnlyThoseInsideOfOtherAxisDisplay;
public SourceOfAutomaticValues sourceOfAutomaticValues = SourceOfAutomaticValues.fixedStepForEachValueAdding;
bool allXValuesCameFromAutomaticSource;//only used for x-axis //ignored for y-axis
public float fixedLowerEndValueOfScale = 0.0f;
public float fixedUpperEndValueOfScale = 100.0f;
public float fixedDisplayedSpan_belowAnchorValue = 500.0f;
public float fixedDisplayedSpan_aboveAnchorValue = 100.0f;
float fixedLowerEndValueOfScale_duringInspectionComponentPhases;
float fixedUpperEndValueOfScale_duringInspectionComponentPhases;
public int approxNumberOfGraduationIntervals = 5; //has only effect, when "graduationIntervalSource" is "axisSpanDividedByFixedNumberofIntervals", otherwise ignored. The interval number in the chart may in some cases be some more or less than this number (up to doulbe of this number), so it's just a raw specification
public int ApproxNumberOfGraduationIntervals
{
get { return approxNumberOfGraduationIntervals; }
set { approxNumberOfGraduationIntervals = Mathf.Clamp(value, 2, 10000); }
}
public float alphaOfGraduationLinesInsideDataArea = 0.2f; //can be used to switch off or accentuate the graduation lines that extend into the data area of the chart.
public float alphaOfGraduationNotation = 1.0f; //can be used to switch off or tone down the numbers notation on the axis graduation marks. default is 1
public bool graduationTypesetting_isManually = false; //if you set this to true, then you can use "AngleDeg_ofAxisGraduationNotationText" and "GraduationTextSize_relToAxisLength".
float used_angleDeg_ofAxisGraduationNotationText; //only used for xAxis
private float angleDeg_ofAxisGraduationNotationText = 0.0f;
public float AngleDeg_ofAxisGraduationNotationText
{
//only used for the x-axis. Ignored for the y-axis
//can be used to change the direction of the notation text at the graduation marks on the x axis. Positive angles turn the text counter clockwise, negative angles turn it clockwise. Is constrained between -90 and +90.
//has only effect, if "graduationTypesetting_isManually" has been set to "true", otherwise it's ignored
get { return angleDeg_ofAxisGraduationNotationText; }
set
{
angleDeg_ofAxisGraduationNotationText = Mathf.Clamp(value, -90.0f, 90.0f);
if (graduationTypesetting_isManually == false)
{
Debug.LogWarning("Setting 'AngleDeg_ofAxisGraduationNotationText' will only have effect if 'graduationTypesetting_isManually' is 'true' (which is not the case at the moment.)");
}
}
}
private float graduationTextSize_relToAxisLength = 0.02f;
public float GraduationTextSize_relToAxisLength
{
//has only effect, if "graduationTypesetting_isManually" has been set to "true", otherwise it's ignored
get { return graduationTextSize_relToAxisLength; }
set
{
graduationTextSize_relToAxisLength = Mathf.Clamp(value, 0.001f, 0.3f);
if (graduationTypesetting_isManually == false)
{
Debug.LogWarning("Setting 'GraduationTextSize_relToAxisLength' will only have effect if 'graduationTypesetting_isManually' is 'true' (which is not the case at the moment.)");
}
}
}
private float lengthConversionFactor_fromChartScaling_toWorldScaling;
public float LengthConversionFactor_fromChartScaling_toWorldScaling
{
get { return lengthConversionFactor_fromChartScaling_toWorldScaling; }
set { Debug.LogError("Setting 'LengthConversionFactor_fromChartScaling_toWorldScaling' manually is not supported."); }
}
private float valueMarkingTheLowerAxisEnd_convertedToUnitsOfTheUnwarpedUnscaledWorldSpace;
public float ValueMarkingTheLowerAxisEnd_convertedToUnitsOfTheUnwarpedUnscaledWorldSpace
{
get { return valueMarkingTheLowerAxisEnd_convertedToUnitsOfTheUnwarpedUnscaledWorldSpace; }
set { Debug.LogError("Setting 'ValueMarkingTheLowerAxisEnd_convertedToUnitsOfTheUnwarpedUnscaledWorldSpace' manually is not supported."); }
}
Vector3 unrotated_axisVector_normalized_inWorldSpace;
private Vector3 axisVector_inWorldSpace;
public Vector3 AxisVector_inWorldSpace
{
get { return axisVector_inWorldSpace; }
set
{
if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x)
{
Debug.LogError("Setting 'xAxis.AxisVector_inWorldSpace' manually is not supported. Use 'chartDrawing.Rotation' and 'chartDrawing.Width_inWorldSpace' instead.");
}
else
{
Debug.LogError("Setting 'yAxis.AxisVector_inWorldSpace' manually is not supported. Use 'chartDrawing.Rotation' and 'chartDrawing.Height_inWorldSpace' instead.");
}
}
}
private Vector3 axisVector_normalized_inWorldSpace;
public Vector3 AxisVector_normalized_inWorldSpace
{
get { return axisVector_normalized_inWorldSpace; }
set { Debug.LogError("Setting 'chartAxis.AxisVector_normalized_inWorldSpace' manually is not supported. Use 'chartDrawing.Rotation' instead."); }
}
private float valueMarkingLowerEndOfTheAxis;
private float valueMarkingUpperEndOfTheAxis;
public float ValueMarkingLowerEndOfTheAxis
{
get { return valueMarkingLowerEndOfTheAxis; }
set { Debug.LogError("Setting 'valueMarkingLowerEndOfTheAxis' manually is not supported. You can use 'fixedLowerEndValueOfScale' instead (after setting 'scaling' to 'fixed_absolute')."); }
}
public float ValueMarkingUpperEndOfTheAxis
{
get { return valueMarkingUpperEndOfTheAxis; }
set { Debug.LogError("Setting 'valueMarkingUpperEndOfTheAxis' manually is not supported. You can use 'fixedUpperEndValueOfScale' instead (after setting 'scaling' to 'fixed_absolute')."); }
}
float lowerEndOfAxisToUpperEnd_inChartUnits;
private float length_inWorldSpace = 1.0f;
public float Length_inWorldSpace
{
get { return length_inWorldSpace; }
set
{
if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x)
{
Debug.LogError("Setting 'xAxis.length_inWorldSpace' manually is not supported. You can use 'chartDrawing.Width_inWorldSpace' instead.");
}
else
{
Debug.LogError("Setting 'yAxis.length_inWorldSpace' manually is not supported. You can use 'chartDrawing.Height_inWorldSpace' instead.");
}
}
}
List<float> posOfGraduationMarks_inChartSpace = new List<float>();
List<string> graduationMarksTexts = new List<string>();
public bool drawZeroPositionAsDottedLine; //default is true for the yAxis and false for the xAxis
PointOfInterest pointOfInterest_displayingTheZeroPositionLine;
PointOfInterest pointOfInterest_displayingTheZeroPositionLine_lowAlphaUnderlay;
public ChartAxis(Vector3 unrotated_axisVector_normalized_inWorldSpace, ChartDrawing chart_thisAxisIsPartOf, UtilitiesDXXL_Math.Dimension cartesianDimension)
{
this.unrotated_axisVector_normalized_inWorldSpace = unrotated_axisVector_normalized_inWorldSpace;
axisVector_inWorldSpace = this.unrotated_axisVector_normalized_inWorldSpace;
axisVector_normalized_inWorldSpace = this.unrotated_axisVector_normalized_inWorldSpace;
this.chart_thisAxisIsPartOf = chart_thisAxisIsPartOf;
this.cartesianDimension = cartesianDimension;
if (this.cartesianDimension == UtilitiesDXXL_Math.Dimension.x)
{
allXValuesCameFromAutomaticSource = true;
name = GetAxisNameForAutomaticSources();
drawZeroPositionAsDottedLine = false;
}
else
{
drawZeroPositionAsDottedLine = true;
}
CreatePointsOfInterest_thatDisplaysTheZeroPositionAsDottedLine(out pointOfInterest_displayingTheZeroPositionLine, out pointOfInterest_displayingTheZeroPositionLine_lowAlphaUnderlay);
chart_thisAxisIsPartOf.AddPointOfInterest(pointOfInterest_displayingTheZeroPositionLine);
chart_thisAxisIsPartOf.AddPointOfInterest(pointOfInterest_displayingTheZeroPositionLine_lowAlphaUnderlay);
}
public void Clear()
{
allXValuesCameFromAutomaticSource = true;
}
public void RecalcScaling()
{
CalcMinMaxOfAxis();
lowerEndOfAxisToUpperEnd_inChartUnits = valueMarkingUpperEndOfTheAxis - valueMarkingLowerEndOfTheAxis;
lengthConversionFactor_fromChartScaling_toWorldScaling = length_inWorldSpace / lowerEndOfAxisToUpperEnd_inChartUnits;
valueMarkingTheLowerAxisEnd_convertedToUnitsOfTheUnwarpedUnscaledWorldSpace = valueMarkingLowerEndOfTheAxis * lengthConversionFactor_fromChartScaling_toWorldScaling;
SetIf_pointOfInterestDisplayingTheZeroPositionLine_isDisplayed();
}
public void Draw(InternalDXXL_Plane chartPlane, float durationInSec, bool hiddenByNearerObjects)
{
//use chartDrawing.Draw() instead.
DXXLWrapperForUntiysBuildInDrawLines.currentlyDrawingChart = chart_thisAxisIsPartOf;
float fixedConeLength_forBothAxisVectors = Get_fixedConeLength_forBothAxisVectors();
float lineWidth_worldSpace = 0.0f;
if (UtilitiesDXXL_Math.ApproximatelyZero(lineWidth_relToChartHeight) == false)
{
lineWidth_worldSpace = lineWidth_relToChartHeight * chart_thisAxisIsPartOf.Height_inWorldSpace;
}
UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits);
UtilitiesDXXL_DrawBasics.VectorFrom(chart_thisAxisIsPartOf.Position_worldspace, axisVector_inWorldSpace, chart_thisAxisIsPartOf.color, lineWidth_worldSpace, null, fixedConeLength_forBothAxisVectors, false, true, false, 0.0f, false, durationInSec, hiddenByNearerObjects, chartPlane, false, 0.0f);
UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors();
if (chart_thisAxisIsPartOf.IsEmptyWithNoLinesToDraw == false)
{
DrawAxisGraduation(durationInSec, hiddenByNearerObjects);
DrawChartBoundaryLine_inTheStyleOfAGraduationLine(durationInSec, hiddenByNearerObjects);
}
DrawAxisName(durationInSec, hiddenByNearerObjects);
DXXLWrapperForUntiysBuildInDrawLines.currentlyDrawingChart = null;
}
public float Get_fixedConeLength_forBothAxisVectors()
{
return (0.05f * Mathf.Max(length_inWorldSpace, theOtherAxis.length_inWorldSpace));
}
void CalcMinMaxOfAxis()
{
//-> lowestValue is guaranteed lower than highestValue after this function
Scaling used_scaling = (chart_thisAxisIsPartOf.chartInspector_component == null) ? scaling : Scaling.fixed_absolute;
switch (used_scaling)
{
case Scaling.dynamic_encapsulateAllValues_includingThoseOutsideOfOtherAxisDisplay:
GetAxisEndsIfAllNonHiddenValuesAreEncapsulated(out valueMarkingLowerEndOfTheAxis, out valueMarkingUpperEndOfTheAxis);
return;
case Scaling.dynamic_encapsulateAllValues_butOnlyThoseInsideOfOtherAxisDisplay:
if (theOtherAxis.HasAFixedScalingType())
{
GetAxisEndsIfAllNonHiddenValuesInsideOtherAxisSpanAreEncapsulated(out valueMarkingLowerEndOfTheAxis, out valueMarkingUpperEndOfTheAxis);
}
else
{
GetAxisEndsIfAllNonHiddenValuesAreEncapsulated(out valueMarkingLowerEndOfTheAxis, out valueMarkingUpperEndOfTheAxis);
}
return;
case Scaling.fixed_relativeToHighestValue:
float highestValueOfAllLines = GetHighestValueOfAllLines();
TryExpandInvalidZeroSpanBesideAnchor();
valueMarkingLowerEndOfTheAxis = GetMinValueBesideAnchor(highestValueOfAllLines);
valueMarkingUpperEndOfTheAxis = GetMaxValueBesideAnchor(highestValueOfAllLines);
return;
case Scaling.fixed_relativeToLowestValue:
float lowestValueOfAllLines = GetLowestValueOfAllLines();
TryExpandInvalidZeroSpanBesideAnchor();
valueMarkingLowerEndOfTheAxis = GetMinValueBesideAnchor(lowestValueOfAllLines);
valueMarkingUpperEndOfTheAxis = GetMaxValueBesideAnchor(lowestValueOfAllLines);
return;
case Scaling.fixed_relativeToMostCurrentValue:
float mostCurrentValue = GetMostCurrentValueOfAllLines();
TryExpandInvalidZeroSpanBesideAnchor();
valueMarkingLowerEndOfTheAxis = GetMinValueBesideAnchor(mostCurrentValue);
valueMarkingUpperEndOfTheAxis = GetMaxValueBesideAnchor(mostCurrentValue);
return;
case Scaling.fixed_absolute:
float used_fixedLowerEndValueOfScale = (chart_thisAxisIsPartOf.chartInspector_component == null) ? fixedLowerEndValueOfScale : fixedLowerEndValueOfScale_duringInspectionComponentPhases;
float used_fixedUpperEndValueOfScale = (chart_thisAxisIsPartOf.chartInspector_component == null) ? fixedUpperEndValueOfScale : fixedUpperEndValueOfScale_duringInspectionComponentPhases;
if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(used_fixedLowerEndValueOfScale, used_fixedUpperEndValueOfScale))
{
Debug.LogWarning("Chart: Don't set 'fixedLowerEndValueOfScale' and 'fixedUpperEndValueOfScale' to the same value. Both are currently " + used_fixedLowerEndValueOfScale + ". Fallback -> automatic widening.");
float paddingAtEachSide = 1.6f;
valueMarkingLowerEndOfTheAxis = used_fixedLowerEndValueOfScale - paddingAtEachSide;
valueMarkingUpperEndOfTheAxis = used_fixedLowerEndValueOfScale + paddingAtEachSide;
}
else
{
if (used_fixedLowerEndValueOfScale < used_fixedUpperEndValueOfScale)
{
valueMarkingLowerEndOfTheAxis = used_fixedLowerEndValueOfScale;
valueMarkingUpperEndOfTheAxis = used_fixedUpperEndValueOfScale;
}
else
{
valueMarkingLowerEndOfTheAxis = used_fixedUpperEndValueOfScale;
valueMarkingUpperEndOfTheAxis = used_fixedLowerEndValueOfScale;
}
}
return;
default:
valueMarkingLowerEndOfTheAxis = 0.0f;
valueMarkingUpperEndOfTheAxis = 1.0f;
Debug.LogError("ScalingType of " + used_scaling + " not implemented.");
return;
}
}
public bool HasAFixedScalingType()
{
//-> this function is currently only fit for cases without chart components.
//-> cases with chart components always have a fixed scaling.
switch (scaling)
{
case Scaling.dynamic_encapsulateAllValues_includingThoseOutsideOfOtherAxisDisplay:
return false;
case Scaling.dynamic_encapsulateAllValues_butOnlyThoseInsideOfOtherAxisDisplay:
return false;
case Scaling.fixed_relativeToHighestValue:
return true;
case Scaling.fixed_relativeToLowestValue:
return true;
case Scaling.fixed_relativeToMostCurrentValue:
return true;
case Scaling.fixed_absolute:
return true;
default:
return true;
}
}
float GetMostCurrentValueOfAllLines()
{
if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x)
{
return chart_thisAxisIsPartOf.lines.GetMostCurrentXValueOfAllLines();
}
else
{
return chart_thisAxisIsPartOf.lines.GetMostCurrentYValueOfAllLines();
}
}
float GetLowestValueOfAllLines()
{
if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x)
{
return chart_thisAxisIsPartOf.lines.GetLowestXValueOfAllLines();
}
else
{
return chart_thisAxisIsPartOf.lines.GetLowestYValueOfAllLines();
}
}
float GetHighestValueOfAllLines()
{
if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x)
{
return chart_thisAxisIsPartOf.lines.GetHighestXValueOfAllLines();
}
else
{
return chart_thisAxisIsPartOf.lines.GetHighestYValueOfAllLines();
}
}
float GetLowestValueOfAllLines_insideSpanOfOtherAxis()
{
if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x)
{
return chart_thisAxisIsPartOf.lines.GetLowestXValueOfAllLines_insideRestricedYSpan(theOtherAxis.valueMarkingLowerEndOfTheAxis, theOtherAxis.valueMarkingUpperEndOfTheAxis);
}
else
{
return chart_thisAxisIsPartOf.lines.GetLowestYValueOfAllLines_insideRestricedXSpan(theOtherAxis.valueMarkingLowerEndOfTheAxis, theOtherAxis.valueMarkingUpperEndOfTheAxis);
}
}
float GetHighestValueOfAllLines_insideSpanOfOtherAxis()
{
if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x)
{
return chart_thisAxisIsPartOf.lines.GetHighestXValueOfAllLines_insideRestricedYSpan(theOtherAxis.valueMarkingLowerEndOfTheAxis, theOtherAxis.valueMarkingUpperEndOfTheAxis);
}
else
{
return chart_thisAxisIsPartOf.lines.GetHighestYValueOfAllLines_insideRestricedXSpan(theOtherAxis.valueMarkingLowerEndOfTheAxis, theOtherAxis.valueMarkingUpperEndOfTheAxis);
}
}
void TryExpandInvalidZeroSpanBesideAnchor()
{
if (UtilitiesDXXL_Math.ApproximatelyZero(fixedDisplayedSpan_belowAnchorValue))
{
if (UtilitiesDXXL_Math.ApproximatelyZero(fixedDisplayedSpan_aboveAnchorValue))
{
Debug.LogWarning("Chart: Don't set 'displayedSpan_belowAnchorValue' and 'displayedSpan_aboveAnchorValue' both to 0. Fallback -> automatic widening.");
float fallbackSpanForEachSide = 1.6f;
fixedDisplayedSpan_belowAnchorValue = fallbackSpanForEachSide;
fixedDisplayedSpan_aboveAnchorValue = fallbackSpanForEachSide;
}
}
}
float GetMinValueBesideAnchor(float anchorValue)
{
return (anchorValue - Mathf.Abs(fixedDisplayedSpan_belowAnchorValue));
}
float GetMaxValueBesideAnchor(float anchorValue)
{
return (anchorValue + Mathf.Abs(fixedDisplayedSpan_aboveAnchorValue));
}
void DrawAxisGraduation(float durationInSec, bool hiddenByNearerObjects)
{
posOfGraduationMarks_inChartSpace.Clear();
float approxGraduationInterval = lowerEndOfAxisToUpperEnd_inChartUnits / (float)approxNumberOfGraduationIntervals;
bool calculationOf_orderOfMagnitudeWasSuccesful;
float decimalOrderOfMagnitude_markingLowerEndOfGraduationInterval = UtilitiesDXXL_Math.GetDecimalOrderOfMagnitudeAtLowerEnd(approxGraduationInterval, out float inverseOf_decimalOrderOfMagnitude_markingLowerEndOfGraduationInterval, out calculationOf_orderOfMagnitudeWasSuccesful);
if (UtilitiesDXXL_Math.ApproximatelyZero(approxGraduationInterval) || (calculationOf_orderOfMagnitudeWasSuccesful == false))
{
Debug.LogWarning("Chart: Failed to draw graduation marks. Approximate graduation interval: " + approxGraduationInterval);
}
else
{
float approxGraduationInterval_withShiftedDecimalSeparatorTillItsInside1toExcl10 = approxGraduationInterval * inverseOf_decimalOrderOfMagnitude_markingLowerEndOfGraduationInterval;
float approxGraduationInterval_inside1toExcl10_roundedToInt = Mathf.Floor(approxGraduationInterval_withShiftedDecimalSeparatorTillItsInside1toExcl10);
float graduationInterval_inChartSpaceUnits = approxGraduationInterval_inside1toExcl10_roundedToInt * decimalOrderOfMagnitude_markingLowerEndOfGraduationInterval;
//lowest mark:
float lowEndOfAxis_butDecimalSeparatorHasBeenShiftedTheNumberOfTimesThatTheIntervalNeededTillItReached1toExcl10 = valueMarkingLowerEndOfTheAxis * inverseOf_decimalOrderOfMagnitude_markingLowerEndOfGraduationInterval;
float lowEndOfAxis_shifted_rounded = Mathf.Floor(lowEndOfAxis_butDecimalSeparatorHasBeenShiftedTheNumberOfTimesThatTheIntervalNeededTillItReached1toExcl10);
float graduationAnchorPos_below_lowEndOfAxis = lowEndOfAxis_shifted_rounded * decimalOrderOfMagnitude_markingLowerEndOfGraduationInterval;
int maxNumberOfGraduationMarks = approxNumberOfGraduationIntervals * 2 + 5;
for (int i = 0; i < maxNumberOfGraduationMarks; i++)
{
float currGraduationMarkPos = graduationAnchorPos_below_lowEndOfAxis + graduationInterval_inChartSpaceUnits * i;
if (currGraduationMarkPos >= valueMarkingLowerEndOfTheAxis && currGraduationMarkPos < valueMarkingUpperEndOfTheAxis)
{
//fixing values like "0.0999999999" to "0.1":
float currGraduationMarkPos_butDecimalSeparatorHasBeenShiftedTheNumberOfTimesThatTheIntervalNeededTillItReached1toExcl10 = currGraduationMarkPos * inverseOf_decimalOrderOfMagnitude_markingLowerEndOfGraduationInterval;
float currGraduationMarkPos_shifted_rounded = Mathf.Round(currGraduationMarkPos_butDecimalSeparatorHasBeenShiftedTheNumberOfTimesThatTheIntervalNeededTillItReached1toExcl10);
decimal currGraduationMarkPos_rounded = (decimal)currGraduationMarkPos_shifted_rounded * (decimal)decimalOrderOfMagnitude_markingLowerEndOfGraduationInterval;
posOfGraduationMarks_inChartSpace.Add((float)currGraduationMarkPos_rounded);
}
if (currGraduationMarkPos >= valueMarkingUpperEndOfTheAxis)
{
break;
}
}
if (posOfGraduationMarks_inChartSpace.Count > 0)
{
DrawGraduationMarks(graduationInterval_inChartSpaceUnits, durationInSec, hiddenByNearerObjects);
}
}
}
float maxTextSize_relToGraduationInterval = 0.45f;
float graduationTextExtent_perpToAxis;
void DrawGraduationMarks(float graduationInterval_inChartSpaceUnits, float durationInSec, bool hiddenByNearerObjects)
{
float lengthOfFullAlphaGraduationLine = 0.03f * length_inWorldSpace;
Color textColor = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(chart_thisAxisIsPartOf.color, alphaOfGraduationNotation);
Color color_ofLowAlphaGraduationLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(chart_thisAxisIsPartOf.color, alphaOfGraduationLinesInsideDataArea);
Quaternion rotation_fromChartRotation_toSkewedText = default;
float textSize_worldSpace = 0.0f;
bool textIsDrawn = !UtilitiesDXXL_Math.ApproximatelyZero(alphaOfGraduationNotation);
float graduationInterval_inWorldSpaceUnits = graduationInterval_inChartSpaceUnits * lengthConversionFactor_fromChartScaling_toWorldScaling;
bool textDirIsSkewed_inChartsLocalSpace = false;
graduationTextExtent_perpToAxis = 0.0f;
if (textIsDrawn)
{
if (graduationTypesetting_isManually)
{
textSize_worldSpace = graduationTextSize_relToAxisLength * length_inWorldSpace;
}
else
{
textSize_worldSpace = 0.02f * length_inWorldSpace;
}
if (cartesianDimension == UtilitiesDXXL_Math.Dimension.y)
{
if (graduationTypesetting_isManually == false)
{
textSize_worldSpace = Mathf.Min(textSize_worldSpace, maxTextSize_relToGraduationInterval * graduationInterval_inWorldSpaceUnits);
}
}
int numberOfLetters_ofLongestGraduationText = 0;
graduationMarksTexts.Clear();
for (int i = 0; i < posOfGraduationMarks_inChartSpace.Count; i++)
{
graduationMarksTexts.Add("" + posOfGraduationMarks_inChartSpace[i]);
numberOfLetters_ofLongestGraduationText = Mathf.Max(numberOfLetters_ofLongestGraduationText, graduationMarksTexts[i].Length);
}
float length_ofLongestGraduationText_worldSpace_preFinalTextSizeForce = textSize_worldSpace * numberOfLetters_ofLongestGraduationText;
graduationTextExtent_perpToAxis = length_ofLongestGraduationText_worldSpace_preFinalTextSizeForce; //used by y-axis. x-axis overwrites below
if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x)
{
if (graduationTypesetting_isManually)
{
used_angleDeg_ofAxisGraduationNotationText = angleDeg_ofAxisGraduationNotationText;
}
else
{
if (length_ofLongestGraduationText_worldSpace_preFinalTextSizeForce < (0.9f * graduationInterval_inWorldSpaceUnits))
{
used_angleDeg_ofAxisGraduationNotationText = 0.0f;
}
else
{
if (posOfGraduationMarks_inChartSpace.Count <= 18)
{
used_angleDeg_ofAxisGraduationNotationText = -45.0f;
textSize_worldSpace = Mathf.Min(textSize_worldSpace, 0.8f * maxTextSize_relToGraduationInterval * graduationInterval_inWorldSpaceUnits);
}
else
{
used_angleDeg_ofAxisGraduationNotationText = -90.0f;
textSize_worldSpace = Mathf.Min(textSize_worldSpace, maxTextSize_relToGraduationInterval * graduationInterval_inWorldSpaceUnits);
}
}
}
textDirIsSkewed_inChartsLocalSpace = !UtilitiesDXXL_Math.ApproximatelyZero(used_angleDeg_ofAxisGraduationNotationText);
if (textDirIsSkewed_inChartsLocalSpace)
{
rotation_fromChartRotation_toSkewedText = Quaternion.AngleAxis(used_angleDeg_ofAxisGraduationNotationText, Vector3.forward);
float length_ofLongestGraduationText_worldSpace_postFinalTextSizeForce = textSize_worldSpace * numberOfLetters_ofLongestGraduationText;
float absSine = Mathf.Sin(Mathf.Deg2Rad * Mathf.Abs(used_angleDeg_ofAxisGraduationNotationText));
graduationTextExtent_perpToAxis = textSize_worldSpace + length_ofLongestGraduationText_worldSpace_postFinalTextSizeForce * absSine;
}
else
{
graduationTextExtent_perpToAxis = textSize_worldSpace * UtilitiesDXXL_Text.relLineDistance;
}
}
}
for (int i = 0; i < posOfGraduationMarks_inChartSpace.Count; i++)
{
if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; }
DrawGraduationMark(i, posOfGraduationMarks_inChartSpace[i], textIsDrawn, textSize_worldSpace, lengthOfFullAlphaGraduationLine, color_ofLowAlphaGraduationLine, textColor, textDirIsSkewed_inChartsLocalSpace, rotation_fromChartRotation_toSkewedText, durationInSec, hiddenByNearerObjects);
}
}
void DrawGraduationMark(int i_graduationMark, float graduationMarkPosition_chartSpace, bool textIsDrawn, float textSize_worldSpace, float lengthOfFullAlphaGraduationLine, Color color_ofLowAlphaGraduationLine, Color textColor, bool textDirIsSkewed_inChartsLocalSpace, Quaternion rotation_fromChartRotation_toSkewedText, float durationInSec, bool hiddenByNearerObjects)
{
Vector2 start_ofFullAlphaGraduationLine_chartSpace;
if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x)
{
start_ofFullAlphaGraduationLine_chartSpace = new Vector2(graduationMarkPosition_chartSpace, theOtherAxis.ValueMarkingLowerEndOfTheAxis);
}
else
{
start_ofFullAlphaGraduationLine_chartSpace = new Vector2(theOtherAxis.ValueMarkingLowerEndOfTheAxis, graduationMarkPosition_chartSpace);
}
Vector3 start_ofFullAlphaGraduationLine_worldSpace = chart_thisAxisIsPartOf.ChartSpace_to_WorldSpace(start_ofFullAlphaGraduationLine_chartSpace);
Vector3 end_ofFullAlphaGraduationLine_worldSpace = start_ofFullAlphaGraduationLine_worldSpace - lengthOfFullAlphaGraduationLine * theOtherAxis.AxisVector_normalized_inWorldSpace;
Vector3 end_ofLowAlphaGraduationLine_worldSpace = start_ofFullAlphaGraduationLine_worldSpace + theOtherAxis.axisVector_inWorldSpace;
Line_fadeableAnimSpeed.InternalDraw(start_ofFullAlphaGraduationLine_worldSpace, end_ofFullAlphaGraduationLine_worldSpace, chart_thisAxisIsPartOf.color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false);
if (alphaOfGraduationLinesInsideDataArea > 0.0f)
{
Vector3 start_ofLowAlphaGraduationLine_worldSpace = start_ofFullAlphaGraduationLine_worldSpace;
Line_fadeableAnimSpeed.InternalDraw(start_ofLowAlphaGraduationLine_worldSpace, end_ofLowAlphaGraduationLine_worldSpace, color_ofLowAlphaGraduationLine, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false);
}
if (textIsDrawn)
{
DrawTextAtGraduationMark(i_graduationMark, textSize_worldSpace, textColor, textDirIsSkewed_inChartsLocalSpace, end_ofFullAlphaGraduationLine_worldSpace, rotation_fromChartRotation_toSkewedText, durationInSec, hiddenByNearerObjects);
}
}
void DrawTextAtGraduationMark(int i_graduationMark, float textSize_worldSpace, Color textColor, bool textDirIsSkewed_inChartsLocalSpace, Vector3 end_ofFullAlphaGraduationLine_worldSpace, Quaternion rotation_fromChartRotation_toSkewedText, float durationInSec, bool hiddenByNearerObjects)
{
string notationText = graduationMarksTexts[i_graduationMark];
if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x)
{
Vector3 textPosition = end_ofFullAlphaGraduationLine_worldSpace;
Quaternion textRotation;
DrawText.TextAnchorDXXL textAnchor;
if (textDirIsSkewed_inChartsLocalSpace)
{
textRotation = chart_thisAxisIsPartOf.InternalRotation * rotation_fromChartRotation_toSkewedText;
if (used_angleDeg_ofAxisGraduationNotationText < 0.0f)
{
//clockwise rotation:
textAnchor = DrawText.TextAnchorDXXL.MiddleLeft;
}
else
{
//counter clockwise rotation:
textAnchor = DrawText.TextAnchorDXXL.MiddleRight;
}
}
else
{
textRotation = chart_thisAxisIsPartOf.InternalRotation;
textAnchor = DrawText.TextAnchorDXXL.UpperCenter;
}
UtilitiesDXXL_Text.WriteFramed(notationText, textPosition, textColor, textSize_worldSpace, textRotation, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, chart_thisAxisIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects);
}
else
{
Vector3 textPosition = end_ofFullAlphaGraduationLine_worldSpace - 0.01f * length_inWorldSpace * theOtherAxis.AxisVector_normalized_inWorldSpace;
DrawText.TextAnchorDXXL textAnchor = DrawText.TextAnchorDXXL.MiddleRight;
UtilitiesDXXL_Text.WriteFramed(notationText, textPosition, textColor, textSize_worldSpace, chart_thisAxisIsPartOf.InternalRotation, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, chart_thisAxisIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects);
}
}
void DrawChartBoundaryLine_inTheStyleOfAGraduationLine(float durationInSec, bool hiddenByNearerObjects)
{
Color color_ofLowAlphaGraduationLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(chart_thisAxisIsPartOf.color, alphaOfGraduationLinesInsideDataArea);
Vector3 startPos_worldSpace = chart_thisAxisIsPartOf.Position_worldspace + AxisVector_inWorldSpace;
Vector3 endPos_worldSpace = startPos_worldSpace + theOtherAxis.AxisVector_inWorldSpace;
Line_fadeableAnimSpeed.InternalDraw(startPos_worldSpace, endPos_worldSpace, color_ofLowAlphaGraduationLine, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false);
}
void DrawAxisName(float durationInSec, bool hiddenByNearerObjects)
{
string drawnName = null;
if (nameHasBeenManuallySet)
{
drawnName = name;
}
else
{
if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x)
{
if (allXValuesCameFromAutomaticSource)
{
drawnName = GetAxisNameForAutomaticSources();
}
else
{
drawnName = "[unknown unit]";
}
}
}
if (drawnName != null && drawnName != "")
{
if (UtilitiesDXXL_Math.ApproximatelyZero(nameText_scaleFactor) == false)
{
Vector3 textPosition_worldSpace;
DrawText.TextAnchorDXXL textAnchor;
float autoLineBreakWidth = length_inWorldSpace;
float textSize = Mathf.Abs(nameText_scaleFactor) * 0.03f * length_inWorldSpace;
switch (cartesianDimension)
{
case UtilitiesDXXL_Math.Dimension.x:
textPosition_worldSpace = chart_thisAxisIsPartOf.Position_worldspace + 0.5f * axisVector_inWorldSpace - theOtherAxis.AxisVector_normalized_inWorldSpace * (graduationTextExtent_perpToAxis + 0.05f * length_inWorldSpace);
textAnchor = DrawText.TextAnchorDXXL.UpperCenter;
UtilitiesDXXL_Text.WriteFramed(drawnName, textPosition_worldSpace, chart_thisAxisIsPartOf.color, textSize, chart_thisAxisIsPartOf.InternalRotation, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, autoLineBreakWidth, chart_thisAxisIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects);
break;
case UtilitiesDXXL_Math.Dimension.y:
textPosition_worldSpace = chart_thisAxisIsPartOf.Position_worldspace + 0.5f * axisVector_inWorldSpace - theOtherAxis.AxisVector_normalized_inWorldSpace * (graduationTextExtent_perpToAxis + 0.07f * length_inWorldSpace);
textAnchor = DrawText.TextAnchorDXXL.LowerCenter;
Quaternion rotationLocalInsideChart = Quaternion.AngleAxis(90.0f, Vector3.forward);
Quaternion textRotation = chart_thisAxisIsPartOf.InternalRotation * rotationLocalInsideChart;
UtilitiesDXXL_Text.WriteFramed(drawnName, textPosition_worldSpace, chart_thisAxisIsPartOf.color, textSize, textRotation, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, autoLineBreakWidth, chart_thisAxisIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects);
break;
default:
break;
}
}
}
}
string GetAxisNameForAutomaticSources()
{
switch (sourceOfAutomaticValues)
{
case SourceOfAutomaticValues.fixedStepForEachValueAdding:
return "data points";
case SourceOfAutomaticValues.fixedStep_followingTheManualIncrementFunction:
return "manually triggered increments";
case SourceOfAutomaticValues.frameCount:
return "frame count (Update)";
case SourceOfAutomaticValues.fixedTime:
return "fixed time [seconds]";
case SourceOfAutomaticValues.fixedUnscaledTime:
return "fixed unscaled time [seconds]";
case SourceOfAutomaticValues.realtimeSinceStartup:
return "realtime since startup [seconds]";
case SourceOfAutomaticValues.time:
return "time [seconds]";
case SourceOfAutomaticValues.timeSinceLevelLoad:
return "time since level load [seconds]";
case SourceOfAutomaticValues.unscaledTime:
return "unscaled time [seconds]";
case SourceOfAutomaticValues.editorTimeSinceStartup:
return "Editor time since startup [seconds]";
default:
return null;
}
}
public void ReportXValueFromNonAutomaticSource()
{
allXValuesCameFromAutomaticSource = false;
}
public void ChartUpdatesAxisDirectionVectors(Quaternion newChartRotation)
{
//Don't call this function manually. Use "chartDrawing.Rotation" and "chartDrawing.Width_inWorldSpace" and "chartDrawing.Height_inWorldSpace" instead.
axisVector_normalized_inWorldSpace = newChartRotation * unrotated_axisVector_normalized_inWorldSpace;
axisVector_inWorldSpace = axisVector_normalized_inWorldSpace * length_inWorldSpace;
}
public void ChartUpdatesAxisLength(float newLength)
{
//Don't call this function manually. Use "chartDrawing.Width_inWorldSpace" and "chartDrawing.Height_inWorldSpace" instead.
axisVector_inWorldSpace = axisVector_normalized_inWorldSpace * newLength;
length_inWorldSpace = newLength;
}
public bool IsInsideDisplayedSpan(float valueToCheckIfItIsInsideTheDisplayedSpan)
{
//same as in "ChartDrawing.ChartSpace_to_WorldSpace"
//if you want to check both dimensions at once you can use "chartDrawing.IsInsideDrawnChartArea"
if (valueToCheckIfItIsInsideTheDisplayedSpan >= valueMarkingLowerEndOfTheAxis)
{
if (valueToCheckIfItIsInsideTheDisplayedSpan <= valueMarkingUpperEndOfTheAxis)
{
return true;
}
}
return false;
}
public bool IsLowerThanDisplayedSpan(float valueToCheckIfItIsLowerThanTheDisplayedSpan)
{
//same as in "ChartDrawing.ChartSpace_to_WorldSpace"
return (valueToCheckIfItIsLowerThanTheDisplayedSpan < valueMarkingLowerEndOfTheAxis);
}
public bool IsHigherThanDisplayedSpan(float valueToCheckIfItIsHigherThanTheDisplayedSpan)
{
//same as in "ChartDrawing.ChartSpace_to_WorldSpace"
return (valueToCheckIfItIsHigherThanTheDisplayedSpan > valueMarkingUpperEndOfTheAxis);
}
static DrawBasics.LineStyle lineStyle_forZeroPositionMarker = DrawBasics.LineStyle.dashed;
void CreatePointsOfInterest_thatDisplaysTheZeroPositionAsDottedLine(out PointOfInterest created_pointOfInterest_displayingTheZeroPositionLine, out PointOfInterest created_pointOfInterest_displayingTheZeroPositionLine_lowAlphaUnderlay)
{
created_pointOfInterest_displayingTheZeroPositionLine = CreatePointOfInterest_thatDisplaysTheZeroPositionAsDottedLine(lineStyle_forZeroPositionMarker, 0.40f);
created_pointOfInterest_displayingTheZeroPositionLine_lowAlphaUnderlay = CreatePointOfInterest_thatDisplaysTheZeroPositionAsDottedLine(DrawBasics.LineStyle.solid, 0.15f);
}
PointOfInterest CreatePointOfInterest_thatDisplaysTheZeroPositionAsDottedLine(DrawBasics.LineStyle lineStyle, float alpha)
{
Color color = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(chart_thisAxisIsPartOf.color, alpha);
PointOfInterest created_pointOfInterest = new PointOfInterest(0.0f, 0.0f, color, chart_thisAxisIsPartOf, null, null);
created_pointOfInterest.drawTextBoxIfPointIsOutsideOfChartArea = false;
created_pointOfInterest.isDeletedOnClear = false;
created_pointOfInterest.forceColorOfParent = true;
if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x)
{
created_pointOfInterest.xValue.lineStyle = lineStyle;
created_pointOfInterest.xValue.linestylePatternScaleFactor = 0.75f;
created_pointOfInterest.xValue.drawCoordinateAsText = true;
created_pointOfInterest.xValue.lineExtent = DimensionOf_PointOfInterest.LineExtent.throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart;
created_pointOfInterest.yValue.lineStyle = DrawBasics.LineStyle.invisible;
}
else
{
created_pointOfInterest.yValue.lineStyle = lineStyle;
created_pointOfInterest.yValue.linestylePatternScaleFactor = 0.75f;
created_pointOfInterest.yValue.drawCoordinateAsText = true;
created_pointOfInterest.yValue.lineExtent = DimensionOf_PointOfInterest.LineExtent.throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart;
created_pointOfInterest.xValue.lineStyle = DrawBasics.LineStyle.invisible;
}
return created_pointOfInterest;
}
void SetIf_pointOfInterestDisplayingTheZeroPositionLine_isDisplayed()
{
if (cartesianDimension == UtilitiesDXXL_Math.Dimension.x)
{
if (drawZeroPositionAsDottedLine)
{
pointOfInterest_displayingTheZeroPositionLine.xValue.lineStyle = lineStyle_forZeroPositionMarker;
pointOfInterest_displayingTheZeroPositionLine_lowAlphaUnderlay.xValue.lineStyle = DrawBasics.LineStyle.solid;
}
else
{
pointOfInterest_displayingTheZeroPositionLine.xValue.lineStyle = DrawBasics.LineStyle.invisible;
pointOfInterest_displayingTheZeroPositionLine_lowAlphaUnderlay.xValue.lineStyle = DrawBasics.LineStyle.invisible;
}
}
else
{
if (drawZeroPositionAsDottedLine)
{
pointOfInterest_displayingTheZeroPositionLine.yValue.lineStyle = lineStyle_forZeroPositionMarker;
pointOfInterest_displayingTheZeroPositionLine_lowAlphaUnderlay.yValue.lineStyle = DrawBasics.LineStyle.solid;
}
else
{
pointOfInterest_displayingTheZeroPositionLine.yValue.lineStyle = DrawBasics.LineStyle.invisible;
pointOfInterest_displayingTheZeroPositionLine_lowAlphaUnderlay.yValue.lineStyle = DrawBasics.LineStyle.invisible;
}
}
}
public void SetAxisScalingDuringInspectionComponentPhases(float fixedLowerEndValueOfScale, float fixedUpperEndValueOfScale)
{
if (UtilitiesDXXL_Math.FloatIsValid(fixedLowerEndValueOfScale))
{
fixedLowerEndValueOfScale_duringInspectionComponentPhases = fixedLowerEndValueOfScale;
}
else
{
fixedLowerEndValueOfScale_duringInspectionComponentPhases = -100.0f;
}
if (UtilitiesDXXL_Math.FloatIsValid(fixedUpperEndValueOfScale))
{
fixedUpperEndValueOfScale_duringInspectionComponentPhases = fixedUpperEndValueOfScale;
}
else
{
fixedUpperEndValueOfScale_duringInspectionComponentPhases = 100.0f;
}
RecalcScaling();
}
public void GetAxisEndsIfAllNonHiddenValuesAreEncapsulated(out float lowEnd, out float upperEnd)
{
float lowestValueOfAllLines = GetLowestValueOfAllLines();
float highestValueOfAllLines = GetHighestValueOfAllLines();
GetAxisEndsIfAllValuesAreEncapsulated_inclPadding(out lowEnd, out upperEnd, lowestValueOfAllLines, highestValueOfAllLines);
}
public void GetAxisEndsIfAllNonHiddenValuesInsideOtherAxisSpanAreEncapsulated(out float lowEnd, out float upperEnd)
{
float lowestValueOfAllLines_insideSpanOfOtherAxis = GetLowestValueOfAllLines_insideSpanOfOtherAxis();
float highestValueOfAllLines_insideSpanOfOtherAxis = GetHighestValueOfAllLines_insideSpanOfOtherAxis();
if (float.IsInfinity(lowestValueOfAllLines_insideSpanOfOtherAxis) || float.IsInfinity(highestValueOfAllLines_insideSpanOfOtherAxis))
{
//-> no value has been found inside the restricted axis span:
lowestValueOfAllLines_insideSpanOfOtherAxis = 0.0f;
highestValueOfAllLines_insideSpanOfOtherAxis = 0.0f;
}
GetAxisEndsIfAllValuesAreEncapsulated_inclPadding(out lowEnd, out upperEnd, lowestValueOfAllLines_insideSpanOfOtherAxis, highestValueOfAllLines_insideSpanOfOtherAxis);
}
public void GetAxisEndsIfAllValuesAreEncapsulated_inclPadding(out float lowEnd, out float upperEnd, float lowestDisplayedValue, float highestDisplayedValue)
{
if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(lowestDisplayedValue, highestDisplayedValue))
{
float paddingAtEachSide = 1.6f;
lowEnd = lowestDisplayedValue - paddingAtEachSide;
upperEnd = lowestDisplayedValue + paddingAtEachSide;
}
else
{
float span_fromLowestToHighest = highestDisplayedValue - lowestDisplayedValue;
float additionalPadding_atEachside = span_fromLowestToHighest * 0.05f;
lowEnd = lowestDisplayedValue - additionalPadding_atEachside;
upperEnd = highestDisplayedValue + additionalPadding_atEachside;
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c2ce6ec8d412c824d99e259a4e207f39
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: afc487da656a5634dac1e97c4355dec4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 051a68451ba2f49419c91170b3f49f91
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b7375d9685841fd498fb7395e665d967
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,95 @@
namespace DrawXXL
{
public class DataComponentsThatAreDrawn
{
//Vector2:
public bool vector2_x = true;
public bool vector2_y = true;
//Vector3:
public bool vector3_x = true;
public bool vector3_y = true;
public bool vector3_z = true;
//Vector4:
public bool vector4_x = true;
public bool vector4_y = true;
public bool vector4_z = true;
public bool vector4_w = true;
//Color:
public bool color_r = true;
public bool color_g = true;
public bool color_b = true;
public bool color_a = true;
//Rotation:
public bool rotation_eulerX = true;
public bool rotation_eulerY = true;
public bool rotation_eulerZ = true;
//Transform:
public bool localPosition_x = true;
public bool localPosition_y = true;
public bool localPosition_z = true;
public bool localEulerAngle_x = false;
public bool localEulerAngle_y = false;
public bool localEulerAngle_z = false;
public bool localScale_x = false;
public bool localScale_y = false;
public bool localScale_z = false;
public bool globalPosition_x = false;
public bool globalPosition_y = false;
public bool globalPosition_z = false;
public bool globalEulerAngle_x = false;
public bool globalEulerAngle_y = false;
public bool globalEulerAngle_z = false;
public bool lossyScale_x = false;
public bool lossyScale_y = false;
public bool lossyScale_z = false;
public void CopyValueFromOtherConfig(DataComponentsThatAreDrawn newConfig)
{
vector2_x = newConfig.vector2_x;
vector2_y = newConfig.vector2_y;
vector3_x = newConfig.vector3_x;
vector3_y = newConfig.vector3_y;
vector3_z = newConfig.vector3_z;
vector4_x = newConfig.vector4_x;
vector4_y = newConfig.vector4_y;
vector4_z = newConfig.vector4_z;
vector4_w = newConfig.vector4_w;
color_r = newConfig.color_r;
color_g = newConfig.color_g;
color_b = newConfig.color_b;
color_a = newConfig.color_a;
rotation_eulerX = newConfig.rotation_eulerX;
rotation_eulerY = newConfig.rotation_eulerY;
rotation_eulerZ = newConfig.rotation_eulerZ;
localPosition_x = newConfig.localPosition_x;
localPosition_y = newConfig.localPosition_y;
localPosition_z = newConfig.localPosition_z;
localEulerAngle_x = newConfig.localEulerAngle_x;
localEulerAngle_y = newConfig.localEulerAngle_y;
localEulerAngle_z = newConfig.localEulerAngle_z;
localScale_x = newConfig.localScale_x;
localScale_y = newConfig.localScale_y;
localScale_z = newConfig.localScale_z;
globalPosition_x = newConfig.globalPosition_x;
globalPosition_y = newConfig.globalPosition_y;
globalPosition_z = newConfig.globalPosition_z;
globalEulerAngle_x = newConfig.globalEulerAngle_x;
globalEulerAngle_y = newConfig.globalEulerAngle_y;
globalEulerAngle_z = newConfig.globalEulerAngle_z;
lossyScale_x = newConfig.lossyScale_x;
lossyScale_y = newConfig.lossyScale_y;
lossyScale_z = newConfig.lossyScale_z;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 60d9d04a4f7323747aaf7b1253d4d4f3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,413 @@
namespace DrawXXL
{
using UnityEngine;
public class DimensionOf_PointOfInterest
{
public enum LineExtent { axisToPoint, throughWholeChart_ifOtherDimensionsValueIsInsideChart, throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart }
private static float sizeOfLabeltext_relToChartHeight = 0.02f;
public static float SizeOfLabeltext_relToChartHeight //this changes globally for all PointsOfInterest
{
get { return sizeOfLabeltext_relToChartHeight; }
set { sizeOfLabeltext_relToChartHeight = Mathf.Max(value, 0.002f); }
}
private static float sizeOfCoordinateText_relToChartHeight = 0.02f;
public static float SizeOfCoordinateText_relToChartHeight //this changes globally for all PointsOfInterest
{
get { return sizeOfCoordinateText_relToChartHeight; }
set { sizeOfCoordinateText_relToChartHeight = Mathf.Max(value, 0.002f); }
}
public float position;
public DrawBasics.LineStyle lineStyle = DrawBasics.LineStyle.solid;
public float lineWidth_relToChartHeight = 0.0f;
public float linestylePatternScaleFactor = 1.0f;
public string labelText; //is only drawn if lineStyle is not invisible
public bool drawCoordinateAsText = true; //"lineStyle is invisible" also disables the drawing of the coordinate value
public Color color;
public LineExtent lineExtent = LineExtent.throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart;
UtilitiesDXXL_Math.Dimension representedDimension;
ChartDrawing chart_thisPointIsPartOf;
public DimensionOf_PointOfInterest theOtherDimension;
float currLineWidth_inWorldUnits;
public bool placeTextTowardsOutsideOfChart = false; //By default the labelText at the horizontal or vertical lines is mounted at the x respectively y axis and extends towards the inside of the chart. Setting "placeTextTowardsOutsideOfChart" to "true" shifts the "labelText", so it extends towards the outside of the chart. It is useful if you have many labelTexts from different points of interest in the chart, that intersect each other and are therefore not readable anymore. In such cases you gain some more breathing space for displayed texts.
public DimensionOf_PointOfInterest(float position, Color color, UtilitiesDXXL_Math.Dimension representedDimension, ChartDrawing chart_thisPointIsPartOf)
{
//use ChartDrawing.AddPointOfInterest() instead
this.position = position;
this.color = color;
this.representedDimension = representedDimension;
this.chart_thisPointIsPartOf = chart_thisPointIsPartOf;
}
public void Draw(float durationInSec, bool hiddenByNearerObjects)
{
//use ChartDrawing.Draw() instead
if (representedDimension == UtilitiesDXXL_Math.Dimension.x)
{
bool lineHasBeenDrawn = DrawVertLineAtXPos(durationInSec, hiddenByNearerObjects);
DrawCoordinateText_vertForXValues(lineHasBeenDrawn, durationInSec, hiddenByNearerObjects);
DrawLabelText_vertForXValues(lineHasBeenDrawn, durationInSec, hiddenByNearerObjects);
}
else
{
bool lineHasBeenDrawn = DrawHorizLineAtYPos(durationInSec, hiddenByNearerObjects);
DrawCoordinateText_horizForYValues(lineHasBeenDrawn, durationInSec, hiddenByNearerObjects);
DrawLabelText_horizForYValues(lineHasBeenDrawn, durationInSec, hiddenByNearerObjects);
}
}
bool DrawVertLineAtXPos(float durationInSec, bool hiddenByNearerObjects)
{
//function returns if line was drawn
if (lineStyle != DrawBasics.LineStyle.invisible)
{
if (UtilitiesDXXL_Math.FloatIsValid(position))
{
Vector2 start_inChartspace = new Vector2(position, chart_thisPointIsPartOf.yAxis.ValueMarkingLowerEndOfTheAxis);
Vector2 end_inChartspace;
bool shouldBeDrawn_becauseItHasPartsInsideTheChartArea;
if (UtilitiesDXXL_Math.FloatIsValid(theOtherDimension.position))
{
switch (lineExtent)
{
case LineExtent.axisToPoint:
GetLineDrawSpecs_for_vertLineAtXPos_extentCase_axisToPoint(out shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out end_inChartspace);
break;
case LineExtent.throughWholeChart_ifOtherDimensionsValueIsInsideChart:
GetLineDrawSpecs_for_vertLineAtXPos_extentCase_throughWholeChart_ifOtherDimensionsValueIsInsideChart(out shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out end_inChartspace);
break;
case LineExtent.throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart:
GetLineDrawSpecs_for_vertLineAtXPos_extentCase_throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart(out shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out end_inChartspace);
break;
default:
UtilitiesDXXL_Log.PrintErrorCode("10-" + lineExtent);
return false;
}
}
else
{
//other dimensions position is invalid:
GetLineDrawSpecs_for_vertLineAtXPos_extentCase_throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart(out shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out end_inChartspace);
}
return TryDrawLine(shouldBeDrawn_becauseItHasPartsInsideTheChartArea, start_inChartspace, end_inChartspace, durationInSec, hiddenByNearerObjects);
}
else
{
return false;
}
}
else
{
return false;
}
}
void GetLineDrawSpecs_for_vertLineAtXPos_extentCase_axisToPoint(out bool shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out Vector2 lineEnd_inChartspace)
{
shouldBeDrawn_becauseItHasPartsInsideTheChartArea = false;
lineEnd_inChartspace = new Vector2(position, theOtherDimension.position);
if (chart_thisPointIsPartOf.xAxis.IsInsideDisplayedSpan(position))
{
if (theOtherDimension.position > chart_thisPointIsPartOf.yAxis.ValueMarkingLowerEndOfTheAxis)
{
shouldBeDrawn_becauseItHasPartsInsideTheChartArea = true;
if (theOtherDimension.position > chart_thisPointIsPartOf.yAxis.ValueMarkingUpperEndOfTheAxis)
{
lineEnd_inChartspace = new Vector2(position, chart_thisPointIsPartOf.yAxis.ValueMarkingUpperEndOfTheAxis);
}
}
}
}
void GetLineDrawSpecs_for_vertLineAtXPos_extentCase_throughWholeChart_ifOtherDimensionsValueIsInsideChart(out bool shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out Vector2 lineEnd_inChartspace)
{
shouldBeDrawn_becauseItHasPartsInsideTheChartArea = false;
lineEnd_inChartspace = new Vector2(position, chart_thisPointIsPartOf.yAxis.ValueMarkingUpperEndOfTheAxis);
if (chart_thisPointIsPartOf.xAxis.IsInsideDisplayedSpan(position))
{
if (chart_thisPointIsPartOf.yAxis.IsInsideDisplayedSpan(theOtherDimension.position))
{
shouldBeDrawn_becauseItHasPartsInsideTheChartArea = true;
}
}
}
void GetLineDrawSpecs_for_vertLineAtXPos_extentCase_throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart(out bool shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out Vector2 lineEnd_inChartspace)
{
shouldBeDrawn_becauseItHasPartsInsideTheChartArea = false;
lineEnd_inChartspace = new Vector2(position, chart_thisPointIsPartOf.yAxis.ValueMarkingUpperEndOfTheAxis);
if (chart_thisPointIsPartOf.xAxis.IsInsideDisplayedSpan(position))
{
shouldBeDrawn_becauseItHasPartsInsideTheChartArea = true;
}
}
bool DrawHorizLineAtYPos(float durationInSec, bool hiddenByNearerObjects)
{
//function returns if line was drawn
if (lineStyle != DrawBasics.LineStyle.invisible)
{
if (UtilitiesDXXL_Math.FloatIsValid(position))
{
Vector2 start_inChartspace = new Vector2(chart_thisPointIsPartOf.xAxis.ValueMarkingLowerEndOfTheAxis, position);
Vector2 end_inChartspace;
bool shouldBeDrawn_becauseItHasPartsInsideTheChartArea;
if (UtilitiesDXXL_Math.FloatIsValid(theOtherDimension.position))
{
switch (lineExtent)
{
case LineExtent.axisToPoint:
GetLineDrawSpecs_for_horizLineAtYPos_extentCase_axisToPoint(out shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out end_inChartspace);
break;
case LineExtent.throughWholeChart_ifOtherDimensionsValueIsInsideChart:
GetLineDrawSpecs_for_horizLineAtYPos_extentCase_throughWholeChart_ifOtherDimensionsValueIsInsideChart(out shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out end_inChartspace);
break;
case LineExtent.throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart:
GetLineDrawSpecs_for_horizLineAtYPos_extentCase_throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart(out shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out end_inChartspace);
break;
default:
UtilitiesDXXL_Log.PrintErrorCode("11-" + lineExtent);
return false;
}
}
else
{
//other dimensions position is invalid:
GetLineDrawSpecs_for_horizLineAtYPos_extentCase_throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart(out shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out end_inChartspace);
}
return TryDrawLine(shouldBeDrawn_becauseItHasPartsInsideTheChartArea, start_inChartspace, end_inChartspace, durationInSec, hiddenByNearerObjects);
}
else
{
return false;
}
}
else
{
return false;
}
}
void GetLineDrawSpecs_for_horizLineAtYPos_extentCase_axisToPoint(out bool shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out Vector2 lineEnd_inChartspace)
{
shouldBeDrawn_becauseItHasPartsInsideTheChartArea = false;
lineEnd_inChartspace = new Vector2(theOtherDimension.position, position);
if (chart_thisPointIsPartOf.yAxis.IsInsideDisplayedSpan(position))
{
if (theOtherDimension.position > chart_thisPointIsPartOf.xAxis.ValueMarkingLowerEndOfTheAxis)
{
shouldBeDrawn_becauseItHasPartsInsideTheChartArea = true;
if (theOtherDimension.position > chart_thisPointIsPartOf.xAxis.ValueMarkingUpperEndOfTheAxis)
{
lineEnd_inChartspace = new Vector2(chart_thisPointIsPartOf.xAxis.ValueMarkingUpperEndOfTheAxis, position);
}
}
}
}
void GetLineDrawSpecs_for_horizLineAtYPos_extentCase_throughWholeChart_ifOtherDimensionsValueIsInsideChart(out bool shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out Vector2 lineEnd_inChartspace)
{
shouldBeDrawn_becauseItHasPartsInsideTheChartArea = false;
lineEnd_inChartspace = new Vector2(chart_thisPointIsPartOf.xAxis.ValueMarkingUpperEndOfTheAxis, position);
if (chart_thisPointIsPartOf.yAxis.IsInsideDisplayedSpan(position))
{
if (chart_thisPointIsPartOf.xAxis.IsInsideDisplayedSpan(theOtherDimension.position))
{
shouldBeDrawn_becauseItHasPartsInsideTheChartArea = true;
}
}
}
void GetLineDrawSpecs_for_horizLineAtYPos_extentCase_throughWholeChart_alsoIfOtherDimensionsValueIsOutsideChart(out bool shouldBeDrawn_becauseItHasPartsInsideTheChartArea, out Vector2 lineEnd_inChartspace)
{
shouldBeDrawn_becauseItHasPartsInsideTheChartArea = false;
lineEnd_inChartspace = new Vector2(chart_thisPointIsPartOf.xAxis.ValueMarkingUpperEndOfTheAxis, position);
if (chart_thisPointIsPartOf.yAxis.IsInsideDisplayedSpan(position))
{
shouldBeDrawn_becauseItHasPartsInsideTheChartArea = true;
}
}
bool TryDrawLine(bool shouldBeDrawn_becauseItHasPartsInsideTheChartArea, Vector2 start_inChartspace, Vector2 end_inChartspace, float durationInSec, bool hiddenByNearerObjects)
{
//function returns if line was drawn
if (shouldBeDrawn_becauseItHasPartsInsideTheChartArea || chart_thisPointIsPartOf.drawValuesOutsideOfChartArea)
{
Vector3 start_inWorldspace = chart_thisPointIsPartOf.ChartSpace_to_WorldSpace(start_inChartspace);
Vector3 end_inWorldspace = chart_thisPointIsPartOf.ChartSpace_to_WorldSpace(end_inChartspace);
Vector3 customAmplitudeAndTextDir = chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace + chart_thisPointIsPartOf.yAxis.AxisVector_normalized_inWorldSpace;
float stylePatternScaleFactor_inWorldspace;
if (UtilitiesDXXL_Math.ApproximatelyZero(linestylePatternScaleFactor))
{
stylePatternScaleFactor_inWorldspace = 0.0f;
}
else
{
stylePatternScaleFactor_inWorldspace = linestylePatternScaleFactor * chart_thisPointIsPartOf.Height_inWorldSpace;
}
float widened_stylePatternScaleFactor_inWorldspace = GetStylePatternScaleFactor_widenedForDottedStyles_inWorldspace(stylePatternScaleFactor_inWorldspace);
if (UtilitiesDXXL_Math.ApproximatelyZero(lineWidth_relToChartHeight))
{
currLineWidth_inWorldUnits = 0.0f;
}
else
{
currLineWidth_inWorldUnits = lineWidth_relToChartHeight * chart_thisPointIsPartOf.Height_inWorldSpace;
}
lineStyle = UtilitiesDXXL_LineStyles.FallbackTo2DLineStyle(lineStyle);
Line_fadeableAnimSpeed.InternalDraw(start_inWorldspace, end_inWorldspace, color, currLineWidth_inWorldUnits, null, lineStyle, widened_stylePatternScaleFactor_inWorldspace, 0.0f, null, customAmplitudeAndTextDir, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, true, true);
return true;
}
else
{
return false;
}
}
void DrawCoordinateText_vertForXValues(bool vertLineHasBeenDrawnfloat, float durationInSec, bool hiddenByNearerObjects)
{
if (vertLineHasBeenDrawnfloat)
{
if (drawCoordinateAsText)
{
Vector2 position_chartspace = new Vector2(position, chart_thisPointIsPartOf.yAxis.ValueMarkingLowerEndOfTheAxis);
Vector3 posOffset_forMoreLeveledDistanceToLine = (-chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace) * (chart_thisPointIsPartOf.yAxis.Length_inWorldSpace * sizeOfCoordinateText_relToChartHeight * relAdditionalShiftOfText);
float absHalfLineWidth_inWorldUnits = Mathf.Abs(0.5f * currLineWidth_inWorldUnits);
Vector3 posOffset_forDifferentLineWidths;
DrawText.TextAnchorDXXL textAnchor;
if (labelText == null || labelText == "")
{
textAnchor = placeTextTowardsOutsideOfChart ? DrawText.TextAnchorDXXL.LowerRight : DrawText.TextAnchorDXXL.LowerLeft;
posOffset_forDifferentLineWidths = (-chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace) * absHalfLineWidth_inWorldUnits;
}
else
{
textAnchor = placeTextTowardsOutsideOfChart ? DrawText.TextAnchorDXXL.UpperRight : DrawText.TextAnchorDXXL.UpperLeft;
posOffset_forDifferentLineWidths = chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace * absHalfLineWidth_inWorldUnits;
}
Vector3 position_worldspace = chart_thisPointIsPartOf.ChartSpace_to_WorldSpace(position_chartspace) + posOffset_forMoreLeveledDistanceToLine + posOffset_forDifferentLineWidths;
float textSize = chart_thisPointIsPartOf.Height_inWorldSpace * sizeOfCoordinateText_relToChartHeight;
Vector3 textDir_normalized = chart_thisPointIsPartOf.yAxis.AxisVector_normalized_inWorldSpace;
Vector3 textUp_normalized = -chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace;
UtilitiesDXXL_Text.Write("" + position, position_worldspace, color, textSize, textDir_normalized, textUp_normalized, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, chart_thisPointIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects, false, false, true);
}
}
}
float relAdditionalShiftOfText = 0.3f;
void DrawCoordinateText_horizForYValues(bool horizLineHasBeenDrawn, float durationInSec, bool hiddenByNearerObjects)
{
if (horizLineHasBeenDrawn)
{
if (drawCoordinateAsText)
{
Vector2 position_chartspace = new Vector2(chart_thisPointIsPartOf.xAxis.ValueMarkingLowerEndOfTheAxis, position);
Vector3 posOffset_forMoreLeveledDistanceToLine = chart_thisPointIsPartOf.yAxis.AxisVector_inWorldSpace * sizeOfCoordinateText_relToChartHeight * relAdditionalShiftOfText;
float absHalfLineWidth_inWorldUnits = Mathf.Abs(0.5f * currLineWidth_inWorldUnits);
Vector3 posOffset_forDifferentLineWidths;
DrawText.TextAnchorDXXL textAnchor;
if (labelText == null || labelText == "")
{
textAnchor = placeTextTowardsOutsideOfChart ? DrawText.TextAnchorDXXL.LowerRight : DrawText.TextAnchorDXXL.LowerLeft;
posOffset_forDifferentLineWidths = chart_thisPointIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * absHalfLineWidth_inWorldUnits;
}
else
{
textAnchor = placeTextTowardsOutsideOfChart ? DrawText.TextAnchorDXXL.UpperRight : DrawText.TextAnchorDXXL.UpperLeft;
posOffset_forDifferentLineWidths = (-chart_thisPointIsPartOf.yAxis.AxisVector_normalized_inWorldSpace) * absHalfLineWidth_inWorldUnits;
}
Vector3 position_worldspace = chart_thisPointIsPartOf.ChartSpace_to_WorldSpace(position_chartspace) + posOffset_forMoreLeveledDistanceToLine + posOffset_forDifferentLineWidths;
float textSize = chart_thisPointIsPartOf.Height_inWorldSpace * sizeOfCoordinateText_relToChartHeight;
Vector3 textDir_normalized = chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace;
Vector3 textUp_normalized = chart_thisPointIsPartOf.yAxis.AxisVector_normalized_inWorldSpace;
UtilitiesDXXL_Text.Write("" + position, position_worldspace, color, textSize, textDir_normalized, textUp_normalized, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, chart_thisPointIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects, false, false, true);
}
}
}
void DrawLabelText_vertForXValues(bool vertLineHasBeenDrawn, float durationInSec, bool hiddenByNearerObjects)
{
if (vertLineHasBeenDrawn)
{
if (labelText != null && labelText != "")
{
Vector2 position_chartspace = new Vector2(position, chart_thisPointIsPartOf.yAxis.ValueMarkingLowerEndOfTheAxis);
Vector3 posOffset_forMoreLeveledDistanceToLine = (-chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace) * (chart_thisPointIsPartOf.yAxis.Length_inWorldSpace * sizeOfCoordinateText_relToChartHeight * relAdditionalShiftOfText);
float absHalfLineWidth_inWorldUnits = Mathf.Abs(0.5f * currLineWidth_inWorldUnits);
Vector3 posOffset_forDifferentLineWidths = (-chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace) * absHalfLineWidth_inWorldUnits;
Vector3 position_worldspace = chart_thisPointIsPartOf.ChartSpace_to_WorldSpace(position_chartspace) + posOffset_forMoreLeveledDistanceToLine + posOffset_forDifferentLineWidths;
float textSize = chart_thisPointIsPartOf.Height_inWorldSpace * sizeOfLabeltext_relToChartHeight;
Vector3 textDir_normalized = chart_thisPointIsPartOf.yAxis.AxisVector_normalized_inWorldSpace;
Vector3 textUp_normalized = -chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace;
DrawText.TextAnchorDXXL textAnchor = placeTextTowardsOutsideOfChart ? DrawText.TextAnchorDXXL.LowerRight : DrawText.TextAnchorDXXL.LowerLeft;
UtilitiesDXXL_Text.Write(labelText, position_worldspace, color, textSize, textDir_normalized, textUp_normalized, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, chart_thisPointIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects, false, false, true);
}
}
}
void DrawLabelText_horizForYValues(bool horizLineHasBeenDrawn, float durationInSec, bool hiddenByNearerObjects)
{
if (horizLineHasBeenDrawn)
{
if (labelText != null && labelText != "")
{
Vector2 position_chartspace = new Vector2(chart_thisPointIsPartOf.xAxis.ValueMarkingLowerEndOfTheAxis, position);
Vector3 posOffset_forMoreLeveledDistanceToLine = chart_thisPointIsPartOf.yAxis.AxisVector_inWorldSpace * sizeOfCoordinateText_relToChartHeight * relAdditionalShiftOfText;
float absHalfLineWidth_inWorldUnits = Mathf.Abs(0.5f * currLineWidth_inWorldUnits);
Vector3 posOffset_forDifferentLineWidths = chart_thisPointIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * absHalfLineWidth_inWorldUnits;
Vector3 position_worldspace = chart_thisPointIsPartOf.ChartSpace_to_WorldSpace(position_chartspace) + posOffset_forMoreLeveledDistanceToLine + posOffset_forDifferentLineWidths;
float textSize = chart_thisPointIsPartOf.Height_inWorldSpace * sizeOfLabeltext_relToChartHeight;
Vector3 textDir_normalized = chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace;
Vector3 textUp_normalized = chart_thisPointIsPartOf.yAxis.AxisVector_normalized_inWorldSpace;
DrawText.TextAnchorDXXL textAnchor = placeTextTowardsOutsideOfChart ? DrawText.TextAnchorDXXL.LowerRight : DrawText.TextAnchorDXXL.LowerLeft;
UtilitiesDXXL_Text.Write(labelText, position_worldspace, color, textSize, textDir_normalized, textUp_normalized, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, chart_thisPointIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects, false, false, true);
}
}
}
float GetStylePatternScaleFactor_widenedForDottedStyles_inWorldspace(float unwidened_stylePatternScaleFactor_inWorldspace)
{
if (lineStyle == DrawBasics.LineStyle.dotted)
{
return unwidened_stylePatternScaleFactor_inWorldspace * 5.0f;
}
if (lineStyle == DrawBasics.LineStyle.dottedDense)
{
return unwidened_stylePatternScaleFactor_inWorldspace * 5.0f;
}
if (lineStyle == DrawBasics.LineStyle.dottedWide)
{
return unwidened_stylePatternScaleFactor_inWorldspace * 5.0f;
}
if (lineStyle == DrawBasics.LineStyle.dotDash)
{
return unwidened_stylePatternScaleFactor_inWorldspace * 5.0f;
}
if (lineStyle == DrawBasics.LineStyle.dotDashLong)
{
return unwidened_stylePatternScaleFactor_inWorldspace * 5.0f;
}
if (lineStyle == DrawBasics.LineStyle.twoDash)
{
return unwidened_stylePatternScaleFactor_inWorldspace * 5.0f;
}
if (lineStyle == DrawBasics.LineStyle.dashed)
{
return unwidened_stylePatternScaleFactor_inWorldspace * 5.0f;
}
if (lineStyle == DrawBasics.LineStyle.dashedLong)
{
return unwidened_stylePatternScaleFactor_inWorldspace * 5.0f;
}
return unwidened_stylePatternScaleFactor_inWorldspace;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: eb0d678b5da020c48b13303fbfe38aa2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,369 @@
namespace DrawXXL
{
using UnityEngine;
public class PointOfInterest
{
private static float textSize_relToChartHeight = 0.04f;
public static float TextSize_relToChartHeight //This changes globally for all PointsOfInterest. This only affects the text in the textbox that is connected with a pointer. For the textsize right at the horizontal und vertical line throught the point: see "DimensionOf_PointOfInterest.SizeOfLabeltext_relToChartHeight" and "DimensionOf_PointOfInterest.SizeOfCoordinateText_relToChartHeight".
{
get { return textSize_relToChartHeight; }
set { textSize_relToChartHeight = Mathf.Max(value, 0.002f); }
}
public static float distanceBetweenTextBoxes_relToChartHeight = 0.06f;
public static float pointerConeLength_relToChartHeight = 0.05f;
public DimensionOf_PointOfInterest xValue;
public DimensionOf_PointOfInterest yValue;
public string text; //if you want to let the textbox pointer point horizontally or vertically into the chart (indicating an x-value or y-value rather than an xy-position) you can set one of the two dimensions(xValue/yValue).position to float.NaN
public Color colorOfPointerTextBox; //this only sets the color of the pointer and the text box. If you want to set the color of the horizonal and vertical line use "SetWholeColor()" or "xValue/yValue.color"
public bool drawTextBoxIfPointIsOutsideOfChartArea = true;
public bool isDeletedOnClear = true;
public bool forceColorOfParent = false; //if this is enabled then "field.colorOfPointerTextBox" and "xValue/yValue.color" and "SetWholeColor" will have no effect anymore but it gets always the color used of the chart or the line this POI is part of. The alpha value is untouched and not forced from the parents.default is false.
public ChartDrawing chart_thisPointIsPartOf;
public ChartLine chartLine_thisPointIsPartOf;
bool isDrawnInNextPass;
public bool internal_isPOIthatCommunicatesTheHiddenPOIs = false; //"POI" = "point of interest"
public PointOfInterest(float position_x, float position_y, Color color, ChartDrawing chart_thisPointIsPartOf, ChartLine chartLine_thisPointIsPartOf, string textToDisplay)
{
//use ChartDrawing.AddPointOfInterest() instead
//use ChartLine.AddPointOfInterest() instead
this.chart_thisPointIsPartOf = chart_thisPointIsPartOf;
this.chartLine_thisPointIsPartOf = chartLine_thisPointIsPartOf;
if (chart_thisPointIsPartOf == null && chartLine_thisPointIsPartOf != null)
{
this.chart_thisPointIsPartOf = chartLine_thisPointIsPartOf.Chart_thisLineIsPartOf;
}
this.colorOfPointerTextBox = color;
xValue = new DimensionOf_PointOfInterest(position_x, color, UtilitiesDXXL_Math.Dimension.x, chart_thisPointIsPartOf);
yValue = new DimensionOf_PointOfInterest(position_y, color, UtilitiesDXXL_Math.Dimension.y, chart_thisPointIsPartOf);
xValue.theOtherDimension = yValue;
yValue.theOtherDimension = xValue;
text = textToDisplay;
}
public Vector3 TryDraw(Vector3 lowAnchorPositionOfText_inWorldspace, UtilitiesDXXL_Math.SkewedDirection cornerOfChartWhereTextBoxIsMounted, float durationInSec, bool hiddenByNearerObjects)
{
//use ChartDrawing.Draw() instead
//"cornerOfChartWhereTextBoxIsMounted": only "upLeft" and "upRight" are implemented
if (isDrawnInNextPass)
{
TryForceColorFromParent(false);
xValue.Draw(durationInSec, hiddenByNearerObjects);
yValue.Draw(durationInSec, hiddenByNearerObjects);
Vector3 lowAnchorPositionOfNextText_inWorldspace = TryDrawTextBoxAndPointer(lowAnchorPositionOfText_inWorldspace, cornerOfChartWhereTextBoxIsMounted, durationInSec, hiddenByNearerObjects);
return lowAnchorPositionOfNextText_inWorldspace;
}
else
{
Vector3 lowAnchorPositionOfNextText_inWorldspace = lowAnchorPositionOfText_inWorldspace;
return lowAnchorPositionOfNextText_inWorldspace;
}
}
Vector3 TryDrawTextBoxAndPointer(Vector3 lowAnchorPositionOfText_inWorldspace, UtilitiesDXXL_Math.SkewedDirection cornerOfChartWhereTextBoxIsMounted, float durationInSec, bool hiddenByNearerObjects)
{
Vector3 lowAnchorPositionOfNextText_inWorldspace;
if (HasTextBox())
{
GetIfAndHowPointerIsDrawn(out Vector2 posOfPointOfInterest_chartSpace, out bool oneDimIsValid_theOtherOneIsInvalid, out UtilitiesDXXL_Math.DimensionNullable theSingleValidDimension, out bool textboxIsDrawn, out bool pointerIsDrawn, out string printedText);
if (textboxIsDrawn)
{
lowAnchorPositionOfNextText_inWorldspace = DrawTextBoxAndPointer(pointerIsDrawn, lowAnchorPositionOfText_inWorldspace, posOfPointOfInterest_chartSpace, oneDimIsValid_theOtherOneIsInvalid, theSingleValidDimension, printedText, cornerOfChartWhereTextBoxIsMounted, durationInSec, hiddenByNearerObjects);
}
else
{
lowAnchorPositionOfNextText_inWorldspace = lowAnchorPositionOfText_inWorldspace;
}
}
else
{
lowAnchorPositionOfNextText_inWorldspace = lowAnchorPositionOfText_inWorldspace;
}
return lowAnchorPositionOfNextText_inWorldspace;
}
UtilitiesDXXL_Math.DimensionNullable GetTheSingleValidDimension(bool oneDimIsValid_theOtherOneIsInvalid, bool xDim_isValid)
{
UtilitiesDXXL_Math.DimensionNullable theSingleValidDimension = UtilitiesDXXL_Math.DimensionNullable.none;
if (oneDimIsValid_theOtherOneIsInvalid)
{
if (xDim_isValid)
{
theSingleValidDimension = UtilitiesDXXL_Math.DimensionNullable.x;
}
else
{
theSingleValidDimension = UtilitiesDXXL_Math.DimensionNullable.y;
}
}
return theSingleValidDimension;
}
bool CheckIf_isInsideChartArea(bool bothDimValuesAreInvalid, bool bothDimValuesAreValid, UtilitiesDXXL_Math.DimensionNullable theSingleValidDimension, Vector2 posOfPointOfInterest_chartSpace)
{
if (bothDimValuesAreInvalid)
{
return false;
}
else
{
if (bothDimValuesAreValid)
{
return chart_thisPointIsPartOf.IsInsideDrawnChartArea(posOfPointOfInterest_chartSpace);
}
else
{
if (theSingleValidDimension == UtilitiesDXXL_Math.DimensionNullable.x)
{
return chart_thisPointIsPartOf.xAxis.IsInsideDisplayedSpan(xValue.position);
}
else
{
return chart_thisPointIsPartOf.yAxis.IsInsideDisplayedSpan(yValue.position);
}
}
}
}
public int Internal_Set_isDrawnInNextPass(int stillAvailableTextBoxes)
{
if (HasTextBox())
{
if (TextBoxWillAnywayNotGetDrawn_becauseOfItsSettingThatHidesItOutsideOfTheChartArea())
{
isDrawnInNextPass = true; //Enable the possibility that a horiz/vert-crosshair may get drawn...
return stillAvailableTextBoxes; //...but don't affect the "available text boxes"-count
}
else
{
isDrawnInNextPass = (stillAvailableTextBoxes > 0);
return (stillAvailableTextBoxes - 1);
}
}
else
{
isDrawnInNextPass = true;
return stillAvailableTextBoxes;
}
}
bool TextBoxWillAnywayNotGetDrawn_becauseOfItsSettingThatHidesItOutsideOfTheChartArea()
{
GetIfAndHowPointerIsDrawn(out Vector2 posOfPointOfInterest_chartSpace, out bool oneDimIsValid_theOtherOneIsInvalid, out UtilitiesDXXL_Math.DimensionNullable theSingleValidDimension, out bool textboxIsDrawn, out bool pointerIsDrawn, out string printedText);
return (!textboxIsDrawn);
}
void GetIfAndHowPointerIsDrawn(out Vector2 posOfPointOfInterest_chartSpace, out bool oneDimIsValid_theOtherOneIsInvalid, out UtilitiesDXXL_Math.DimensionNullable theSingleValidDimension, out bool textboxIsDrawn, out bool pointerIsDrawn, out string printedText)
{
posOfPointOfInterest_chartSpace = new Vector2(xValue.position, yValue.position);
bool xDim_isValid = UtilitiesDXXL_Math.FloatIsValid(xValue.position);
bool yDim_isValid = UtilitiesDXXL_Math.FloatIsValid(yValue.position);
bool atLeastOneDimValueIsValid = (xDim_isValid || yDim_isValid);
bool bothDimValuesAreValid = (xDim_isValid && yDim_isValid);
bool bothDimValuesAreInvalid = ((xDim_isValid == false) && (yDim_isValid == false));
oneDimIsValid_theOtherOneIsInvalid = (xDim_isValid != yDim_isValid);
theSingleValidDimension = GetTheSingleValidDimension(oneDimIsValid_theOtherOneIsInvalid, xDim_isValid);
bool isInsideChartArea = CheckIf_isInsideChartArea(bothDimValuesAreInvalid, bothDimValuesAreValid, theSingleValidDimension, posOfPointOfInterest_chartSpace);
GetIfAndHowPointerIsDrawn(out textboxIsDrawn, out pointerIsDrawn, out printedText, isInsideChartArea, atLeastOneDimValueIsValid);
}
void GetIfAndHowPointerIsDrawn(out bool textboxIsDrawn, out bool pointerIsDrawn, out string printedText, bool isInsideChartArea, bool atLeastOneDimValueIsValid)
{
printedText = null;
if (internal_isPOIthatCommunicatesTheHiddenPOIs)
{
textboxIsDrawn = true;
pointerIsDrawn = false;
printedText = text;
}
else
{
if (isInsideChartArea || chart_thisPointIsPartOf.drawValuesOutsideOfChartArea)
{
textboxIsDrawn = true;
pointerIsDrawn = atLeastOneDimValueIsValid ? true : false;
printedText = text;
}
else
{
//->"is OUTSIDE of chart area" and "chart DOESN'T draw values outside of the chart area"
pointerIsDrawn = false;
if (drawTextBoxIfPointIsOutsideOfChartArea)
{
textboxIsDrawn = true;
printedText = "[<color=#adadadFF><icon=logMessage></color> Is outside of chart area at<br>( " + xValue.position + " / " + yValue.position + " )]<br>" + text;
}
else
{
textboxIsDrawn = false;
}
}
}
}
Vector3 DrawTextBoxAndPointer(bool pointerIsDrawn, Vector3 lowAnchorPositionOfText_inWorldspace, Vector2 posOfPointOfInterest_chartSpace, bool oneDimIsValid_theOtherOneIsInvalid, UtilitiesDXXL_Math.DimensionNullable theSingleValidDimension, string printedText, UtilitiesDXXL_Math.SkewedDirection cornerOfChartWhereTextBoxIsMounted, float durationInSec, bool hiddenByNearerObjects)
{
float textSize = textSize_relToChartHeight * chart_thisPointIsPartOf.Height_inWorldSpace;
DrawText.TextAnchorDXXL textAnchor;
if (cornerOfChartWhereTextBoxIsMounted == UtilitiesDXXL_Math.SkewedDirection.upLeft)
{
//topLeftCorner:
textAnchor = DrawText.TextAnchorDXXL.LowerRight;
}
else
{
//topRightCorner:
textAnchor = DrawText.TextAnchorDXXL.LowerLeft;
}
float enclosingBox_paddingSize_relToTextSize = 0.0f;
float autoLineBreakWidth = 0.7f * chart_thisPointIsPartOf.Width_inWorldSpace;
UtilitiesDXXL_Text.WriteFramed(printedText, lowAnchorPositionOfText_inWorldspace, colorOfPointerTextBox, textSize, chart_thisPointIsPartOf.InternalRotation, textAnchor, DrawBasics.LineStyle.solid, 0.0f, enclosingBox_paddingSize_relToTextSize, 0.0f, 0.0f, autoLineBreakWidth, chart_thisPointIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects);
if (pointerIsDrawn)
{
DrawPointer(posOfPointOfInterest_chartSpace, oneDimIsValid_theOtherOneIsInvalid, theSingleValidDimension, cornerOfChartWhereTextBoxIsMounted, durationInSec, hiddenByNearerObjects);
}
Vector3 highCorner_ofTextBox_worldSpace;
if (cornerOfChartWhereTextBoxIsMounted == UtilitiesDXXL_Math.SkewedDirection.upLeft)
{
//boxes in topLeftCorner:
highCorner_ofTextBox_worldSpace = DrawText.parsedTextSpecs.upperRightPos_ofEnclosingBox;
}
else
{
//boxes in topRightCorner:
highCorner_ofTextBox_worldSpace = DrawText.parsedTextSpecs.upperLeftPos_ofEnclosingBox;
}
return (highCorner_ofTextBox_worldSpace + chart_thisPointIsPartOf.yAxis.AxisVector_inWorldSpace * distanceBetweenTextBoxes_relToChartHeight);
}
void DrawPointer(Vector2 posOfPointOfInterest_chartSpace, bool oneDimIsValid_theOtherOneIsInvalid, UtilitiesDXXL_Math.DimensionNullable theSingleValidDimension, UtilitiesDXXL_Math.SkewedDirection cornerOfChartWhereTextBoxIsMounted, float durationInSec, bool hiddenByNearerObjects)
{
//-> already guaranteed here: at least one dimension value is valid:
Vector3 lowInnerCorner_ofTextBox_worldSpace;
Vector3 lowOuterCorner_ofTextBox_worldSpace;
if (cornerOfChartWhereTextBoxIsMounted == UtilitiesDXXL_Math.SkewedDirection.upLeft)
{
//boxes in topLeftCorner:
lowInnerCorner_ofTextBox_worldSpace = DrawText.parsedTextSpecs.lowRightPos_ofEnclosingBox;
lowOuterCorner_ofTextBox_worldSpace = DrawText.parsedTextSpecs.lowLeftPos_ofEnclosingBox;
}
else
{
//boxes in topRightCorner:
lowInnerCorner_ofTextBox_worldSpace = DrawText.parsedTextSpecs.lowLeftPos_ofEnclosingBox;
lowOuterCorner_ofTextBox_worldSpace = DrawText.parsedTextSpecs.lowRightPos_ofEnclosingBox;
}
float forceFixedConeLength = chart_thisPointIsPartOf.Height_inWorldSpace * pointerConeLength_relToChartHeight;
bool pointerIsDrawnWithKink_thenAxisParallelIntoChart = oneDimIsValid_theOtherOneIsInvalid;
if (pointerIsDrawnWithKink_thenAxisParallelIntoChart)
{
DrawPointerWithKink(lowInnerCorner_ofTextBox_worldSpace, lowOuterCorner_ofTextBox_worldSpace, theSingleValidDimension, cornerOfChartWhereTextBoxIsMounted, forceFixedConeLength, durationInSec, hiddenByNearerObjects);
}
else
{
DrawPointerWithoutKink(posOfPointOfInterest_chartSpace, lowInnerCorner_ofTextBox_worldSpace, forceFixedConeLength, durationInSec, hiddenByNearerObjects);
}
}
void DrawPointerWithKink(Vector3 lowInnerCorner_ofTextBox_worldSpace, Vector3 lowOuterCorner_ofTextBox_worldSpace, UtilitiesDXXL_Math.DimensionNullable theSingleValidDimension, UtilitiesDXXL_Math.SkewedDirection cornerOfChartWhereTextBoxIsMounted, float forceFixedConeLength, float durationInSec, bool hiddenByNearerObjects)
{
float lengthFactor_forAxisParallelPointerSection = 0.1f;
Vector3 customAmplitudeAndTextDir;
Vector3 startPosAtTextBoxCorner_worldSpace;
Vector3 kinkPosToFinalPointer_worldSpace;
Vector3 pointerTargetPos_worldSpace;
if (theSingleValidDimension == UtilitiesDXXL_Math.DimensionNullable.x)
{
customAmplitudeAndTextDir = chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace;
startPosAtTextBoxCorner_worldSpace = lowInnerCorner_ofTextBox_worldSpace;
Vector2 pointerTargetPos_chartSpace = new Vector2(xValue.position, chart_thisPointIsPartOf.yAxis.ValueMarkingUpperEndOfTheAxis);
pointerTargetPos_worldSpace = chart_thisPointIsPartOf.ChartSpace_to_WorldSpace(pointerTargetPos_chartSpace) - chart_thisPointIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * (0.5f * pointerConeLength_relToChartHeight);
kinkPosToFinalPointer_worldSpace = pointerTargetPos_worldSpace + chart_thisPointIsPartOf.yAxis.AxisVector_inWorldSpace * lengthFactor_forAxisParallelPointerSection;
}
else
{
customAmplitudeAndTextDir = chart_thisPointIsPartOf.yAxis.AxisVector_normalized_inWorldSpace;
startPosAtTextBoxCorner_worldSpace = lowOuterCorner_ofTextBox_worldSpace;
if (cornerOfChartWhereTextBoxIsMounted == UtilitiesDXXL_Math.SkewedDirection.upLeft)
{
Vector2 pointerTargetPos_chartSpace = new Vector2(chart_thisPointIsPartOf.xAxis.ValueMarkingLowerEndOfTheAxis, yValue.position);
pointerTargetPos_worldSpace = chart_thisPointIsPartOf.ChartSpace_to_WorldSpace(pointerTargetPos_chartSpace);
kinkPosToFinalPointer_worldSpace = pointerTargetPos_worldSpace - chart_thisPointIsPartOf.xAxis.AxisVector_inWorldSpace * lengthFactor_forAxisParallelPointerSection;
}
else
{
Vector2 pointerTargetPos_chartSpace = new Vector2(chart_thisPointIsPartOf.xAxis.ValueMarkingUpperEndOfTheAxis, yValue.position);
pointerTargetPos_worldSpace = chart_thisPointIsPartOf.ChartSpace_to_WorldSpace(pointerTargetPos_chartSpace);
kinkPosToFinalPointer_worldSpace = pointerTargetPos_worldSpace + chart_thisPointIsPartOf.xAxis.AxisVector_inWorldSpace * lengthFactor_forAxisParallelPointerSection;
}
}
Line_fadeableAnimSpeed.InternalDraw(startPosAtTextBoxCorner_worldSpace, kinkPosToFinalPointer_worldSpace, colorOfPointerTextBox, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false);
bool setConeLengthToRelative_notToAbsolute = UtilitiesDXXL_Math.ApproximatelyZero(forceFixedConeLength);
float coneLength_ifSetToRelative = 0.17f;
float coneLength_ifSetToAbsolute = forceFixedConeLength;
float coneLength = UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(setConeLengthToRelative_notToAbsolute, coneLength_ifSetToRelative, coneLength_ifSetToAbsolute);
DrawBasics.Vector(kinkPosToFinalPointer_worldSpace, pointerTargetPos_worldSpace, colorOfPointerTextBox, 0.0f, null, coneLength, false, true, customAmplitudeAndTextDir, false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects);
UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors();
}
void DrawPointerWithoutKink(Vector2 posOfPointOfInterest_chartSpace, Vector3 lowInnerCorner_ofTextBox_worldSpace, float forceFixedConeLength, float durationInSec, bool hiddenByNearerObjects)
{
Vector3 customAmplitudeAndTextDir = chart_thisPointIsPartOf.xAxis.AxisVector_normalized_inWorldSpace;
Vector3 startPosAtTextBoxCorner_worldSpace = lowInnerCorner_ofTextBox_worldSpace;
Vector3 pointerTargetPos_worldSpace = chart_thisPointIsPartOf.ChartSpace_to_WorldSpace(posOfPointOfInterest_chartSpace);
bool setConeLengthToRelative_notToAbsolute = UtilitiesDXXL_Math.ApproximatelyZero(forceFixedConeLength);
float coneLength_ifSetToRelative = 0.17f;
float coneLength_ifSetToAbsolute = forceFixedConeLength;
float coneLength = UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(setConeLengthToRelative_notToAbsolute, coneLength_ifSetToRelative, coneLength_ifSetToAbsolute);
DrawBasics.Vector(startPosAtTextBoxCorner_worldSpace, pointerTargetPos_worldSpace, colorOfPointerTextBox, 0.0f, null, coneLength, false, true, customAmplitudeAndTextDir, false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects);
UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors();
}
public void SetWholeColor(Color newColor)
{
//This not only sets the color of the poiner and the text box (as setting field.colorOfPointerTextBox would) but also of the horizonal and vertical line.
colorOfPointerTextBox = newColor;
xValue.color = newColor;
yValue.color = newColor;
}
void TryForceColorFromParent(bool alsoForceAlpha = false)
{
if (forceColorOfParent)
{
if (chartLine_thisPointIsPartOf != null)
{
colorOfPointerTextBox = new Color(chartLine_thisPointIsPartOf.Color.r, chartLine_thisPointIsPartOf.Color.g, chartLine_thisPointIsPartOf.Color.b, alsoForceAlpha ? chartLine_thisPointIsPartOf.Color.a : colorOfPointerTextBox.a);
xValue.color = new Color(chartLine_thisPointIsPartOf.Color.r, chartLine_thisPointIsPartOf.Color.g, chartLine_thisPointIsPartOf.Color.b, alsoForceAlpha ? chartLine_thisPointIsPartOf.Color.a : xValue.color.a);
yValue.color = new Color(chartLine_thisPointIsPartOf.Color.r, chartLine_thisPointIsPartOf.Color.g, chartLine_thisPointIsPartOf.Color.b, alsoForceAlpha ? chartLine_thisPointIsPartOf.Color.a : yValue.color.a);
}
else
{
colorOfPointerTextBox = new Color(chart_thisPointIsPartOf.color.r, chart_thisPointIsPartOf.color.g, chart_thisPointIsPartOf.color.b, alsoForceAlpha ? chart_thisPointIsPartOf.color.a : colorOfPointerTextBox.a);
xValue.color = new Color(chart_thisPointIsPartOf.color.r, chart_thisPointIsPartOf.color.g, chart_thisPointIsPartOf.color.b, alsoForceAlpha ? chart_thisPointIsPartOf.color.a : xValue.color.a);
yValue.color = new Color(chart_thisPointIsPartOf.color.r, chart_thisPointIsPartOf.color.g, chart_thisPointIsPartOf.color.b, alsoForceAlpha ? chart_thisPointIsPartOf.color.a : yValue.color.a);
}
}
}
bool HasTextBox()
{
return (text != null && text != "");
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1a53c3d7c3432844a878b6f098221fda
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: afd6e8e1c61d3a1449bce3b17b0d4efa
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b23e7ea809c2b0b49909def88736de81
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,124 @@
namespace DrawXXL
{
using UnityEngine;
using System.Collections.Generic;
using System.IO;
public class InternalDXXL_ChartToCSVfileWriter
{
public static string default_csvFileName = "DrawXXL_chart";
public void ExportToCSVfile(ChartLines lines, string fileName)
{
if (fileName == null || fileName == "")
{
fileName = default_csvFileName;
}
string pathPlusFileNameInclFileTypeEnding = Create_pathPlusFileNameInclFileTypeEnding(fileName);
int maxFilesWithSameName = 1000000;
bool hasFoundValidFilename = false;
int sequentialNumberOfSameFilename = -1;
for (int i = 0; i < maxFilesWithSameName; i++)
{
if (File.Exists(pathPlusFileNameInclFileTypeEnding))
{
sequentialNumberOfSameFilename = i + 1;
pathPlusFileNameInclFileTypeEnding = Create_pathPlusFileNameInclFileTypeEnding(fileName + "(" + sequentialNumberOfSameFilename + ")");
}
else
{
hasFoundValidFilename = true;
break;
}
}
if (hasFoundValidFilename == false)
{
Debug.LogError("Generating CSV file failed: Too many files with same name (of '" + fileName + "').");
return;
}
StreamWriter streamWriter = null;
try
{
List<ChartLine> allLinesWithAtLeastOneDataPoint_validOrInvalid = lines.Get_all_hiddenAndUnhiddenLines_withAtLeastOneValidOrInvalidDatapoint(out int numberOfDatapoints_inLongestLine, false);
streamWriter = new StreamWriter(pathPlusFileNameInclFileTypeEnding);
//Line names:
for (int i_line = 0; i_line < allLinesWithAtLeastOneDataPoint_validOrInvalid.Count; i_line++)
{
string lineName = allLinesWithAtLeastOneDataPoint_validOrInvalid[i_line].GetNameCompound(false);
if (i_line < (allLinesWithAtLeastOneDataPoint_validOrInvalid.Count - 1))
{
streamWriter.Write("\"x of " + lineName + "\",\"y of " + lineName + "\",");
}
else
{
streamWriter.WriteLine("\"x of " + lineName + "\",\"y of " + lineName + "\"");
}
}
//data points:
for (int i_datapoint = 0; i_datapoint < numberOfDatapoints_inLongestLine; i_datapoint++)
{
for (int i_line = 0; i_line < allLinesWithAtLeastOneDataPoint_validOrInvalid.Count; i_line++)
{
if (i_datapoint < allLinesWithAtLeastOneDataPoint_validOrInvalid[i_line].dataPoints.Count)
{
if (i_line < (allLinesWithAtLeastOneDataPoint_validOrInvalid.Count - 1))
{
streamWriter.Write("\"" + allLinesWithAtLeastOneDataPoint_validOrInvalid[i_line].dataPoints[i_datapoint].xValue + "\",\"" + allLinesWithAtLeastOneDataPoint_validOrInvalid[i_line].dataPoints[i_datapoint].yValue + "\",");
}
else
{
streamWriter.WriteLine("\"" + allLinesWithAtLeastOneDataPoint_validOrInvalid[i_line].dataPoints[i_datapoint].xValue + "\",\"" + allLinesWithAtLeastOneDataPoint_validOrInvalid[i_line].dataPoints[i_datapoint].yValue + "\"");
}
}
else
{
if (i_line < (allLinesWithAtLeastOneDataPoint_validOrInvalid.Count - 1))
{
streamWriter.Write(",,");
}
else
{
streamWriter.WriteLine(",");
}
}
}
}
}
catch
{
Debug.LogError("Writing CSV file failed.");
}
finally
{
try
{
streamWriter.Close();
if (sequentialNumberOfSameFilename == (-1))
{
Debug.Log("The file '" + fileName + ".csv' was generated.");
}
else
{
Debug.Log("The file '" + fileName + "(" + sequentialNumberOfSameFilename + ").csv' was generated.");
}
}
catch
{
Debug.LogError("Closing the new CSV file failed.");
}
}
}
string Create_pathPlusFileNameInclFileTypeEnding(string fileName)
{
return (Application.dataPath + "/" + fileName + ".csv");
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 71041864ca5542b429191d71a08545b1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,389 @@
namespace DrawXXL
{
using UnityEngine;
public class InternalDXXL_DataPointOfChartLine
{
public enum ValidState { isValid, isNaN_atX, isNaN_atY, isPositiveInfinity_atX, isPositiveInfinity_atY, isNegativeInfinity_atX, isNegativeInfinity_atY, isPlaceholderDuringPhasesWhereThisLineOfListDidntExistsDueToListChangedItsCount_existsOnlyToStayInXSyncWithOtherLinesOfList }
///[Set during point creation]:
public float xValue; //-> is only expected to be "invalid" when using an "AddXYValue()"-function (which doesn't use the automatic x-value-source). So it is not expected for complexer data types (like Vector/Quaternion/Color, which consist of more than 1 line), and also it is not expected for anything that comes from "AddValues_eachIndexIsALine" where many lines are grouped.
public float yValue;
public ValidState validState; //if both values (x and y) are "NaN" (or Infintiy) then this is set to the "_atX" variants.
public int i_ofThisPointInsideContainingLine;
public ChartLine line_thisPointIsPartOf;
public bool hasLittleEmphasizingCircleAroundPoint = false;
public bool forceConnectionLineToLowAlpha;
///[Set during drawing]:
public bool isInsideChartRect;
public bool isInsideChartsXSpan;
public bool isDrawn;
public int i_ofPrecedingPointFromWhichLineCanBeDrawn;
public Vector3 positionInWorldSpace;
public Vector3 positionInWorldSpace_atYHeightOfValidPrecedingPoint;
public Vector3 positionInWorldSpace_atYHeightOfLowerEndOf_rgbColorUnderlay;
public Vector3 positionInWorldSpace_atYHeightOfUpperEndOf_rgbColorUnderlay;
//Others:
static float alphaFactor_indicatingVertConnectionLines = 0.2f;
static float alphaFactor_indicatingNonExistingValues = 0.25f;
public void DetermineIfAndHowPointIsDrawn(float valueMarkingLowerEndOf_XAxis, float valueMarkingUpperEndOf_XAxis, float valueMarkingLowerEndOf_YAxis, float valueMarkingUpperEndOf_YAxis, int i_ofTheMostCurrentDrawnPoint, bool thereHaveBeenValidPointsOutsideTheDrawnChartArea_sinceMostCurrentDrawnPoint)
{
if (validState == ValidState.isValid)
{
isInsideChartRect = true;
if (xValue < valueMarkingLowerEndOf_XAxis) { isInsideChartRect = false; }
if (xValue > valueMarkingUpperEndOf_XAxis) { isInsideChartRect = false; }
if (yValue < valueMarkingLowerEndOf_YAxis) { isInsideChartRect = false; }
if (yValue > valueMarkingUpperEndOf_YAxis) { isInsideChartRect = false; }
bool isInDrawnArea = isInsideChartRect || line_thisPointIsPartOf.Chart_thisLineIsPartOf.drawValuesOutsideOfChartArea;
isDrawn = isInDrawnArea;
i_ofPrecedingPointFromWhichLineCanBeDrawn = i_ofTheMostCurrentDrawnPoint;
if ((line_thisPointIsPartOf.Chart_thisLineIsPartOf.drawValuesOutsideOfChartArea == false) && thereHaveBeenValidPointsOutsideTheDrawnChartArea_sinceMostCurrentDrawnPoint)
{
i_ofPrecedingPointFromWhichLineCanBeDrawn = -1;
}
positionInWorldSpace = line_thisPointIsPartOf.Chart_thisLineIsPartOf.ChartSpace_to_WorldSpace(new Vector2(xValue, yValue));
}
else
{
isInsideChartRect = false;
isDrawn = false;
}
}
public void DetermineIfAndHowPointIsDrawn_forRGBColorUnderlay(float valueMarkingLowerEndOf_XAxis, float valueMarkingUpperEndOf_XAxis, float valueMarkingLowerEndOf_YAxis, float valueMarkingUpperEndOf_YAxis)
{
//-> is only called for valid datapoints
isInsideChartsXSpan = true;
if (xValue < valueMarkingLowerEndOf_XAxis) { isInsideChartsXSpan = false; }
if (xValue > valueMarkingUpperEndOf_XAxis) { isInsideChartsXSpan = false; }
float yGap_toXAxis = 0.01f * (valueMarkingUpperEndOf_YAxis - valueMarkingLowerEndOf_YAxis);
positionInWorldSpace_atYHeightOfLowerEndOf_rgbColorUnderlay = line_thisPointIsPartOf.Chart_thisLineIsPartOf.ChartSpace_to_WorldSpace(new Vector2(xValue, valueMarkingLowerEndOf_YAxis + yGap_toXAxis));
positionInWorldSpace_atYHeightOfUpperEndOf_rgbColorUnderlay = line_thisPointIsPartOf.Chart_thisLineIsPartOf.ChartSpace_to_WorldSpace(new Vector2(xValue, valueMarkingUpperEndOf_YAxis));
}
public void DrawConnectionLineFromPrecedingPoint(Vector3 worldPos_ofPrecedingDrawnPoint, float yValue_ofPrecedingDrawnPoint_inChartSpace, bool lineFromPrecedingDrawnPoint_shouldBeLowerAlphaIndicatingAnInvalidPhase, float absLineWidth_worldSpace, Vector3 amplitudeDir_forNonZeroWidthLines, float durationInSec, bool hiddenByNearerObjects)
{
switch (line_thisPointIsPartOf.lineConnectionsType)
{
case ChartLine.LineConnectionsType.straightFromPointToPoint:
DrawLineFromPrecedingToCurrPoint(worldPos_ofPrecedingDrawnPoint, lineFromPrecedingDrawnPoint_shouldBeLowerAlphaIndicatingAnInvalidPhase, absLineWidth_worldSpace, amplitudeDir_forNonZeroWidthLines, durationInSec, hiddenByNearerObjects);
break;
case ChartLine.LineConnectionsType.horizPlateauTillNextPoint:
DrawHorizLineFromPrecedingPointThenLowAlphaVertToCurrent(worldPos_ofPrecedingDrawnPoint, yValue_ofPrecedingDrawnPoint_inChartSpace, lineFromPrecedingDrawnPoint_shouldBeLowerAlphaIndicatingAnInvalidPhase, absLineWidth_worldSpace, amplitudeDir_forNonZeroWidthLines, durationInSec, hiddenByNearerObjects);
break;
case ChartLine.LineConnectionsType.invisible:
break;
default:
break;
}
}
void DrawLineFromPrecedingToCurrPoint(Vector3 worldPos_ofPrecedingDrawnPoint, bool lineFromPrecedingDrawnPoint_shouldBeLowerAlphaIndicatingAnInvalidPhase, float absLineWidth_worldSpace, Vector3 amplitudeDir_forNonZeroWidthLines, float durationInSec, bool hiddenByNearerObjects)
{
if (lineFromPrecedingDrawnPoint_shouldBeLowerAlphaIndicatingAnInvalidPhase || forceConnectionLineToLowAlpha)
{
DrawLineFromPrecedingToCurrPoint_lowAlphaIndicatingNonExistingValues(worldPos_ofPrecedingDrawnPoint, durationInSec, hiddenByNearerObjects);
}
else
{
DrawLineFromPrecedingToCurrPoint_fullAlpha(worldPos_ofPrecedingDrawnPoint, absLineWidth_worldSpace, amplitudeDir_forNonZeroWidthLines, durationInSec, hiddenByNearerObjects);
}
}
void DrawLineFromPrecedingToCurrPoint_fullAlpha(Vector3 worldPos_ofPrecedingDrawnPoint, float absLineWidth_worldSpace, Vector3 amplitudeDir_forNonZeroWidthLines, float durationInSec, bool hiddenByNearerObjects)
{
Line_fadeableAnimSpeed.InternalDraw(worldPos_ofPrecedingDrawnPoint, positionInWorldSpace, line_thisPointIsPartOf.Color, absLineWidth_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, amplitudeDir_forNonZeroWidthLines, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false);
}
void DrawLineFromPrecedingToCurrPoint_lowAlphaIndicatingNonExistingValues(Vector3 worldPos_ofPrecedingDrawnPoint, float durationInSec, bool hiddenByNearerObjects)
{
Color color_loweredAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(line_thisPointIsPartOf.Color, alphaFactor_indicatingNonExistingValues);
Line_fadeableAnimSpeed.InternalDraw(worldPos_ofPrecedingDrawnPoint, positionInWorldSpace, color_loweredAlpha, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false);
}
void DrawHorizLineFromPrecedingPointThenLowAlphaVertToCurrent(Vector3 worldPos_ofPrecedingDrawnPoint, float yValue_ofPrecedingDrawnPoint_inChartSpace, bool lineFromPrecedingDrawnPoint_shouldBeLowerAlphaIndicatingAnInvalidPhase, float absLineWidth_worldSpace, Vector3 amplitudeDir_forNonZeroWidthLines, float durationInSec, bool hiddenByNearerObjects)
{
if (lineFromPrecedingDrawnPoint_shouldBeLowerAlphaIndicatingAnInvalidPhase || forceConnectionLineToLowAlpha)
{
DrawHorizLineFromPrecedingPointThenLowAlphaVertToCurrent_lowAlphaConfigIndicatingNonExistingValues(worldPos_ofPrecedingDrawnPoint, yValue_ofPrecedingDrawnPoint_inChartSpace, durationInSec, hiddenByNearerObjects);
}
else
{
DrawHorizLineFromPrecedingPointThenLowAlphaVertToCurrent_defaultAlphaConfig(worldPos_ofPrecedingDrawnPoint, yValue_ofPrecedingDrawnPoint_inChartSpace, absLineWidth_worldSpace, amplitudeDir_forNonZeroWidthLines, durationInSec, hiddenByNearerObjects);
}
}
void DrawHorizLineFromPrecedingPointThenLowAlphaVertToCurrent_defaultAlphaConfig(Vector3 worldPos_ofPrecedingDrawnPoint, float yValue_ofPrecedingDrawnPoint_inChartSpace, float absLineWidth_worldSpace, Vector3 amplitudeDir_forNonZeroWidthLines, float durationInSec, bool hiddenByNearerObjects)
{
//horiz Line:
CalcWorldPosAtYHeightOfValidPrecedingPoint(yValue_ofPrecedingDrawnPoint_inChartSpace);
Line_fadeableAnimSpeed.InternalDraw(worldPos_ofPrecedingDrawnPoint, positionInWorldSpace_atYHeightOfValidPrecedingPoint, line_thisPointIsPartOf.Color, absLineWidth_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, amplitudeDir_forNonZeroWidthLines, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false);
//vert Line:
Color color_ofVertConnectionLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(line_thisPointIsPartOf.Color, alphaFactor_indicatingVertConnectionLines);
Line_fadeableAnimSpeed.InternalDraw(positionInWorldSpace_atYHeightOfValidPrecedingPoint, positionInWorldSpace, color_ofVertConnectionLine, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false);
}
void DrawHorizLineFromPrecedingPointThenLowAlphaVertToCurrent_lowAlphaConfigIndicatingNonExistingValues(Vector3 worldPos_ofPrecedingDrawnPoint, float yValue_ofPrecedingDrawnPoint_inChartSpace, float durationInSec, bool hiddenByNearerObjects)
{
//horiz Line:
CalcWorldPosAtYHeightOfValidPrecedingPoint(yValue_ofPrecedingDrawnPoint_inChartSpace);
Color colorHoriz_loweredAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(line_thisPointIsPartOf.Color, alphaFactor_indicatingNonExistingValues);
Line_fadeableAnimSpeed.InternalDraw(worldPos_ofPrecedingDrawnPoint, positionInWorldSpace_atYHeightOfValidPrecedingPoint, colorHoriz_loweredAlpha, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false);
//vert Line:
Color color_ofVertConnectionLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(line_thisPointIsPartOf.Color, alphaFactor_indicatingVertConnectionLines);
Color colorVert_loweredAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofVertConnectionLine, 0.5f);
Line_fadeableAnimSpeed.InternalDraw(positionInWorldSpace_atYHeightOfValidPrecedingPoint, positionInWorldSpace, colorVert_loweredAlpha, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false);
}
void CalcWorldPosAtYHeightOfValidPrecedingPoint(float yValue_ofPrecedingDrawnPoint_inChartSpace)
{
positionInWorldSpace_atYHeightOfValidPrecedingPoint = line_thisPointIsPartOf.Chart_thisLineIsPartOf.ChartSpace_to_WorldSpace(new Vector2(xValue, yValue_ofPrecedingDrawnPoint_inChartSpace));
}
public void DrawPointVisualization(float absSizeOfPointVisualization_inWorldSpace, float absLineWidth_forLineItself_worldSpace, float absLineWidth_forPointVisualisators_worldSpace, Vector3 amplitudeDir_forNonZeroWidthLines, float durationInSec, bool hiddenByNearerObjects)
{
TryDrawLittleEmphasizingCircleAroundPoint(absLineWidth_forLineItself_worldSpace, durationInSec, hiddenByNearerObjects);
if (validState == ValidState.isValid)
{
DrawVerticalFillLineFromXAxisToPoint(durationInSec, hiddenByNearerObjects);
float halfAbsSizeOfPointVisualization_inWorldSpace;
bool filledWithSpokes;
int numberOfCornersOfStarShape;
switch (line_thisPointIsPartOf.dataPointVisualization)
{
case ChartLine.DataPointVisualization.invisible:
break;
case ChartLine.DataPointVisualization.cross:
halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace;
//horiz crossline:
Vector3 leftCrossEnd_worldSpace = positionInWorldSpace - line_thisPointIsPartOf.Chart_thisLineIsPartOf.xAxis.AxisVector_normalized_inWorldSpace * halfAbsSizeOfPointVisualization_inWorldSpace;
Vector3 rightCrossEnd_worldSpace = positionInWorldSpace + line_thisPointIsPartOf.Chart_thisLineIsPartOf.xAxis.AxisVector_normalized_inWorldSpace * halfAbsSizeOfPointVisualization_inWorldSpace;
Line_fadeableAnimSpeed.InternalDraw(leftCrossEnd_worldSpace, rightCrossEnd_worldSpace, line_thisPointIsPartOf.Color, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, amplitudeDir_forNonZeroWidthLines, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false);
//vert crossline:
Vector3 lowerCrossEnd_worldSpace = positionInWorldSpace - line_thisPointIsPartOf.Chart_thisLineIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * halfAbsSizeOfPointVisualization_inWorldSpace;
Vector3 upperCrossEnd_worldSpace = positionInWorldSpace + line_thisPointIsPartOf.Chart_thisLineIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * halfAbsSizeOfPointVisualization_inWorldSpace;
Line_fadeableAnimSpeed.InternalDraw(lowerCrossEnd_worldSpace, upperCrossEnd_worldSpace, line_thisPointIsPartOf.Color, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, amplitudeDir_forNonZeroWidthLines, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false);
break;
case ChartLine.DataPointVisualization.cross45deg:
float halfAbsLengthOfCrossLines_projectedOntoChartAxis_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace * UtilitiesDXXL_Math.inverseSqrtOf2_precalced;
//horiz crossline:
Vector3 lowLeftCrossEnd_worldSpace = positionInWorldSpace - line_thisPointIsPartOf.Chart_thisLineIsPartOf.xAxis.AxisVector_normalized_inWorldSpace * halfAbsLengthOfCrossLines_projectedOntoChartAxis_inWorldSpace - line_thisPointIsPartOf.Chart_thisLineIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * halfAbsLengthOfCrossLines_projectedOntoChartAxis_inWorldSpace;
Vector3 topRightCrossEnd_worldSpace = positionInWorldSpace + line_thisPointIsPartOf.Chart_thisLineIsPartOf.xAxis.AxisVector_normalized_inWorldSpace * halfAbsLengthOfCrossLines_projectedOntoChartAxis_inWorldSpace + line_thisPointIsPartOf.Chart_thisLineIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * halfAbsLengthOfCrossLines_projectedOntoChartAxis_inWorldSpace;
Line_fadeableAnimSpeed.InternalDraw(lowLeftCrossEnd_worldSpace, topRightCrossEnd_worldSpace, line_thisPointIsPartOf.Color, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, amplitudeDir_forNonZeroWidthLines, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false);
//vert crossline:
Vector3 topLeftCrossEnd_worldSpace = positionInWorldSpace - line_thisPointIsPartOf.Chart_thisLineIsPartOf.xAxis.AxisVector_normalized_inWorldSpace * halfAbsLengthOfCrossLines_projectedOntoChartAxis_inWorldSpace + line_thisPointIsPartOf.Chart_thisLineIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * halfAbsLengthOfCrossLines_projectedOntoChartAxis_inWorldSpace;
Vector3 lowRightCrossEnd_worldSpace = positionInWorldSpace + line_thisPointIsPartOf.Chart_thisLineIsPartOf.xAxis.AxisVector_normalized_inWorldSpace * halfAbsLengthOfCrossLines_projectedOntoChartAxis_inWorldSpace - line_thisPointIsPartOf.Chart_thisLineIsPartOf.yAxis.AxisVector_normalized_inWorldSpace * halfAbsLengthOfCrossLines_projectedOntoChartAxis_inWorldSpace;
Line_fadeableAnimSpeed.InternalDraw(topLeftCrossEnd_worldSpace, lowRightCrossEnd_worldSpace, line_thisPointIsPartOf.Color, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, amplitudeDir_forNonZeroWidthLines, true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false);
break;
case ChartLine.DataPointVisualization.square:
filledWithSpokes = false;
DrawShapes.Square(positionInWorldSpace, absSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, filledWithSpokes, false, durationInSec, hiddenByNearerObjects);
break;
case ChartLine.DataPointVisualization.squareCrossed:
filledWithSpokes = true;
DrawShapes.Square(positionInWorldSpace, absSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, filledWithSpokes, false, durationInSec, hiddenByNearerObjects);
break;
case ChartLine.DataPointVisualization.triangle:
filledWithSpokes = false;
halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace;
DrawShapes.Triangle(positionInWorldSpace, halfAbsSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, filledWithSpokes, false, durationInSec, hiddenByNearerObjects);
break;
case ChartLine.DataPointVisualization.triangleCrossed:
filledWithSpokes = true;
halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace;
DrawShapes.Triangle(positionInWorldSpace, halfAbsSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, filledWithSpokes, false, durationInSec, hiddenByNearerObjects);
break;
case ChartLine.DataPointVisualization.pentagon:
filledWithSpokes = false;
halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace;
DrawShapes.Pentagon(positionInWorldSpace, halfAbsSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, filledWithSpokes, false, durationInSec, hiddenByNearerObjects);
break;
case ChartLine.DataPointVisualization.pentagonCrossed:
filledWithSpokes = true;
halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace;
DrawShapes.Pentagon(positionInWorldSpace, halfAbsSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, filledWithSpokes, false, durationInSec, hiddenByNearerObjects);
break;
case ChartLine.DataPointVisualization.circle:
halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace;
filledWithSpokes = false;
DrawShapes.Decagon(positionInWorldSpace, halfAbsSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, filledWithSpokes, false, durationInSec, hiddenByNearerObjects);
break;
case ChartLine.DataPointVisualization.circleFilled:
halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace;
filledWithSpokes = true;
DrawShapes.Decagon(positionInWorldSpace, halfAbsSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, filledWithSpokes, false, durationInSec, hiddenByNearerObjects);
break;
case ChartLine.DataPointVisualization.star4corners:
filledWithSpokes = false;
numberOfCornersOfStarShape = 4;
halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace;
DrawShapes.Star(positionInWorldSpace, halfAbsSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, numberOfCornersOfStarShape, 0.5f, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, filledWithSpokes, false, durationInSec, hiddenByNearerObjects);
break;
case ChartLine.DataPointVisualization.star4CornersCrossed:
filledWithSpokes = true;
numberOfCornersOfStarShape = 4;
halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace;
DrawShapes.Star(positionInWorldSpace, halfAbsSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, numberOfCornersOfStarShape, 0.5f, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, filledWithSpokes, false, durationInSec, hiddenByNearerObjects);
break;
case ChartLine.DataPointVisualization.star5corners:
filledWithSpokes = false;
numberOfCornersOfStarShape = 5;
halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace;
DrawShapes.Star(positionInWorldSpace, halfAbsSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, numberOfCornersOfStarShape, 0.5f, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, filledWithSpokes, false, durationInSec, hiddenByNearerObjects);
break;
case ChartLine.DataPointVisualization.star5CornersCrossed:
filledWithSpokes = true;
numberOfCornersOfStarShape = 5;
halfAbsSizeOfPointVisualization_inWorldSpace = 0.5f * absSizeOfPointVisualization_inWorldSpace;
DrawShapes.Star(positionInWorldSpace, halfAbsSizeOfPointVisualization_inWorldSpace, line_thisPointIsPartOf.Color, numberOfCornersOfStarShape, 0.5f, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, absLineWidth_forPointVisualisators_worldSpace, null, DrawBasics.LineStyle.solid, 1.0f, filledWithSpokes, false, durationInSec, hiddenByNearerObjects);
break;
case ChartLine.DataPointVisualization.heart:
float heartIconSize = absSizeOfPointVisualization_inWorldSpace * 1.25f;
int strokeWidth_asPPMofSize_ofHeartIcon = CalcIconWidth_asPPMofSize(heartIconSize, absLineWidth_forPointVisualisators_worldSpace);
DrawBasics.Icon(positionInWorldSpace, DrawBasics.IconType.heart, line_thisPointIsPartOf.Color, heartIconSize, null, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, strokeWidth_asPPMofSize_ofHeartIcon, false, durationInSec, hiddenByNearerObjects);
break;
case ChartLine.DataPointVisualization.customIconSymbol:
float iconSize = absSizeOfPointVisualization_inWorldSpace * 1.35f;
int strokeWidth_asPPMofSize = CalcIconWidth_asPPMofSize(iconSize, absLineWidth_forPointVisualisators_worldSpace);
DrawBasics.Icon(positionInWorldSpace, line_thisPointIsPartOf.customIconAsDatapointVisualization, line_thisPointIsPartOf.Color, iconSize, null, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, strokeWidth_asPPMofSize, false, durationInSec, hiddenByNearerObjects);
break;
default:
break;
}
}
}
int CalcIconWidth_asPPMofSize(float iconSize, float absLineWidth_forPointVisualisators_worldSpace)
{
if (UtilitiesDXXL_Math.ApproximatelyZero(absLineWidth_forPointVisualisators_worldSpace))
{
return 0;
}
else
{
return Mathf.RoundToInt((absLineWidth_forPointVisualisators_worldSpace / iconSize) * 1000000.0f);
}
}
void DrawVerticalFillLineFromXAxisToPoint(float durationInSec, bool hiddenByNearerObjects)
{
if (UtilitiesDXXL_Math.ApproximatelyZero(line_thisPointIsPartOf.Alpha_ofVerticalAreaFillLines) == false)
{
if (line_thisPointIsPartOf.Alpha_ofVerticalAreaFillLines > 0.0f)
{
Color colorOfVertLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(line_thisPointIsPartOf.Color, line_thisPointIsPartOf.Alpha_ofVerticalAreaFillLines);
Vector2 positionsVertProjectionOntoXAxis_inChartSpace = new Vector2(xValue, line_thisPointIsPartOf.Chart_thisLineIsPartOf.yAxis.ValueMarkingLowerEndOfTheAxis);
Vector3 positionsVertProjectionOntoXAxis_inWorldSpace = line_thisPointIsPartOf.Chart_thisLineIsPartOf.ChartSpace_to_WorldSpace(positionsVertProjectionOntoXAxis_inChartSpace);
Line_fadeableAnimSpeed.InternalDraw(positionInWorldSpace, positionsVertProjectionOntoXAxis_inWorldSpace, colorOfVertLine, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false);
}
}
}
void TryDrawLittleEmphasizingCircleAroundPoint(float absLineWidth_worldSpace, float durationInSec, bool hiddenByNearerObjects)
{
if (hasLittleEmphasizingCircleAroundPoint)
{
float radius = line_thisPointIsPartOf.Chart_thisLineIsPartOf.Height_inWorldSpace * 0.005f + 0.5f * absLineWidth_worldSpace;
DrawShapes.Decagon(positionInWorldSpace, radius, line_thisPointIsPartOf.Color, line_thisPointIsPartOf.Chart_thisLineIsPartOf.InternalRotation, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects);
}
}
public bool HasAPrecedingPointFromWhichLineCanBeDrawn()
{
//needs "DetermineIfAndHowPointIsDrawn" called beforehand
return (i_ofPrecedingPointFromWhichLineCanBeDrawn >= 0);
}
public string GetInvalidTypeString()
{
switch (validState)
{
case ValidState.isValid:
return "Is valid: " + GetStringTheDisplaysTheXandYvalue();
case ValidState.isNaN_atX:
return GetStringTheDisplaysTheXandYvalue();
case ValidState.isNaN_atY:
return GetStringTheDisplaysTheXandYvalue();
case ValidState.isPositiveInfinity_atX:
return GetStringTheDisplaysTheXandYvalue();
case ValidState.isPositiveInfinity_atY:
return GetStringTheDisplaysTheXandYvalue();
case ValidState.isNegativeInfinity_atX:
return GetStringTheDisplaysTheXandYvalue();
case ValidState.isNegativeInfinity_atY:
return GetStringTheDisplaysTheXandYvalue();
case ValidState.isPlaceholderDuringPhasesWhereThisLineOfListDidntExistsDueToListChangedItsCount_existsOnlyToStayInXSyncWithOtherLinesOfList:
return "Collection index didn't exist at 'AddValues_eachIndexIsALine()'-call (Length/Count was too small).";
default:
return "[<color=#ce0e0eFF><icon=logMessageError></color> ValidState of " + validState + " not implemented]";
}
}
string GetStringTheDisplaysTheXandYvalue()
{
return "x = " + xValue + " / y = " + yValue;
}
public static ValidState GetValidStateOf_datapointToBeCreated(bool newDatapoint_isPlaceholderDuringPhasesWhereThisLineOfListDidntExistsDueToListChangedItsCount_existsOnlyToStayInXSyncWithOtherLinesOfList, float xValue, float yValue)
{
ValidState validStateOfNewDataPoint = ValidState.isValid;
if (newDatapoint_isPlaceholderDuringPhasesWhereThisLineOfListDidntExistsDueToListChangedItsCount_existsOnlyToStayInXSyncWithOtherLinesOfList)
{
validStateOfNewDataPoint = ValidState.isPlaceholderDuringPhasesWhereThisLineOfListDidntExistsDueToListChangedItsCount_existsOnlyToStayInXSyncWithOtherLinesOfList;
}
else
{
if (float.IsNaN(xValue))
{
validStateOfNewDataPoint = ValidState.isNaN_atX;
}
else
{
if (float.IsPositiveInfinity(xValue))
{
validStateOfNewDataPoint = ValidState.isPositiveInfinity_atX;
}
else
{
if (float.IsNegativeInfinity(xValue))
{
validStateOfNewDataPoint = ValidState.isNegativeInfinity_atX;
}
else
{
if (float.IsNaN(yValue))
{
validStateOfNewDataPoint = ValidState.isNaN_atY;
}
else
{
if (float.IsPositiveInfinity(yValue))
{
validStateOfNewDataPoint = ValidState.isPositiveInfinity_atY;
}
else
{
if (float.IsNegativeInfinity(yValue))
{
validStateOfNewDataPoint = ValidState.isNegativeInfinity_atY;
}
}
}
}
}
}
}
return validStateOfNewDataPoint;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ea7c7f5c3b5bf064d9a53823137fecd3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,107 @@
namespace DrawXXL
{
using UnityEngine;
public class InternalDXXL_HorizontalThresholdLine
{
float yPosition;
bool lineItselfCountsToLowerArea;
ChartLine line_thisThresholdIsPartOf;
public InternalDXXL_HorizontalThresholdLine(float yPosition, ChartLine line_thisThresholdIsPartOf, bool lineItselfCountsToLowerArea)
{
this.yPosition = yPosition;
this.line_thisThresholdIsPartOf = line_thisThresholdIsPartOf;
this.lineItselfCountsToLowerArea = lineItselfCountsToLowerArea;
}
public PointOfInterest CheckIntersection(InternalDXXL_DataPointOfChartLine previousDataPoint, InternalDXXL_DataPointOfChartLine currDataPoint)
{
if (previousDataPoint.validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid && currDataPoint.validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid)
{
if (lineItselfCountsToLowerArea)
{
//lineItselfCountsTo-LOWER-area:
if (previousDataPoint.yValue <= yPosition)
{
if (currDataPoint.yValue > yPosition)
{
return CreateIntersectionPoint(previousDataPoint, currDataPoint);
}
}
else
{
if (currDataPoint.yValue <= yPosition)
{
return CreateIntersectionPoint(previousDataPoint, currDataPoint);
}
}
}
else
{
//lineItselfCountsTo-HIGHER-area:
if (previousDataPoint.yValue < yPosition)
{
if (currDataPoint.yValue >= yPosition)
{
return CreateIntersectionPoint(previousDataPoint, currDataPoint);
}
}
else
{
if (currDataPoint.yValue < yPosition)
{
return CreateIntersectionPoint(previousDataPoint, currDataPoint);
}
}
}
}
return null;
}
PointOfInterest CreateIntersectionPoint(InternalDXXL_DataPointOfChartLine previousDataPoint, InternalDXXL_DataPointOfChartLine currDataPoint)
{
previousDataPoint.hasLittleEmphasizingCircleAroundPoint = true;
currDataPoint.hasLittleEmphasizingCircleAroundPoint = true;
float x_ofIntersectionPos;
if (line_thisThresholdIsPartOf.lineConnectionsType == ChartLine.LineConnectionsType.horizPlateauTillNextPoint)
{
x_ofIntersectionPos = currDataPoint.xValue;
}
else
{
InternalDXXL_Line2D line2D_betweenDataPoints = new InternalDXXL_Line2D();
Vector2 previousDataPoint_asV2 = new Vector2(previousDataPoint.xValue, previousDataPoint.yValue);
Vector2 currDataPoint_asV2 = new Vector2(currDataPoint.xValue, currDataPoint.yValue);
line2D_betweenDataPoints.Recalc_line_throughTwoPoints_returnSteepForVertLines(previousDataPoint_asV2, currDataPoint_asV2);
x_ofIntersectionPos = line2D_betweenDataPoints.GetXatY(yPosition);
}
Color colorOfGeneratedIntersectionPoints = UtilitiesDXXL_Colors.GetSimilarColorWithSlightlyOtherBrightnessValue(line_thisThresholdIsPartOf.Color);
colorOfGeneratedIntersectionPoints.a = 1.0f;
string notificationText;
if (previousDataPoint.yValue < currDataPoint.yValue)
{
Color risingFlankColor = Color.Lerp(UtilitiesDXXL_Colors.green_boolTrue, colorOfGeneratedIntersectionPoints, 0.18f);
notificationText = "Line '" + line_thisThresholdIsPartOf.Name + "':<br><color=#" + ColorUtility.ToHtmlStringRGBA(risingFlankColor) + ">" + DrawText.MarkupIcon(DrawBasics.IconType.arrowUp) + "</color>Rising flank intersects threshold at<br>x = " + x_ofIntersectionPos + " / y = " + yPosition + "<br>Data point before intersection:<br>x = " + previousDataPoint.xValue + " / y = " + previousDataPoint.yValue + "<br>Data point after intersection:<br>x = " + currDataPoint.xValue + " / y = " + currDataPoint.yValue;
}
else
{
Color fallingFlankColor = Color.Lerp(UtilitiesDXXL_Colors.red_boolFalse, colorOfGeneratedIntersectionPoints, 0.18f);
notificationText = "Line '" + line_thisThresholdIsPartOf.Name + "':<br><color=#" + ColorUtility.ToHtmlStringRGBA(fallingFlankColor) + ">" + DrawText.MarkupIcon(DrawBasics.IconType.arrowDown) + "</color>Falling flank intersects threshold at<br>x = " + x_ofIntersectionPos + " / y = " + yPosition + "<br>Data point before intersection:<br>x = " + previousDataPoint.xValue + " / y = " + previousDataPoint.yValue + "<br>Data point after intersection:<br>x = " + currDataPoint.xValue + " / y = " + currDataPoint.yValue;
}
PointOfInterest pointOfInterest_thatIndicatesTheThresholdCrossing = new PointOfInterest(x_ofIntersectionPos, yPosition, colorOfGeneratedIntersectionPoints, line_thisThresholdIsPartOf.Chart_thisLineIsPartOf, line_thisThresholdIsPartOf, notificationText);
pointOfInterest_thatIndicatesTheThresholdCrossing.drawTextBoxIfPointIsOutsideOfChartArea = true;
pointOfInterest_thatIndicatesTheThresholdCrossing.isDeletedOnClear = true;
pointOfInterest_thatIndicatesTheThresholdCrossing.forceColorOfParent = false;
pointOfInterest_thatIndicatesTheThresholdCrossing.xValue.lineStyle = DrawBasics.LineStyle.invisible;
pointOfInterest_thatIndicatesTheThresholdCrossing.yValue.lineStyle = DrawBasics.LineStyle.invisible;
return pointOfInterest_thatIndicatesTheThresholdCrossing;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 38f65caec75b17548b15445629b00abb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
namespace DrawXXL
{
public struct InternalDXXL_HorizontalThresholdLineInitializer
{
public float yPositionOfThresholdToCreate;
public bool lineItselfCountsToLowerArea;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5cb7905e96a371f46b115fe814ce96c7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,247 @@
namespace DrawXXL
{
using System;
using UnityEngine;
[Serializable]
public class InternalDXXL_LineSpecsForChartInspector
{
static int default_numberOfDisplayedDatapointsInArray = 7;
public static bool lineCompoundNames_haveSpaces_betweenTheNamePartConnectingMinus = true;
public ChartLine line_theseSpecsBelongTo;
public bool currentHideLineState;
public bool currentHideCursorXState_duringComponentInspectionPhase = true;
public bool currentHideCursorYState_duringComponentInspectionPhase = false;
public Color lineColor;
public ChartLine.LineConnectionsType connectionsType;
public ChartLine.DataPointVisualization dataPointVisualization;
[Range(0.002f, 0.3f)] public float dataPointVisualization_size;
[Range(0.0f, 1.0f)] public float alpha_ofVertFillLines;
[Range(0.0f, 0.2f)] public float lineWidth;
public string linesCompoundName;
[SerializeField] int numberOfDisplayedDatapointsInArray = default_numberOfDisplayedDatapointsInArray;
[SerializeField] InternalDXXL_NeighboringDatapointForChartInspector[] neighboringDatapointValues;
[SerializeField] int i_insideShortenedForInspectorArray_markingTheValueAtCursor;
[SerializeField] bool lineSection_isExpanded = false;
[SerializeField] bool datapointValuesSection_isExpanded = false;
int i_ofValueInsideLinesDatapointListThatIsXNearestToCursor;
public bool hasValidDatapointThatIsXNearestToCursor = false;
public Vector2 posInChartspace_ofDatapointThatIsNearestToCursor;
public int i_ofThisLineSpec_insideChartInspectorsLinesSpecsArray;
public void TryRefill_arrayWithNeighboringDatapointValues()
{
TryReconstruct_arrayWithNeighboringDatapointValues();
if (lineSection_isExpanded && datapointValuesSection_isExpanded)
{
for (int i_currentlyFilledSlot_inShortenedInspectorArray = 0; i_currentlyFilledSlot_inShortenedInspectorArray < neighboringDatapointValues.Length; i_currentlyFilledSlot_inShortenedInspectorArray++)
{
if (hasValidDatapointThatIsXNearestToCursor)
{
int slotsDiffernceToCursorSlot = i_currentlyFilledSlot_inShortenedInspectorArray - i_insideShortenedForInspectorArray_markingTheValueAtCursor;
int i_insideLinesDatapointList = i_ofValueInsideLinesDatapointListThatIsXNearestToCursor + slotsDiffernceToCursorSlot;
if (i_insideLinesDatapointList < 0 || i_insideLinesDatapointList >= line_theseSpecsBelongTo.dataPoints.Count)
{
neighboringDatapointValues[i_currentlyFilledSlot_inShortenedInspectorArray].x = float.NaN;
neighboringDatapointValues[i_currentlyFilledSlot_inShortenedInspectorArray].y = float.NaN;
neighboringDatapointValues[i_currentlyFilledSlot_inShortenedInspectorArray].deltaSincePrecedingY = float.NaN;
}
else
{
neighboringDatapointValues[i_currentlyFilledSlot_inShortenedInspectorArray].x = line_theseSpecsBelongTo.dataPoints[i_insideLinesDatapointList].xValue;
neighboringDatapointValues[i_currentlyFilledSlot_inShortenedInspectorArray].y = line_theseSpecsBelongTo.dataPoints[i_insideLinesDatapointList].yValue;
if (i_insideLinesDatapointList < 1)
{
neighboringDatapointValues[i_currentlyFilledSlot_inShortenedInspectorArray].deltaSincePrecedingY = float.NaN;
}
else
{
neighboringDatapointValues[i_currentlyFilledSlot_inShortenedInspectorArray].deltaSincePrecedingY = line_theseSpecsBelongTo.dataPoints[i_insideLinesDatapointList].yValue - line_theseSpecsBelongTo.dataPoints[i_insideLinesDatapointList - 1].yValue;
}
}
}
else
{
//Obtainment of "i_ofValueInsideLinesDatapointListThatIsXNearestToCursor" failed:
neighboringDatapointValues[i_currentlyFilledSlot_inShortenedInspectorArray].x = float.NaN;
neighboringDatapointValues[i_currentlyFilledSlot_inShortenedInspectorArray].y = float.NaN;
neighboringDatapointValues[i_currentlyFilledSlot_inShortenedInspectorArray].deltaSincePrecedingY = float.NaN;
}
}
}
}
void TryReconstruct_arrayWithNeighboringDatapointValues()
{
numberOfDisplayedDatapointsInArray = Mathf.Max(numberOfDisplayedDatapointsInArray, 3);
numberOfDisplayedDatapointsInArray = Mathf.Min(numberOfDisplayedDatapointsInArray, 200); //-> why not exporting to CSV if many datapoints are needed? The editor will have performance problems with higher values
if (numberOfDisplayedDatapointsInArray != neighboringDatapointValues.Length) { Reconstruct_arrayWithNeighboringDatapointValues(); }
}
public void Reconstruct_arrayWithNeighboringDatapointValues()
{
neighboringDatapointValues = new InternalDXXL_NeighboringDatapointForChartInspector[numberOfDisplayedDatapointsInArray];
i_insideShortenedForInspectorArray_markingTheValueAtCursor = Mathf.RoundToInt(0.5f * (neighboringDatapointValues.Length - 1));
for (int i = 0; i < neighboringDatapointValues.Length; i++)
{
neighboringDatapointValues[i] = new InternalDXXL_NeighboringDatapointForChartInspector();
}
}
public void Recalc_posThatIsXNearestToCursor(float xValueOfCursor_inChartspace)
{
Calc_i_ofValueInsideLinesDatapointListThatIsXNearestToCursor(xValueOfCursor_inChartspace);
hasValidDatapointThatIsXNearestToCursor = (i_ofValueInsideLinesDatapointListThatIsXNearestToCursor >= 0);
if (hasValidDatapointThatIsXNearestToCursor)
{
posInChartspace_ofDatapointThatIsNearestToCursor = new Vector2(line_theseSpecsBelongTo.dataPoints[i_ofValueInsideLinesDatapointListThatIsXNearestToCursor].xValue, line_theseSpecsBelongTo.dataPoints[i_ofValueInsideLinesDatapointListThatIsXNearestToCursor].yValue);
}
else
{
posInChartspace_ofDatapointThatIsNearestToCursor = new Vector2(xValueOfCursor_inChartspace, 0.5f);
}
}
void Calc_i_ofValueInsideLinesDatapointListThatIsXNearestToCursor(float xValueOfCursor_inChartspace)
{
if (line_theseSpecsBelongTo.AllXValuesCameFromAutomaticSource)
{
//performance saving assumption: the x values always rise
int i_nearestBelowCursor = -1;
int i_nearestAboveCursor = line_theseSpecsBelongTo.dataPoints.Count;
RestrictPossibleCandidates(10000, out i_nearestBelowCursor, out i_nearestAboveCursor, i_nearestBelowCursor, i_nearestAboveCursor, xValueOfCursor_inChartspace);
RestrictPossibleCandidates(1000, out i_nearestBelowCursor, out i_nearestAboveCursor, i_nearestBelowCursor, i_nearestAboveCursor, xValueOfCursor_inChartspace);
RestrictPossibleCandidates(100, out i_nearestBelowCursor, out i_nearestAboveCursor, i_nearestBelowCursor, i_nearestAboveCursor, xValueOfCursor_inChartspace);
RestrictPossibleCandidates(10, out i_nearestBelowCursor, out i_nearestAboveCursor, i_nearestBelowCursor, i_nearestAboveCursor, xValueOfCursor_inChartspace);
if ((i_nearestBelowCursor < 0) && (i_nearestAboveCursor >= line_theseSpecsBelongTo.dataPoints.Count))
{
//pre-checks that restrict the datapoint candidates failed:
i_ofValueInsideLinesDatapointListThatIsXNearestToCursor = Get_i_datapointThatIsXNearestToCursor_viaBruteForceCheckAllDatapoints(xValueOfCursor_inChartspace);
}
else
{
if (i_nearestBelowCursor == i_nearestAboveCursor) { i_ofValueInsideLinesDatapointListThatIsXNearestToCursor = i_nearestBelowCursor; return; }
//cursor is left of whole line:
if (i_nearestAboveCursor <= 0) { i_ofValueInsideLinesDatapointListThatIsXNearestToCursor = 0; return; }
//cursor is right of whole line:
if (i_nearestBelowCursor >= (line_theseSpecsBelongTo.dataPoints.Count - 1)) { i_ofValueInsideLinesDatapointListThatIsXNearestToCursor = (line_theseSpecsBelongTo.dataPoints.Count - 1); return; }
i_nearestBelowCursor = Mathf.Max(i_nearestBelowCursor, 0);
i_nearestAboveCursor = Mathf.Min(i_nearestAboveCursor, (line_theseSpecsBelongTo.dataPoints.Count - 1));
i_ofValueInsideLinesDatapointListThatIsXNearestToCursor = Get_i_datapointThatIsXNearestToCursor_ofDatapointSpan(xValueOfCursor_inChartspace, i_nearestBelowCursor, i_nearestAboveCursor);
}
}
else
{
//no assumption that the x values always rise:
i_ofValueInsideLinesDatapointListThatIsXNearestToCursor = Get_i_datapointThatIsXNearestToCursor_viaBruteForceCheckAllDatapoints(xValueOfCursor_inChartspace);
}
}
void RestrictPossibleCandidates(int indexDistanceBetweenEachCheckedDatapoint, out int i_nearestBelowCursor, out int i_nearestAboveCursor, int i_nearestBelowCursor_atStartOfCheck, int i_nearestAboveCursor_atStartOfCheck, float xValueOfCursor_inChartspace)
{
i_nearestBelowCursor = i_nearestBelowCursor_atStartOfCheck;
i_nearestAboveCursor = i_nearestAboveCursor_atStartOfCheck;
indexDistanceBetweenEachCheckedDatapoint = Mathf.Max(indexDistanceBetweenEachCheckedDatapoint, 1);
for (int i_currentlyCheckedDatapoint = i_nearestBelowCursor_atStartOfCheck; i_currentlyCheckedDatapoint <= i_nearestAboveCursor_atStartOfCheck;)
{
if (i_currentlyCheckedDatapoint >= 0 && i_currentlyCheckedDatapoint < line_theseSpecsBelongTo.dataPoints.Count)
{
if (line_theseSpecsBelongTo.dataPoints[i_currentlyCheckedDatapoint].validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid)
{
if (line_theseSpecsBelongTo.dataPoints[i_currentlyCheckedDatapoint].xValue < xValueOfCursor_inChartspace)
{
i_nearestBelowCursor = i_currentlyCheckedDatapoint;
}
else
{
i_nearestAboveCursor = i_currentlyCheckedDatapoint;
break;
}
}
}
i_currentlyCheckedDatapoint = i_currentlyCheckedDatapoint + indexDistanceBetweenEachCheckedDatapoint;
}
}
int Get_i_datapointThatIsXNearestToCursor_viaBruteForceCheckAllDatapoints(float xValueOfCursor_inChartspace)
{
return Get_i_datapointThatIsXNearestToCursor_ofDatapointSpan(xValueOfCursor_inChartspace, 0, line_theseSpecsBelongTo.dataPoints.Count - 1);
}
int Get_i_datapointThatIsXNearestToCursor_ofDatapointSpan(float xValueOfCursor_inChartspace, int i_lowSpanEnd, int i_highSpanEnd)
{
//Debug.Log("span: <b>" + (i_highSpanEnd - i_lowSpanEnd) + "</b> i_lowSpanEnd : "+ i_lowSpanEnd + " i_highSpanEnd: "+ i_highSpanEnd);
int i_ofCurrentlyNearest = -1;
float absDistance_ofCurrentlyNearest = float.PositiveInfinity;
for (int i_currentlyCheckedDatapoint = i_lowSpanEnd; i_currentlyCheckedDatapoint <= i_highSpanEnd; i_currentlyCheckedDatapoint++)
{
if (line_theseSpecsBelongTo.dataPoints[i_currentlyCheckedDatapoint].validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid)
{
//some aggressive inlining:
float absDistanceToCursor = line_theseSpecsBelongTo.dataPoints[i_currentlyCheckedDatapoint].xValue - xValueOfCursor_inChartspace;
if (absDistanceToCursor < 0.0f)
{
absDistanceToCursor = -absDistanceToCursor;
}
if (absDistanceToCursor < absDistance_ofCurrentlyNearest)
{
absDistance_ofCurrentlyNearest = absDistanceToCursor;
i_ofCurrentlyNearest = i_currentlyCheckedDatapoint;
}
}
}
return i_ofCurrentlyNearest;
}
public void DrawCursorNearestPoint(float sizeOfDatapointVisualization, bool hiddenByNearerObjects)
{
if (currentHideLineState == false)
{
if ((currentHideCursorXState_duringComponentInspectionPhase == false) || (currentHideCursorYState_duringComponentInspectionPhase == false))
{
if (hasValidDatapointThatIsXNearestToCursor)
{
ChartDrawing parentChart = line_theseSpecsBelongTo.Chart_thisLineIsPartOf;
if (parentChart.IsInsideDrawnChartArea(posInChartspace_ofDatapointThatIsNearestToCursor) || parentChart.drawValuesOutsideOfChartArea)
{
Vector3 position_worldSpace = parentChart.ChartSpace_to_WorldSpace(posInChartspace_ofDatapointThatIsNearestToCursor);
float sizeOfMarkingCross = parentChart.Height_inWorldSpace * (0.01f + 0.6f * sizeOfDatapointVisualization);
Color datapointColor = line_theseSpecsBelongTo.Color;
DrawBasics.Point(position_worldSpace, datapointColor, sizeOfMarkingCross, parentChart.InternalRotation, 0.0f, null, datapointColor, false, false, true, 0.0f, hiddenByNearerObjects);
float circleRadius = 0.14f * sizeOfMarkingCross;
DrawShapes.Decagon(position_worldSpace, circleRadius, datapointColor, parentChart.InternalRotation, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, 0.0f, hiddenByNearerObjects);
float textSize = 0.3f * sizeOfMarkingCross;
float dimensionSpecifyingTextSize = textSize * 0.5f;
Color color_ofDimensionSpecifier = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(datapointColor, 0.4f);
if (currentHideCursorYState_duringComponentInspectionPhase == false)
{
UtilitiesDXXL_Text.WriteFramed(" y=", position_worldSpace, color_ofDimensionSpecifier, dimensionSpecifyingTextSize, parentChart.InternalRotation, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, parentChart.autoFlipAllText_toFitObsererCamera, 0.0f, hiddenByNearerObjects);
UtilitiesDXXL_Text.WriteFramed(" " + posInChartspace_ofDatapointThatIsNearestToCursor.y, position_worldSpace, datapointColor, textSize, parentChart.InternalRotation, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, parentChart.autoFlipAllText_toFitObsererCamera, 0.0f, hiddenByNearerObjects);
}
if (currentHideCursorXState_duringComponentInspectionPhase == false)
{
Vector3 textDir_forXText_normalized = parentChart.yAxis.AxisVector_normalized_inWorldSpace;
Vector3 textUp_forXText_normalized = -parentChart.xAxis.AxisVector_normalized_inWorldSpace;
UtilitiesDXXL_Text.Write(" x=", position_worldSpace, color_ofDimensionSpecifier, dimensionSpecifyingTextSize, textDir_forXText_normalized, textUp_forXText_normalized, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, parentChart.autoFlipAllText_toFitObsererCamera, 0.0f, hiddenByNearerObjects, false, false, true);
UtilitiesDXXL_Text.Write(" " + posInChartspace_ofDatapointThatIsNearestToCursor.x, position_worldSpace, datapointColor, textSize, textDir_forXText_normalized, textUp_forXText_normalized, DrawText.TextAnchorDXXL.LowerLeftOfFirstLine, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, parentChart.autoFlipAllText_toFitObsererCamera, 0.0f, hiddenByNearerObjects, false, false, true);
}
}
}
}
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 17d8a010df19ac94abcdc1b898f79166
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,12 @@
namespace DrawXXL
{
using System;
[Serializable]
public struct InternalDXXL_NeighboringDatapointForChartInspector
{
public float x;
public float y;
public float deltaSincePrecedingY;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6e0462d2ff3fca04fb36e93d040db7a0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,9 @@
namespace DrawXXL
{
public class InternalDXXL_TurningPoint //This is "class" instead of "struct" because it should be nullable
{
public PointOfInterest pointOfInterest_thatRepresentsThisTurningPoint;
public bool isTheEndOfAPlateau;
public bool isTheMostRightOf_theNonPlataueEndTurningPointsAtSameYHeight;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bff8d6ed15c7bc947a984463baadaa55
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,393 @@
namespace DrawXXL
{
using UnityEngine;
using System.Collections.Generic;
public class InternalDXXL_TurningPointDetector
{
List<InternalDXXL_TurningPoint> allUpperTurningPoints = new List<InternalDXXL_TurningPoint>();
List<InternalDXXL_TurningPoint> allLowerTurningPoints = new List<InternalDXXL_TurningPoint>();
List<InternalDXXL_TurningPoint> turningPoints_thatHighlightOnlyTheOverallHighestYValue = new List<InternalDXXL_TurningPoint>();
List<InternalDXXL_TurningPoint> turningPoints_thatHighlightOnlyTheOverallLowestYValue = new List<InternalDXXL_TurningPoint>();
int i_ofDatapoint_thatIsCurrentCandidateFor_startOfMaxPlateau;
int i_ofDatapoint_thatIsCurrentCandidateFor_endOfMaxPlateau;
int i_ofDatapoint_thatIsCurrentCandidateFor_startOfMinPlateau;
int i_ofDatapoint_thatIsCurrentCandidateFor_endOfMinPlateau;
int i_ofPrecedingDatapoint;
ChartLine line_thisDetectorIsPartOf;
public InternalDXXL_TurningPointDetector(ChartLine line_thisDetectorIsPartOf)
{
this.line_thisDetectorIsPartOf = line_thisDetectorIsPartOf;
DiscardPrecedingPointsFromComparison();
}
public void Clear()
{
allUpperTurningPoints.Clear();
allLowerTurningPoints.Clear();
turningPoints_thatHighlightOnlyTheOverallHighestYValue.Clear();
turningPoints_thatHighlightOnlyTheOverallLowestYValue.Clear();
DiscardPrecedingPointsFromComparison();
}
public void DiscardPrecedingPointsFromComparison()
{
i_ofPrecedingDatapoint = -1;
i_ofDatapoint_thatIsCurrentCandidateFor_startOfMaxPlateau = -1;
i_ofDatapoint_thatIsCurrentCandidateFor_endOfMaxPlateau = -1;
i_ofDatapoint_thatIsCurrentCandidateFor_startOfMinPlateau = -1;
i_ofDatapoint_thatIsCurrentCandidateFor_endOfMinPlateau = -1;
}
public void AddNewDatapoint(int i_newDatapoint)
{
if (line_thisDetectorIsPartOf.dataPoints[i_newDatapoint].validState == InternalDXXL_DataPointOfChartLine.ValidState.isValid)
{
if (i_ofPrecedingDatapoint >= 0)
{
CheckMaxPlateau(i_newDatapoint);
CheckMinPlateau(i_newDatapoint);
}
i_ofPrecedingDatapoint = i_newDatapoint;
}
else
{
//New datapoint is invalid:
DiscardPrecedingPointsFromComparison();
}
}
void CheckMaxPlateau(int i_newDatapoint)
{
if (line_thisDetectorIsPartOf.dataPoints[i_newDatapoint].yValue > line_thisDetectorIsPartOf.dataPoints[i_ofPrecedingDatapoint].yValue)
{
i_ofDatapoint_thatIsCurrentCandidateFor_startOfMaxPlateau = i_newDatapoint;
i_ofDatapoint_thatIsCurrentCandidateFor_endOfMaxPlateau = i_newDatapoint;
}
else
{
if (line_thisDetectorIsPartOf.dataPoints[i_newDatapoint].yValue == line_thisDetectorIsPartOf.dataPoints[i_ofPrecedingDatapoint].yValue)
{
i_ofDatapoint_thatIsCurrentCandidateFor_endOfMaxPlateau = i_newDatapoint;
}
else
{
if (i_ofDatapoint_thatIsCurrentCandidateFor_startOfMaxPlateau > 0)
{
CreateTurningPoint_atMaxPlateau();
}
i_ofDatapoint_thatIsCurrentCandidateFor_startOfMaxPlateau = -1;
i_ofDatapoint_thatIsCurrentCandidateFor_endOfMaxPlateau = -1;
}
}
}
void CreateTurningPoint_atMaxPlateau()
{
bool isPlateauConsistingOfTwoInsteadOfOnlyOnePointOfInterest = (i_ofDatapoint_thatIsCurrentCandidateFor_endOfMaxPlateau != i_ofDatapoint_thatIsCurrentCandidateFor_startOfMaxPlateau);
//string labelText_atVertLine = isPlateauConsistingOfTwoInsteadOfOnlyOnePointOfInterest ? "start of max" : null; //->would be too packed in many situations
InternalDXXL_TurningPoint turningPoint_atStartOfMaxPlateau = CreateTurningPoint(i_ofDatapoint_thatIsCurrentCandidateFor_startOfMaxPlateau, "max", false);
InternalDXXL_TurningPoint turningPoint_atEndOfMaxPlateau = null;
if (isPlateauConsistingOfTwoInsteadOfOnlyOnePointOfInterest)
{
turningPoint_atEndOfMaxPlateau = CreateTurningPoint(i_ofDatapoint_thatIsCurrentCandidateFor_endOfMaxPlateau, null, true);
}
bool addToListWithOverallHighestTurningPoints = CompareWith_overallHighestValues();
allUpperTurningPoints.Add(turningPoint_atStartOfMaxPlateau);
if (addToListWithOverallHighestTurningPoints) { turningPoints_thatHighlightOnlyTheOverallHighestYValue.Add(turningPoint_atStartOfMaxPlateau); }
line_thisDetectorIsPartOf.AddPointOfInterest(turningPoint_atStartOfMaxPlateau.pointOfInterest_thatRepresentsThisTurningPoint);
if (turningPoint_atEndOfMaxPlateau != null)
{
allUpperTurningPoints.Add(turningPoint_atEndOfMaxPlateau);
if (addToListWithOverallHighestTurningPoints) { turningPoints_thatHighlightOnlyTheOverallHighestYValue.Add(turningPoint_atEndOfMaxPlateau); }
line_thisDetectorIsPartOf.AddPointOfInterest(turningPoint_atEndOfMaxPlateau.pointOfInterest_thatRepresentsThisTurningPoint);
}
}
bool CompareWith_overallHighestValues()
{
if (turningPoints_thatHighlightOnlyTheOverallHighestYValue.Count > 0)
{
if (line_thisDetectorIsPartOf.dataPoints[i_ofDatapoint_thatIsCurrentCandidateFor_startOfMaxPlateau].yValue > turningPoints_thatHighlightOnlyTheOverallHighestYValue[0].pointOfInterest_thatRepresentsThisTurningPoint.yValue.position)
{
turningPoints_thatHighlightOnlyTheOverallHighestYValue.Clear();
return true;
}
else
{
if (line_thisDetectorIsPartOf.dataPoints[i_ofDatapoint_thatIsCurrentCandidateFor_startOfMaxPlateau].yValue == turningPoints_thatHighlightOnlyTheOverallHighestYValue[0].pointOfInterest_thatRepresentsThisTurningPoint.yValue.position)
{
return true;
}
else
{
return false;
}
}
}
else
{
return true;
}
}
void CheckMinPlateau(int i_newDatapoint)
{
if (line_thisDetectorIsPartOf.dataPoints[i_newDatapoint].yValue < line_thisDetectorIsPartOf.dataPoints[i_ofPrecedingDatapoint].yValue)
{
i_ofDatapoint_thatIsCurrentCandidateFor_startOfMinPlateau = i_newDatapoint;
i_ofDatapoint_thatIsCurrentCandidateFor_endOfMinPlateau = i_newDatapoint;
}
else
{
if (line_thisDetectorIsPartOf.dataPoints[i_newDatapoint].yValue == line_thisDetectorIsPartOf.dataPoints[i_ofPrecedingDatapoint].yValue)
{
i_ofDatapoint_thatIsCurrentCandidateFor_endOfMinPlateau = i_newDatapoint;
}
else
{
if (i_ofDatapoint_thatIsCurrentCandidateFor_startOfMinPlateau > 0)
{
CreateTurningPointOf_atMinPlateau();
}
i_ofDatapoint_thatIsCurrentCandidateFor_startOfMinPlateau = -1;
i_ofDatapoint_thatIsCurrentCandidateFor_endOfMinPlateau = -1;
}
}
}
void CreateTurningPointOf_atMinPlateau()
{
bool isPlateauConsistingOfTwoInsteadOfOnlyOnePointOfInterest = (i_ofDatapoint_thatIsCurrentCandidateFor_endOfMinPlateau != i_ofDatapoint_thatIsCurrentCandidateFor_startOfMinPlateau);
//string labelText_atVertLine = isPlateauConsistingOfTwoInsteadOfOnlyOnePointOfInterest ? "start of min" : null;//->would be too packed in many situations
InternalDXXL_TurningPoint turningPoint_atStartOfMinPlateau = CreateTurningPoint(i_ofDatapoint_thatIsCurrentCandidateFor_startOfMinPlateau, "min", false);
InternalDXXL_TurningPoint turningPoint_atEndOfMinPlateau = null;
if (isPlateauConsistingOfTwoInsteadOfOnlyOnePointOfInterest)
{
turningPoint_atEndOfMinPlateau = CreateTurningPoint(i_ofDatapoint_thatIsCurrentCandidateFor_endOfMinPlateau, null, true);
}
bool addToListWithOverallLowestTurningPoints = CompareWith_overallLowestValues();
allLowerTurningPoints.Add(turningPoint_atStartOfMinPlateau);
if (addToListWithOverallLowestTurningPoints) { turningPoints_thatHighlightOnlyTheOverallLowestYValue.Add(turningPoint_atStartOfMinPlateau); }
line_thisDetectorIsPartOf.AddPointOfInterest(turningPoint_atStartOfMinPlateau.pointOfInterest_thatRepresentsThisTurningPoint);
if (turningPoint_atEndOfMinPlateau != null)
{
allLowerTurningPoints.Add(turningPoint_atEndOfMinPlateau);
if (addToListWithOverallLowestTurningPoints) { turningPoints_thatHighlightOnlyTheOverallLowestYValue.Add(turningPoint_atEndOfMinPlateau); }
line_thisDetectorIsPartOf.AddPointOfInterest(turningPoint_atEndOfMinPlateau.pointOfInterest_thatRepresentsThisTurningPoint);
}
}
bool CompareWith_overallLowestValues()
{
if (turningPoints_thatHighlightOnlyTheOverallLowestYValue.Count > 0)
{
if (line_thisDetectorIsPartOf.dataPoints[i_ofDatapoint_thatIsCurrentCandidateFor_startOfMinPlateau].yValue < turningPoints_thatHighlightOnlyTheOverallLowestYValue[0].pointOfInterest_thatRepresentsThisTurningPoint.yValue.position)
{
turningPoints_thatHighlightOnlyTheOverallLowestYValue.Clear();
return true;
}
else
{
if (line_thisDetectorIsPartOf.dataPoints[i_ofDatapoint_thatIsCurrentCandidateFor_startOfMinPlateau].yValue == turningPoints_thatHighlightOnlyTheOverallLowestYValue[0].pointOfInterest_thatRepresentsThisTurningPoint.yValue.position)
{
return true;
}
else
{
return false;
}
}
}
else
{
return true;
}
}
InternalDXXL_TurningPoint CreateTurningPoint(int i_ofDatapointWhereToCreate, string labelText_atHorizLine, bool isEndOfPlateau)
{
float position_x = line_thisDetectorIsPartOf.dataPoints[i_ofDatapointWhereToCreate].xValue;
float position_y = line_thisDetectorIsPartOf.dataPoints[i_ofDatapointWhereToCreate].yValue;
PointOfInterest createdPointOfInterest = new PointOfInterest(position_x, position_y, DrawBasics.defaultColor, line_thisDetectorIsPartOf.Chart_thisLineIsPartOf, line_thisDetectorIsPartOf, null);
createdPointOfInterest.drawTextBoxIfPointIsOutsideOfChartArea = false;
createdPointOfInterest.isDeletedOnClear = true;
createdPointOfInterest.forceColorOfParent = true;
//createdPointOfInterest.xValue.labelText = labelText_atVertLine;
createdPointOfInterest.xValue.labelText = null;
createdPointOfInterest.xValue.drawCoordinateAsText = true;
createdPointOfInterest.xValue.lineExtent = DimensionOf_PointOfInterest.LineExtent.axisToPoint;
createdPointOfInterest.xValue.linestylePatternScaleFactor = 0.8f;
createdPointOfInterest.yValue.labelText = labelText_atHorizLine + " = " + line_thisDetectorIsPartOf.dataPoints[i_ofDatapointWhereToCreate].yValue;
createdPointOfInterest.yValue.drawCoordinateAsText = false;
createdPointOfInterest.yValue.lineExtent = DimensionOf_PointOfInterest.LineExtent.axisToPoint;
InternalDXXL_TurningPoint createdTurningPoint = new InternalDXXL_TurningPoint();
createdTurningPoint.pointOfInterest_thatRepresentsThisTurningPoint = createdPointOfInterest;
createdTurningPoint.isTheEndOfAPlateau = isEndOfPlateau;
return createdTurningPoint;
}
public void SetIfVisualizationIsDisplayed()
{
SetIfVisualizationOfYMaximumTurningPointsIsDisplayed();
SetIfVisualizationOfYMinimumTurningPointsIsDisplayed();
SetIfVisualizationOfSingleHighestValueIsDisplayed();
SetIfVisualizationOfSingleLowestValueIsDisplayed();
}
void SetIfVisualizationOfYMaximumTurningPointsIsDisplayed()
{
if (line_thisDetectorIsPartOf.markAllYMaximumTurningPoints)
{
SetVisibleState_forListOf_pointsOfInterest(true, allUpperTurningPoints, true, false);
}
else
{
SetVisibleState_forListOf_pointsOfInterest(false, allUpperTurningPoints, true, false);
}
}
void SetIfVisualizationOfYMinimumTurningPointsIsDisplayed()
{
if (line_thisDetectorIsPartOf.markAllYMinimumTurningPoints)
{
SetVisibleState_forListOf_pointsOfInterest(true, allLowerTurningPoints, false, false);
}
else
{
SetVisibleState_forListOf_pointsOfInterest(false, allLowerTurningPoints, false, false);
}
}
void SetIfVisualizationOfSingleHighestValueIsDisplayed()
{
if (line_thisDetectorIsPartOf.markAllYMaximumTurningPoints == false)
{
//-> all turningPoints are turned to invisible, if arriving here
if (UtilitiesDXXL_Math.ApproximatelyZero(line_thisDetectorIsPartOf.alpha_ofMaxiumumYValueMarker) == false)
{
SetVisibleState_forListOf_pointsOfInterest(true, turningPoints_thatHighlightOnlyTheOverallHighestYValue, true, true);
}
}
}
void SetIfVisualizationOfSingleLowestValueIsDisplayed()
{
if (line_thisDetectorIsPartOf.markAllYMinimumTurningPoints == false)
{
//-> all turningPoints are turned to invisible, if arriving here
if (UtilitiesDXXL_Math.ApproximatelyZero(line_thisDetectorIsPartOf.alpha_ofMinimumYValueMarker) == false)
{
SetVisibleState_forListOf_pointsOfInterest(true, turningPoints_thatHighlightOnlyTheOverallLowestYValue, false, true);
}
}
}
void SetVisibleState_forListOf_pointsOfInterest(bool shouldBeVisible, List<InternalDXXL_TurningPoint> concernedTurningPoints, bool isHighTurningPoint_notLow, bool forceInvisibleIfItIsNotTheMostExtremePointOfTheWholeLine)
{
if (shouldBeVisible)
{
MarkPointsIfTheyAre_theMostRightOf_theNonPlataueEndTurningPointsAtSameYHeight(concernedTurningPoints);
for (int i = 0; i < concernedTurningPoints.Count; i++)
{
if (isHighTurningPoint_notLow)
{
//high turning points:
if (forceInvisibleIfItIsNotTheMostExtremePointOfTheWholeLine)
{
//-> The first and the last datapoint or datapoints beside invalid values can be more extreme but don't count as turning points
float yOfTurningPoint = concernedTurningPoints[i].pointOfInterest_thatRepresentsThisTurningPoint.yValue.position;
if (yOfTurningPoint < line_thisDetectorIsPartOf.HighestYValue) { continue; }
}
concernedTurningPoints[i].pointOfInterest_thatRepresentsThisTurningPoint.xValue.color = new Color(1, 1, 1, line_thisDetectorIsPartOf.alpha_ofMaxiumumYValueMarker); //-> only for setting alpha. The actual color gets forced from lineParent
concernedTurningPoints[i].pointOfInterest_thatRepresentsThisTurningPoint.yValue.color = new Color(1, 1, 1, line_thisDetectorIsPartOf.alpha_ofMaxiumumYValueMarker); //-> only for setting alpha. The actual color gets forced from lineParent
}
else
{
//low turning points:
if (forceInvisibleIfItIsNotTheMostExtremePointOfTheWholeLine)
{
//-> The first and the last datapoint or datapoints beside invalid values can be more extreme but don't count as turning points
float yOfTurningPoint = concernedTurningPoints[i].pointOfInterest_thatRepresentsThisTurningPoint.yValue.position;
if (yOfTurningPoint > line_thisDetectorIsPartOf.LowestYValue) { continue; }
}
concernedTurningPoints[i].pointOfInterest_thatRepresentsThisTurningPoint.xValue.color = new Color(1, 1, 1, line_thisDetectorIsPartOf.alpha_ofMinimumYValueMarker); //-> only for setting alpha. The actual color gets forced from lineParent
concernedTurningPoints[i].pointOfInterest_thatRepresentsThisTurningPoint.yValue.color = new Color(1, 1, 1, line_thisDetectorIsPartOf.alpha_ofMinimumYValueMarker); //-> only for setting alpha. The actual color gets forced from lineParent
}
DrawBasics.LineStyle linestyle_forHorizLine = DrawBasics.LineStyle.solid;
if (concernedTurningPoints[i].isTheEndOfAPlateau) { linestyle_forHorizLine = DrawBasics.LineStyle.invisible; }
if (concernedTurningPoints[i].isTheMostRightOf_theNonPlataueEndTurningPointsAtSameYHeight == false) { linestyle_forHorizLine = DrawBasics.LineStyle.invisible; } //-> This prevents multiple points at the same yHeight from adding up their alpha from the horizontal low alpha turningPointMarkerLines until it is almost alpha=1 and is not distinguishable anymore from the dataLine itself.
if (line_thisDetectorIsPartOf.disableMinMaxYVisualizers_dueTo_lineRepresentsBoolValues) { linestyle_forHorizLine = DrawBasics.LineStyle.invisible; }
concernedTurningPoints[i].pointOfInterest_thatRepresentsThisTurningPoint.xValue.lineStyle = DrawBasics.LineStyle.dashed;
concernedTurningPoints[i].pointOfInterest_thatRepresentsThisTurningPoint.yValue.lineStyle = linestyle_forHorizLine;
}
}
else
{
for (int i = 0; i < concernedTurningPoints.Count; i++)
{
concernedTurningPoints[i].pointOfInterest_thatRepresentsThisTurningPoint.xValue.lineStyle = DrawBasics.LineStyle.invisible;
concernedTurningPoints[i].pointOfInterest_thatRepresentsThisTurningPoint.yValue.lineStyle = DrawBasics.LineStyle.invisible;
}
}
}
void MarkPointsIfTheyAre_theMostRightOf_theNonPlataueEndTurningPointsAtSameYHeight(List<InternalDXXL_TurningPoint> concernedTurningPoints)
{
for (int i_currCheckedTurningPoint = 0; i_currCheckedTurningPoint < concernedTurningPoints.Count; i_currCheckedTurningPoint++)
{
if (concernedTurningPoints[i_currCheckedTurningPoint].isTheEndOfAPlateau)
{
concernedTurningPoints[i_currCheckedTurningPoint].isTheMostRightOf_theNonPlataueEndTurningPointsAtSameYHeight = false;
continue;
}
else
{
concernedTurningPoints[i_currCheckedTurningPoint].isTheMostRightOf_theNonPlataueEndTurningPointsAtSameYHeight = true;
}
for (int i_currLowerComparedTurningPoint = 0; i_currLowerComparedTurningPoint < i_currCheckedTurningPoint; i_currLowerComparedTurningPoint++)
{
if (concernedTurningPoints[i_currLowerComparedTurningPoint].isTheEndOfAPlateau)
{
continue;
}
else
{
float y_ofCurrCheckedTurningPoint = concernedTurningPoints[i_currCheckedTurningPoint].pointOfInterest_thatRepresentsThisTurningPoint.yValue.position;
float y_ofCurrLowerComparedTurningPoint = concernedTurningPoints[i_currLowerComparedTurningPoint].pointOfInterest_thatRepresentsThisTurningPoint.yValue.position;
if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(y_ofCurrCheckedTurningPoint, y_ofCurrLowerComparedTurningPoint))
{
float x_ofCurrCheckedTurningPoint = concernedTurningPoints[i_currCheckedTurningPoint].pointOfInterest_thatRepresentsThisTurningPoint.xValue.position;
float x_ofCurrLowerComparedTurningPoint = concernedTurningPoints[i_currLowerComparedTurningPoint].pointOfInterest_thatRepresentsThisTurningPoint.xValue.position;
if (x_ofCurrCheckedTurningPoint > x_ofCurrLowerComparedTurningPoint)
{
concernedTurningPoints[i_currLowerComparedTurningPoint].isTheMostRightOf_theNonPlataueEndTurningPointsAtSameYHeight = false;
}
else
{
concernedTurningPoints[i_currCheckedTurningPoint].isTheMostRightOf_theNonPlataueEndTurningPointsAtSameYHeight = false;
break;
}
}
}
}
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e7190062bd9564f4eb7527ea9c08d402
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a7bf68dbb34f7c041bb4f776bea9575f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,163 @@
namespace DrawXXL
{
public class UtilitiesDXXL_ChartLine
{
public delegate bool IsDrawnBecause_theSingleComponentOfMulticomponentData_thisLineRepresents_isEnabledChecker(DataComponentsThatAreDrawn dataComponentsThatAreDrawn);
//Non-multiComponentData:
public static bool DoDrawBecauseLineDoesntRepresentMultiComponentData(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return true;
}
//Vector2:
public static bool DrawIf_vector2_x_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.vector2_x;
}
public static bool DrawIf_vector2_y_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.vector2_y;
}
//Vector3:
public static bool DrawIf_vector3_x_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.vector3_x;
}
public static bool DrawIf_vector3_y_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.vector3_y;
}
public static bool DrawIf_vector3_z_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.vector3_z;
}
//Vector4:
public static bool DrawIf_vector4_x_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.vector4_x;
}
public static bool DrawIf_vector4_y_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.vector4_y;
}
public static bool DrawIf_vector4_z_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.vector4_z;
}
public static bool DrawIf_vector4_w_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.vector4_w;
}
//Color:
public static bool DrawIf_color_r_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.color_r;
}
public static bool DrawIf_color_g_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.color_g;
}
public static bool DrawIf_color_b_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.color_b;
}
public static bool DrawIf_color_a_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.color_a;
}
//Rotation:
public static bool DrawIf_rotation_eulerX_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.rotation_eulerX;
}
public static bool DrawIf_rotation_eulerY_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.rotation_eulerY;
}
public static bool DrawIf_rotation_eulerZ_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.rotation_eulerZ;
}
//Transform:
public static bool DrawIf_localPosition_x_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.localPosition_x;
}
public static bool DrawIf_localPosition_y_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.localPosition_y;
}
public static bool DrawIf_localPosition_z_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.localPosition_z;
}
public static bool DrawIf_localEulerAngle_x_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.localEulerAngle_x;
}
public static bool DrawIf_localEulerAngle_y_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.localEulerAngle_y;
}
public static bool DrawIf_localEulerAngle_z_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.localEulerAngle_z;
}
public static bool DrawIf_localScale_x_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.localScale_x;
}
public static bool DrawIf_localScale_y_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.localScale_y;
}
public static bool DrawIf_localScale_z_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.localScale_z;
}
public static bool DrawIf_globalPosition_x_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.globalPosition_x;
}
public static bool DrawIf_globalPosition_y_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.globalPosition_y;
}
public static bool DrawIf_globalPosition_z_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.globalPosition_z;
}
public static bool DrawIf_globalEulerAngle_x_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.globalEulerAngle_x;
}
public static bool DrawIf_globalEulerAngle_y_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.globalEulerAngle_y;
}
public static bool DrawIf_globalEulerAngle_z_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.globalEulerAngle_z;
}
public static bool DrawIf_lossyScale_x_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.lossyScale_x;
}
public static bool DrawIf_lossyScale_y_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.lossyScale_y;
}
public static bool DrawIf_lossyScale_z_isEnabled(DataComponentsThatAreDrawn dataComponentsThatAreDrawn)
{
return dataComponentsThatAreDrawn.lossyScale_z;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c62dec88fec09a3458a145bf8261f5c6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c35c0bee2a8b75c4d88f55da8ac32278
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,932 @@
namespace DrawXXL
{
using UnityEngine;
using System.Collections.Generic;
public class PieChartDrawing
{
public enum RotationSource
{
screen,
screen_butVerticalInWorldSpace,
userDefinedFixedRotation
}
public RotationSource rotationSource = RotationSource.screen;
public int internal_indexNumberOfPremadeChart = -1; //-> this is used internally for the automatic layout of the premade chart, whose position hasn't been explicitly set by the user.
private Vector3 position_worldspace = Vector3.zero;
public Vector3 Position_worldspace
{
get
{
if (internal_indexNumberOfPremadeChart == (-1))
{
return position_worldspace;
}
else
{
return DrawCharts.GetAutoLayoutedPositionOfPremadePieChart(this);
}
}
set
{
position_worldspace = value;
internal_indexNumberOfPremadeChart = -1; //-> if a user sets the position, then the chart is not affected anymore by the automatic layouting of the premade charts.
}
}
public Quaternion fixedRotation = Quaternion.identity;
public Quaternion internalRotation = Quaternion.identity; //This is the internally used rotation. The user should use "fixedRotation" instead. "fixedRotation" does nothing but getting filled into this before drawing if "rotationSource=userDefinedFixedRotation"
private float size_ofPieCircleDiameter = 1.0f;
public float Size_ofPieCircleDiameter
{
get { return size_ofPieCircleDiameter; }
set { size_ofPieCircleDiameter = Mathf.Clamp(value, 0.001f, 100000.0f); }
}
public Vector2 position_inCamViewportspace = new Vector2(0.41f, 0.41f);
private float size_ofPieCircleDiameter_relToCamViewport = 0.45f;
public float Size_ofPieCircleDiameter_relToCamViewport
{
get { return size_ofPieCircleDiameter_relToCamViewport; }
set { size_ofPieCircleDiameter_relToCamViewport = Mathf.Clamp(value, 0.01f, 2.0f); }
}
private Vector3 right_normalized;
public Vector3 Right_normalized
{
get { return right_normalized; }
set { Debug.LogError("Setting 'Right_normalized' directly is not supported. Use 'rotationSource' and 'fixedRotation' instead."); }
}
private Vector3 up_normalized;
public Vector3 Up_normalized
{
get { return up_normalized; }
set { Debug.LogError("Setting 'Up_normalized' directly is not supported. Use 'rotationSource' and 'fixedRotation' instead."); }
}
private Vector3 forward_normalized;
public Vector3 Forward_normalized
{
get { return forward_normalized; }
set { Debug.LogError("Setting 'Forward_normalized' directly is not supported. Use 'rotationSource' and 'fixedRotation' instead."); }
}
public float mostRecent_vertDistance_fromCircleCenter_toUpperBounderySquare = 0.0f;
public enum SegmentSorting
{
decreasingSize_clockwise,
decreasingSize_counterClockwise,
creationOrder_clockwise,
creationOrder_counterClockwise
}
public SegmentSorting segmentSorting = SegmentSorting.decreasingSize_clockwise;
public float angleDegCCfromUp_whereMainSegmentStarts = 0.0f;
private string title;
private string title_insideMarkup;
public string Title
{
get { return title; }
set
{
title = value;
title_insideMarkup = "<sw=50000>" + title + "</sw>";
}
}
public string subTitle;
static float default_luminanceOfSegmentColors = 0.5f;
private float luminanceOfSegmentColors = default_luminanceOfSegmentColors;
public float LuminanceOfSegmentColors
{
get { return luminanceOfSegmentColors; }
set
{
value = Mathf.Clamp01(value);
ReassignLuminanceToSegmentColors(luminanceOfSegmentColors, value);
luminanceOfSegmentColors = value;
}
}
public Color color = DrawBasics.defaultColor;
private float relSize_ofSegmentsNameTexts = 1.0f;
public float RelSize_ofSegmentsNameTexts
{
get { return relSize_ofSegmentsNameTexts; }
set { relSize_ofSegmentsNameTexts = Mathf.Clamp(value, 0.01f, 10.0f); }
}
public int postDecimalPositions_ofPercentageDisplay = 1;
public bool trackNegativeValues = false; //The pie chart cannot display negative values. Though it is possible that the value of a segment ends up in the negative area, e.g. by adding negative values via "AddValue()" or frequent calling of "DecrementValue()". The chart will not display segments with negative values, but it can keep track of negative values. Example: The "DecrementValue()" function is called five times on a segment. So the value is at "-5". If "trackNegativeValues" is true, then it needs 6 calls of "IncrementValue()" for the segment value to reach "1" (the first value where it can be displayed again in the chart). If "trackNegativeValues" is set to "false" then all negative values are discarded and it needs only one call of "IncrementValue" to reach the segment value of "1".
private float percentageThreshold_belowWhichSegmentsGetCombinedInto_othersSection = 1.0f;
public float PercentageThreshold_belowWhichSegmentsGetCombinedInto_othersSection
{
get { return percentageThreshold_belowWhichSegmentsGetCombinedInto_othersSection; }
set { percentageThreshold_belowWhichSegmentsGetCombinedInto_othersSection = Mathf.Clamp(value, 0.01f, 99.0f); }
}
List<PieChartSegment> segments_inCreationOrder = new List<PieChartSegment>();
List<PieChartSegment> segments_orderedForDrawing = new List<PieChartSegment>();
List<PieChartSegment> segments_orderedWithDecreasingSize = new List<PieChartSegment>();
List<InternalDXXL_PieAngleSpan> angleSpans_thatAreAlreadyCoveredWithText = new List<InternalDXXL_PieAngleSpan>();
PieChartSegment combinedOthersSegment;
public bool mentionZeroSegmentsInLegend = true; //This determines if empty segments with value of 0 are displayed in the text legend column on the right side of the chart.
public bool showSegmentNames = true;
public bool showSegmentValues = true;
public bool showSegmentPercentages = true;
public bool autoFlipAllText_toFitObsererCamera = true;
public PieChartDrawing(string title = null)
{
Title = title;
combinedOthersSegment = new PieChartSegment("Others", this, 1000000);
combinedOthersSegment.color = SeededColorGenerator.ForceApproxLuminance(Color.gray, default_luminanceOfSegmentColors);
}
public void Draw(float durationInSec = 0.0f, bool hiddenByNearerObjects = true)
{
DXXLWrapperForUntiysBuildInDrawLines.currentlyDrawingPieChart = this;
ApplyInternalRotation(); // <-"DXXLWrapperForUntiyDebugDraw.CheckIfDrawingIsCurrentlySkipped" uses the here applied rotation already in it's fallback
if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; }
float sum_ofAllNonNegativeSegments = Get_sum_ofAllNonNegativeSegments();
bool sum_ofAllNonNegativeSegments_isZero = UtilitiesDXXL_Math.ApproximatelyZero(sum_ofAllNonNegativeSegments);
TryDrawNotificationForEmptyChart(sum_ofAllNonNegativeSegments_isZero, durationInSec, hiddenByNearerObjects);
bool mentionOthersSection_inRightTextColumn = RecalcSegmentsDrawProperties(sum_ofAllNonNegativeSegments);
if (sum_ofAllNonNegativeSegments_isZero == false) { SortSegmentsForDrawing(); }
float vertOffset_ofNextTextBlock_fromRightColumnsTop = DrawSegments(mentionOthersSection_inRightTextColumn, durationInSec, hiddenByNearerObjects);
float size_ofPieCircleRadius = 0.5f * size_ofPieCircleDiameter;
float distance_circleCenter_toLeftBorder = size_ofPieCircleRadius + size_ofPieCircleRadius * 1.0f * relSize_ofSegmentsNameTexts;
float distance_circleCenter_toRightBorder = size_ofPieCircleRadius + size_ofPieCircleRadius * 2.25f * relSize_ofSegmentsNameTexts;
float distance_circleCenter_toLowEndOfTitleTexts = size_ofPieCircleRadius + size_ofPieCircleRadius * 0.65f * relSize_ofSegmentsNameTexts;
float vertDistance_fromCircleCenter_toLowCenterPosOfNextTitleText = distance_circleCenter_toLowEndOfTitleTexts;
mostRecent_vertDistance_fromCircleCenter_toUpperBounderySquare = TryDrawChartTitles(distance_circleCenter_toLeftBorder, distance_circleCenter_toRightBorder, vertDistance_fromCircleCenter_toLowCenterPosOfNextTitleText, durationInSec, hiddenByNearerObjects);
DrawBoundarySquare(vertOffset_ofNextTextBlock_fromRightColumnsTop, distance_circleCenter_toLowEndOfTitleTexts, distance_circleCenter_toLeftBorder, distance_circleCenter_toRightBorder, size_ofPieCircleRadius, durationInSec, hiddenByNearerObjects);
DXXLWrapperForUntiysBuildInDrawLines.currentlyDrawingPieChart = null;
}
public void DrawScreenspace(bool chartSize_isDefinedRelTo_cameraWidth_notCameraHeight = false, float durationInSec = 0.0f)
{
if (UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "PieChartDrawing.DrawScreenspace") == false) { return; }
DrawScreenspace(automaticallyFoundCamera, chartSize_isDefinedRelTo_cameraWidth_notCameraHeight, durationInSec);
}
public void DrawScreenspace(Camera targetCamera, bool chartSize_isDefinedRelTo_cameraWidth_notCameraHeight = false, float durationInSec = 0.0f)
{
if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; }
if (UtilitiesDXXL_Log.ErrorLogForNullUnityObjects(targetCamera, "targetCamera")) { return; }
if (UtilitiesDXXL_Screenspace.CheckIfViewportIsTooSmall(targetCamera)) { return; }
if (DrawXXL_LinesManager.instance.noteAllScreenspaceDrawsToSheduler_insteadOfImmediatelyDrawingThem)
{
DrawXXL_LinesManager.instance.listOfSheduled_DrawScreenspacePieChart.Add(new DrawScreenspacePieChart(targetCamera, chartSize_isDefinedRelTo_cameraWidth_notCameraHeight , durationInSec, this));
return;
}
Vector3 chartPosition_beforeScreenspaceDrawing = Position_worldspace;
Quaternion fixedChartRotation_beforeScreenspaceDrawing = fixedRotation;
float size_ofPieCircleDiameter_beforeScreenspaceDrawing = size_ofPieCircleDiameter;
RotationSource rotationSource_beforeScreenspaceDrawing = rotationSource;
autoFlipAllText_toFitObsererCamera = false;
try
{
Position_worldspace = UtilitiesDXXL_Screenspace.ViewportSpacePos_to_WorldPosOnDrawPlane(targetCamera, position_inCamViewportspace, false);
fixedRotation = targetCamera.transform.rotation;
rotationSource = RotationSource.userDefinedFixedRotation;
if (chartSize_isDefinedRelTo_cameraWidth_notCameraHeight)
{
size_ofPieCircleDiameter = UtilitiesDXXL_Screenspace.HorizExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, InternalDXXL_BoundsCamViewportSpace.viewportCenter, true, size_ofPieCircleDiameter_relToCamViewport);
}
else
{
size_ofPieCircleDiameter = UtilitiesDXXL_Screenspace.VertExtentInsideViewportSpace_to_WorldSpaceExtentOnDrawPlane(targetCamera, InternalDXXL_BoundsCamViewportSpace.viewportCenter, true, size_ofPieCircleDiameter_relToCamViewport);
}
Draw(durationInSec, false);
}
catch { }
Position_worldspace = chartPosition_beforeScreenspaceDrawing;
fixedRotation = fixedChartRotation_beforeScreenspaceDrawing;
size_ofPieCircleDiameter = size_ofPieCircleDiameter_beforeScreenspaceDrawing;
rotationSource = rotationSource_beforeScreenspaceDrawing;
autoFlipAllText_toFitObsererCamera = true;
}
void ApplyInternalRotation()
{
Vector3 observerCamForward_normalized;
Vector3 observerCamUp_normalized;
Vector3 observerCamRight_normalized;
Vector3 cam_to_lineCenter;
switch (rotationSource)
{
case RotationSource.screen:
UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter, Position_worldspace, Vector3.zero, null);
internalRotation = Quaternion.LookRotation(observerCamForward_normalized, observerCamUp_normalized);
break;
case RotationSource.screen_butVerticalInWorldSpace:
UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter, Position_worldspace, Vector3.zero, null);
UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.GetUpAndTextDir_withoutCallerSpecifiedPreference_independentFromTooShortLineDir_alignedVertical(out Vector3 chartUp_normalized, out Vector3 chartRight_normalized, observerCamForward_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter);
Vector3 chartForward_normalized = Vector3.Cross(chartRight_normalized, chartUp_normalized);
internalRotation = Quaternion.LookRotation(chartForward_normalized, chartUp_normalized);
break;
case RotationSource.userDefinedFixedRotation:
internalRotation = fixedRotation;
break;
default:
internalRotation = fixedRotation;
Debug.LogError("rotationSource of '" + rotationSource + "' not implemented.");
break;
}
right_normalized = internalRotation * Vector3.right;
up_normalized = internalRotation * Vector3.up;
forward_normalized = internalRotation * Vector3.forward;
}
float Get_sum_ofAllNonNegativeSegments()
{
float sum_ofAllNonNegativeSegments = 0.0f;
for (int i_segment = 0; i_segment < segments_inCreationOrder.Count; i_segment++)
{
if (segments_inCreationOrder[i_segment].ValueAsFloat > 0.0f)
{
sum_ofAllNonNegativeSegments = sum_ofAllNonNegativeSegments + segments_inCreationOrder[i_segment].ValueAsFloat;
}
}
return sum_ofAllNonNegativeSegments;
}
void TryDrawNotificationForEmptyChart(bool sum_ofAllNonNegativeSegments_isZero, float durationInSec, bool hiddenByNearerObjects)
{
if (sum_ofAllNonNegativeSegments_isZero)
{
float autoLineBreakWidth_ofNoNonZeroSegmentsText = 1.8f * size_ofPieCircleDiameter;
float size_ofNoNonZeroSegmentsText = 0.057f * size_ofPieCircleDiameter;
UtilitiesDXXL_Text.Write("<size=60><color=#adadadFF><icon=logMessage></color></size><br>This pie chart doesn't contain<br>any segment with a value bigger<br>than 0.<br> ", Position_worldspace, color, size_ofNoNonZeroSegmentsText, right_normalized, up_normalized, DrawText.TextAnchorDXXL.LowerCenter, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, autoLineBreakWidth_ofNoNonZeroSegmentsText, autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects, false, false, true);
}
}
bool RecalcSegmentsDrawProperties(float sum_ofAllNonNegativeSegments)
{
for (int i_segment = 0; i_segment < segments_inCreationOrder.Count; i_segment++)
{
segments_inCreationOrder[i_segment].CalcPercentage(sum_ofAllNonNegativeSegments);
}
int numberOfSegments_inCombinedOthersSection = 0;
int numberOfNonZeroSegments_inCombinedOthersSection = 0;
for (int i_segment = 0; i_segment < segments_inCreationOrder.Count; i_segment++)
{
if (segments_inCreationOrder[i_segment].isTooSmallToBeDrawn)
{
numberOfSegments_inCombinedOthersSection++;
if (segments_inCreationOrder[i_segment].ValueAsFloat > 0.0f)
{
numberOfNonZeroSegments_inCombinedOthersSection++;
}
}
}
combinedOthersSegment.SetValue(0.0f);
combinedOthersSegment.isTooSmallToBeDrawn = true;
bool mentionOthersSection_inRightTextColumn;
if (numberOfSegments_inCombinedOthersSection <= 1)
{
mentionOthersSection_inRightTextColumn = false;
for (int i_segment = 0; i_segment < segments_inCreationOrder.Count; i_segment++)
{
segments_inCreationOrder[i_segment].textInRightColumn_shouldBeInsideTheOthersSection = false;
if (segments_inCreationOrder[i_segment].angleDeg_insidePie > 0.0f)
{
segments_inCreationOrder[i_segment].isTooSmallToBeDrawn = false;
}
}
}
else
{
//-> "othersSection" contains at least two other segments
//-> (but all these contained segments may be 0)
for (int i_segment = 0; i_segment < segments_inCreationOrder.Count; i_segment++)
{
if (segments_inCreationOrder[i_segment].isTooSmallToBeDrawn)
{
if (segments_inCreationOrder[i_segment].ValueAsFloat > 0.0f)
{
combinedOthersSegment.AddValue(segments_inCreationOrder[i_segment].ValueAsFloat);
}
}
}
combinedOthersSegment.CalcPercentage(sum_ofAllNonNegativeSegments);
if (combinedOthersSegment.angleDeg_insidePie > 0.0f)
{
combinedOthersSegment.isTooSmallToBeDrawn = false; //-> this overwrites "percentageThreshold_belowWhichSegmentsGetCombinedInto_othersSection"
mentionOthersSection_inRightTextColumn = true;
}
else
{
if (mentionZeroSegmentsInLegend)
{
mentionOthersSection_inRightTextColumn = true;
}
else
{
mentionOthersSection_inRightTextColumn = false;
}
}
if (mentionZeroSegmentsInLegend)
{
combinedOthersSegment.name = "" + numberOfSegments_inCombinedOthersSection + " Others";
}
else
{
combinedOthersSegment.name = "" + numberOfNonZeroSegments_inCombinedOthersSection + " Others";
}
}
return mentionOthersSection_inRightTextColumn;
}
float DrawSegments(bool mentionOthersSection_inRightTextColumn, float durationInSec, bool hiddenByNearerObjects)
{
//-> the order of calling of the following functions matters, because
// 1) The elements are z-fighting. Later calls are drawn on top of earlier calls.
// 2) The earlier calls fill class members inside "PieChartSegment" that are used by the later calls.
Color color_ofLastDrawnSegment = TryDrawCircledLines(durationInSec, hiddenByNearerObjects);
TryDrawStraightSegmentBorderLines(color_ofLastDrawnSegment, durationInSec, hiddenByNearerObjects);
PrepareTextDrawing();
TryDrawTextsBesideSegments(durationInSec, hiddenByNearerObjects);
float vertOffset_ofNextTextBlock_fromRightColumnsTop = TryDrawTextsInRightColumn(mentionOthersSection_inRightTextColumn, durationInSec, hiddenByNearerObjects);
return vertOffset_ofNextTextBlock_fromRightColumnsTop;
}
Color TryDrawCircledLines(float durationInSec, bool hiddenByNearerObjects)
{
Color color_ofPrecedingSegment = default;
float startingAngleDegCCFromUp_ofCurrSegment = angleDegCCfromUp_whereMainSegmentStarts;
for (int i_segment = 0; i_segment < segments_orderedForDrawing.Count; i_segment++)
{
startingAngleDegCCFromUp_ofCurrSegment = segments_orderedForDrawing[i_segment].TryDrawCircledLines(startingAngleDegCCFromUp_ofCurrSegment, durationInSec, hiddenByNearerObjects);
if (segments_orderedForDrawing[i_segment].isTooSmallToBeDrawn == false) { color_ofPrecedingSegment = segments_orderedForDrawing[i_segment].color; }
}
combinedOthersSegment.TryDrawCircledLines(startingAngleDegCCFromUp_ofCurrSegment, durationInSec, hiddenByNearerObjects);
if (combinedOthersSegment.isTooSmallToBeDrawn == false) { color_ofPrecedingSegment = combinedOthersSegment.color; }
return color_ofPrecedingSegment;
}
void TryDrawStraightSegmentBorderLines(Color color_ofLastDrawnSegment, float durationInSec, bool hiddenByNearerObjects)
{
Color color_ofPrecedingSegment = color_ofLastDrawnSegment;
for (int i_segment = 0; i_segment < segments_orderedForDrawing.Count; i_segment++)
{
segments_orderedForDrawing[i_segment].TryDrawStraightSegmentBorderLine(color_ofPrecedingSegment, durationInSec, hiddenByNearerObjects);
if (segments_orderedForDrawing[i_segment].isTooSmallToBeDrawn == false) { color_ofPrecedingSegment = segments_orderedForDrawing[i_segment].color; }
}
combinedOthersSegment.TryDrawStraightSegmentBorderLine(color_ofPrecedingSegment, durationInSec, hiddenByNearerObjects);
}
void PrepareTextDrawing()
{
for (int i_segment = 0; i_segment < segments_orderedForDrawing.Count; i_segment++)
{
segments_orderedForDrawing[i_segment].PrepareTextDrawing();
}
combinedOthersSegment.PrepareTextDrawing();
}
void TryDrawTextsBesideSegments(float durationInSec, bool hiddenByNearerObjects)
{
angleSpans_thatAreAlreadyCoveredWithText.Clear();
for (int i_segment = 0; i_segment < segments_orderedWithDecreasingSize.Count; i_segment++)
{
if (segments_orderedWithDecreasingSize[i_segment].isTooSmallToBeDrawn)
{
segments_orderedWithDecreasingSize[i_segment].ReportThat_textShouldBeDrawnIntoRightColumn_becauseSpaceAtChartWasTooSmall();
}
else
{
segments_orderedWithDecreasingSize[i_segment].TryDrawTextBesideSegment(durationInSec, hiddenByNearerObjects);
}
}
if (combinedOthersSegment.ValueAsFloat > 0.0f)
{
combinedOthersSegment.TryDrawTextBesideSegment(durationInSec, hiddenByNearerObjects);
}
else
{
combinedOthersSegment.ReportThat_textShouldBeDrawnIntoRightColumn_becauseSpaceAtChartWasTooSmall();
}
}
float TryDrawTextsInRightColumn(bool mentionOthersSection_inRightTextColumn, float durationInSec, bool hiddenByNearerObjects)
{
float vertOffset_ofNextTextBlock_fromRightColumnsTop = 0.0f;
for (int i_segment = 0; i_segment < segments_orderedForDrawing.Count; i_segment++)
{
if (mentionOthersSection_inRightTextColumn == false) { segments_orderedForDrawing[i_segment].textInRightColumn_shouldBeInsideTheOthersSection = false; } //-> this is for the case where the othersSection would contain only 1 segment, and therefore this segment gets drawn instead of the otherSection. Without this it would not appear in the right column
vertOffset_ofNextTextBlock_fromRightColumnsTop = segments_orderedForDrawing[i_segment].TryDrawTextInRightColumnOutsideOthersSection(false, vertOffset_ofNextTextBlock_fromRightColumnsTop, durationInSec, hiddenByNearerObjects);
}
if (mentionOthersSection_inRightTextColumn)
{
//-> others section contains at least two other segments
//-> at least one contained segment ist non-zero OR "mentionZeroSegmentsInLegend" is activated
vertOffset_ofNextTextBlock_fromRightColumnsTop = combinedOthersSegment.TryDrawTextInRightColumnOutsideOthersSection(true, vertOffset_ofNextTextBlock_fromRightColumnsTop, durationInSec, hiddenByNearerObjects);
for (int i_segment = 0; i_segment < segments_orderedForDrawing.Count; i_segment++)
{
vertOffset_ofNextTextBlock_fromRightColumnsTop = segments_orderedForDrawing[i_segment].TryDrawTextInRightColumnInsideOthersSection(vertOffset_ofNextTextBlock_fromRightColumnsTop, combinedOthersSegment.color, durationInSec, hiddenByNearerObjects);
}
}
return vertOffset_ofNextTextBlock_fromRightColumnsTop;
}
float TryDrawChartTitles(float distance_circleCenter_toLeftBorder, float distance_circleCenter_toRightBorder, float vertDistance_fromCircleCenter_toLowCenterPosOfNextTitleText, float durationInSec, bool hiddenByNearerObjects)
{
float widthOfBoundarySquare = distance_circleCenter_toLeftBorder + distance_circleCenter_toRightBorder;
float halfWidthOfBoundarySquare = 0.5f * widthOfBoundarySquare;
float autoLineBreakWidth = 0.9f * widthOfBoundarySquare;
if (subTitle != null && subTitle != "")
{
float size_ofSubTitleText = 0.06f * size_ofPieCircleDiameter;
Vector3 lowCenterPos_ofNextTitleText = Position_worldspace + up_normalized * vertDistance_fromCircleCenter_toLowCenterPosOfNextTitleText + right_normalized * ((-distance_circleCenter_toLeftBorder) + halfWidthOfBoundarySquare);
UtilitiesDXXL_Text.Write(subTitle, lowCenterPos_ofNextTitleText, color, size_ofSubTitleText, right_normalized, up_normalized, DrawText.TextAnchorDXXL.LowerCenter, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, autoLineBreakWidth, autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects, false, false, true);
vertDistance_fromCircleCenter_toLowCenterPosOfNextTitleText = vertDistance_fromCircleCenter_toLowCenterPosOfNextTitleText + (DrawText.parsedTextSpecs.height_wholeTextBlock + size_ofSubTitleText);
}
if (title != null && title != "")
{
float size_ofTitleText = 0.18f * size_ofPieCircleDiameter;
Vector3 lowCenterPos_ofNextTitleText = Position_worldspace + up_normalized * vertDistance_fromCircleCenter_toLowCenterPosOfNextTitleText + right_normalized * ((-distance_circleCenter_toLeftBorder) + halfWidthOfBoundarySquare);
UtilitiesDXXL_Text.Write(title_insideMarkup, lowCenterPos_ofNextTitleText, color, size_ofTitleText, right_normalized, up_normalized, DrawText.TextAnchorDXXL.LowerCenter, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, autoLineBreakWidth, autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects, false, false, true);
vertDistance_fromCircleCenter_toLowCenterPosOfNextTitleText = vertDistance_fromCircleCenter_toLowCenterPosOfNextTitleText + DrawText.parsedTextSpecs.height_wholeTextBlock;
}
return vertDistance_fromCircleCenter_toLowCenterPosOfNextTitleText;
}
void DrawBoundarySquare(float vertOffset_ofNextTextBlock_fromRightColumnsTop, float distance_circleCenter_toLowEndOfTitleTexts, float distance_circleCenter_toLeftBorder, float distance_circleCenter_toRightBorder, float size_ofPieCircleRadius, float durationInSec, bool hiddenByNearerObjects)
{
float offset_fromCircleCenter_toLowestPosOfRightColumn = Get_vertOffset_fromCircleCenter_toTopRightPosOfRightColumn() + vertOffset_ofNextTextBlock_fromRightColumnsTop;
float offset_fromCircleCenter_toLowestPosOfRightColumnInclOffset = offset_fromCircleCenter_toLowestPosOfRightColumn - size_ofPieCircleRadius * 0.25f * relSize_ofSegmentsNameTexts;
float minOffset_fromCircleCenter_toLowerBounderySquare = (-distance_circleCenter_toLowEndOfTitleTexts); //-> naming confusion: It contains "min", but the "min" would only be correct if the value would be an abs/positive value. Since this offset is always negative, it is actually the "max" value, but this would be an unintuitive name as well.
Vector3 circleCenter_to_upperBorderOfBoundarySquare = up_normalized * mostRecent_vertDistance_fromCircleCenter_toUpperBounderySquare;
Vector3 circleCenter_to_lowerBorderOfBoundarySquare = up_normalized * Mathf.Min(minOffset_fromCircleCenter_toLowerBounderySquare, offset_fromCircleCenter_toLowestPosOfRightColumnInclOffset);//-> since the searched value is always a negative one this is actually looking for the "max-negative".
Vector3 circleCenter_to_leftBorderOfBoundarySquare = right_normalized * (-distance_circleCenter_toLeftBorder);
Vector3 circleCenter_to_rightBorderOfBoundarySquare = right_normalized * distance_circleCenter_toRightBorder;
Vector3 topLeftCorner_ofBoundarySquare = Position_worldspace + circleCenter_to_upperBorderOfBoundarySquare + circleCenter_to_leftBorderOfBoundarySquare;
Vector3 topRightCorner_ofBoundarySquare = Position_worldspace + circleCenter_to_upperBorderOfBoundarySquare + circleCenter_to_rightBorderOfBoundarySquare;
Vector3 lowLeftCorner_ofBoundarySquare = Position_worldspace + circleCenter_to_lowerBorderOfBoundarySquare + circleCenter_to_leftBorderOfBoundarySquare;
Vector3 lowRightCorner_ofBoundarySquare = Position_worldspace + circleCenter_to_lowerBorderOfBoundarySquare + circleCenter_to_rightBorderOfBoundarySquare;
Line_fadeableAnimSpeed.InternalDraw(topLeftCorner_ofBoundarySquare, topRightCorner_ofBoundarySquare, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false);
Line_fadeableAnimSpeed.InternalDraw(topRightCorner_ofBoundarySquare, lowRightCorner_ofBoundarySquare, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false);
Line_fadeableAnimSpeed.InternalDraw(lowRightCorner_ofBoundarySquare, lowLeftCorner_ofBoundarySquare, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false);
Line_fadeableAnimSpeed.InternalDraw(lowLeftCorner_ofBoundarySquare, topLeftCorner_ofBoundarySquare, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false);
}
public void AddValue(string segmentName, float addedValue)
{
if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls
{
GetSegment(segmentName, true).AddValue(addedValue);
}
}
public void AddValue(string segmentName, int addedValue)
{
if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls
{
GetSegment(segmentName, true).AddValue(addedValue);
}
}
public void AddValueToAllSegments(float addedValue)
{
if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls
{
for (int i = 0; i < segments_inCreationOrder.Count; i++)
{
segments_inCreationOrder[i].AddValue(addedValue);
}
}
}
public void AddValueToAllSegments(int addedValue)
{
if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls
{
for (int i = 0; i < segments_inCreationOrder.Count; i++)
{
segments_inCreationOrder[i].AddValue(addedValue);
}
}
}
public void IncrementValue(string segmentName)
{
GetSegment(segmentName, true).AddValue(1);
}
public void IncrementValuesOfAllSegments()
{
for (int i = 0; i < segments_inCreationOrder.Count; i++)
{
segments_inCreationOrder[i].AddValue(1);
}
}
public void DecrementValue(string segmentName)
{
GetSegment(segmentName, true).AddValue(-1);
}
public void DecrementValuesOfAllSegments()
{
for (int i = 0; i < segments_inCreationOrder.Count; i++)
{
segments_inCreationOrder[i].AddValue(-1);
}
}
public void SetValue(string segmentName, float newValue)
{
GetSegment(segmentName, true).SetValue(newValue);
}
public void SetValueOfAllSegments(float newValue)
{
for (int i = 0; i < segments_inCreationOrder.Count; i++)
{
segments_inCreationOrder[i].SetValue(newValue);
}
}
public void SetValue(string segmentName, int newValue)
{
GetSegment(segmentName, true).SetValue(newValue);
}
public void SetValueOfAllSegments(int newValue)
{
for (int i = 0; i < segments_inCreationOrder.Count; i++)
{
segments_inCreationOrder[i].SetValue(newValue);
}
}
public void AddValues_eachIndexIsASegment(List<float> valuesToAdd)
{
if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls
{
for (int i = 0; i < valuesToAdd.Count; i++)
{
GetSegment("i=" + i, true).AddValue(valuesToAdd[i]);
}
}
}
public void AddValues_eachIndexIsASegment(float[] valuesToAdd)
{
if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls
{
for (int i = 0; i < valuesToAdd.Length; i++)
{
GetSegment("i=" + i, true).AddValue(valuesToAdd[i]);
}
}
}
public void AddValues_eachIndexIsASegment(List<int> valuesToAdd)
{
if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls
{
for (int i = 0; i < valuesToAdd.Count; i++)
{
GetSegment("i=" + i, true).AddValue(valuesToAdd[i]);
}
}
}
public void AddValues_eachIndexIsASegment(int[] valuesToAdd)
{
if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls
{
for (int i = 0; i < valuesToAdd.Length; i++)
{
GetSegment("i=" + i, true).AddValue(valuesToAdd[i]);
}
}
}
public void IncrementValues_eachIndexIsASegment(List<bool> incrementedListSlots)
{
for (int i = 0; i < incrementedListSlots.Count; i++)
{
if (incrementedListSlots[i] == true)
{
IncrementValue("i=" + i);
}
}
}
public void IncrementValues_eachIndexIsASegment(bool[] incrementedArraySlots)
{
for (int i = 0; i < incrementedArraySlots.Length; i++)
{
if (incrementedArraySlots[i] == true)
{
IncrementValue("i=" + i);
}
}
}
public void DecrementValues_eachIndexIsASegment(List<bool> decrementedListSlots)
{
for (int i = 0; i < decrementedListSlots.Count; i++)
{
if (decrementedListSlots[i] == true)
{
DecrementValue("i=" + i);
}
}
}
public void DecrementValues_eachIndexIsASegment(bool[] decrementedArraySlots)
{
for (int i = 0; i < decrementedArraySlots.Length; i++)
{
if (decrementedArraySlots[i] == true)
{
DecrementValue("i=" + i);
}
}
}
public void SetValues_eachIndexIsASegment(List<float> valuesToSet)
{
for (int i = 0; i < valuesToSet.Count; i++)
{
GetSegment("i=" + i, true).SetValue(valuesToSet[i]);
}
}
public void SetValues_eachIndexIsASegment(float[] valuesToSet)
{
for (int i = 0; i < valuesToSet.Length; i++)
{
GetSegment("i=" + i, true).SetValue(valuesToSet[i]);
}
}
public void SetValues_eachIndexIsASegment(List<int> valuesToSet)
{
for (int i = 0; i < valuesToSet.Count; i++)
{
GetSegment("i=" + i, true).SetValue(valuesToSet[i]);
}
}
public void SetValues_eachIndexIsASegment(int[] valuesToSet)
{
for (int i = 0; i < valuesToSet.Length; i++)
{
GetSegment("i=" + i, true).SetValue(valuesToSet[i]);
}
}
public void Clear()
{
segments_inCreationOrder.Clear();
segments_orderedForDrawing.Clear();
segments_orderedWithDecreasingSize.Clear();
}
public PieChartSegment GetSegment(string segmentName, bool createSegmentIfItDoesntExist)
{
if (segmentName == null || segmentName == "")
{
Debug.LogError("'GetSegment()' failed, because the requested 'segmentName' is null or empty.");
return null;
}
for (int i = 0; i < segments_inCreationOrder.Count; i++)
{
if (segments_inCreationOrder[i].name != null)
{
if (segments_inCreationOrder[i].name == segmentName)
{
return segments_inCreationOrder[i];
}
}
}
//A segment with this name doesn't exist yet:
if (createSegmentIfItDoesntExist)
{
PieChartSegment newlyCreatedPieChartSegment = new PieChartSegment(segmentName, this, segments_inCreationOrder.Count);
segments_inCreationOrder.Add(newlyCreatedPieChartSegment);
segments_orderedForDrawing.Add(segments_inCreationOrder[segments_inCreationOrder.Count - 1]);
segments_orderedWithDecreasingSize.Add(segments_inCreationOrder[segments_inCreationOrder.Count - 1]);
TryReassignRainbowColorsToAllSegments();
return segments_inCreationOrder[segments_inCreationOrder.Count - 1];
}
else
{
return null;
}
}
public bool OrderingIsClockwise()
{
return ((segmentSorting == SegmentSorting.creationOrder_clockwise) || (segmentSorting == SegmentSorting.decreasingSize_clockwise));
}
void SortSegmentsForDrawing()
{
segments_orderedWithDecreasingSize.Sort(BiggerValueLeadsToLowerIndex);
switch (segmentSorting)
{
case SegmentSorting.decreasingSize_clockwise:
segments_orderedForDrawing.Sort(BiggerValueLeadsToLowerIndex);
break;
case SegmentSorting.decreasingSize_counterClockwise:
segments_orderedForDrawing.Sort(BiggerValueLeadsToLowerIndex);
break;
case SegmentSorting.creationOrder_clockwise:
Fill_segments_fromListInCreationOrder_toListOrderedForDrawing();
break;
case SegmentSorting.creationOrder_counterClockwise:
Fill_segments_fromListInCreationOrder_toListOrderedForDrawing();
break;
default:
segments_orderedForDrawing.Sort(BiggerValueLeadsToLowerIndex);
Debug.LogError("segmentSorting of '" + segmentSorting + "' not implemented.");
break;
}
}
int BiggerValueLeadsToLowerIndex(PieChartSegment segment1, PieChartSegment segment2)
{
if (UtilitiesDXXL_Math.CheckIf_twoFloatsAreApproximatelyEqual(segment1.ValueAsFloat, segment2.ValueAsFloat))
{
//-> this prevents ongoing flickering change of the order of (zero) segments inside the right column
if (segment1.i_ofThisSegment_insideCreationOrderedList < segment2.i_ofThisSegment_insideCreationOrderedList)
{
return (-1);
}
else
{
return (1);
}
}
else
{
if (segment1.ValueAsFloat > segment2.ValueAsFloat)
{
return (-1);
}
else
{
return (1);
}
}
}
void Fill_segments_fromListInCreationOrder_toListOrderedForDrawing()
{
for (int i = 0; i < segments_inCreationOrder.Count; i++)
{
segments_orderedForDrawing[i] = segments_inCreationOrder[i];
}
}
public bool CheckIfAngleForTextIsAlreadyCovered(float startAngleDegCCFromUp_ofText, float endAngleDegCCFromUp_ofText)
{
for (int i = 0; i < angleSpans_thatAreAlreadyCoveredWithText.Count; i++)
{
if (angleSpans_thatAreAlreadyCoveredWithText[i].DoesIntersect(startAngleDegCCFromUp_ofText, endAngleDegCCFromUp_ofText))
{
return true;
}
}
return false;
}
public void MarkAngleSpanAsCoveredWithText(float startAngleDegCCFromUp_ofText, float endAngleDegCCFromUp_ofText)
{
InternalDXXL_PieAngleSpan reservedAngleSpan = new InternalDXXL_PieAngleSpan();
reservedAngleSpan.startAngleDegCCFromUp = startAngleDegCCFromUp_ofText;
reservedAngleSpan.endAngleDegCCFromUp = endAngleDegCCFromUp_ofText;
angleSpans_thatAreAlreadyCoveredWithText.Add(reservedAngleSpan);
if (startAngleDegCCFromUp_ofText < 0.0f)
{
InternalDXXL_PieAngleSpan reservedAngleSpan_copy1 = new InternalDXXL_PieAngleSpan();
reservedAngleSpan_copy1.startAngleDegCCFromUp = startAngleDegCCFromUp_ofText + 360.0f;
reservedAngleSpan_copy1.endAngleDegCCFromUp = endAngleDegCCFromUp_ofText + 360.0f;
angleSpans_thatAreAlreadyCoveredWithText.Add(reservedAngleSpan_copy1);
}
if (endAngleDegCCFromUp_ofText > 360.0f)
{
InternalDXXL_PieAngleSpan reservedAngleSpan_copy2 = new InternalDXXL_PieAngleSpan();
reservedAngleSpan_copy2.startAngleDegCCFromUp = startAngleDegCCFromUp_ofText - 360.0f;
reservedAngleSpan_copy2.endAngleDegCCFromUp = endAngleDegCCFromUp_ofText - 360.0f;
angleSpans_thatAreAlreadyCoveredWithText.Add(reservedAngleSpan_copy2);
}
}
public float Get_vertOffset_fromCircleCenter_toTopRightPosOfRightColumn()
{
float size_ofPieCircleRadius = 0.5f * size_ofPieCircleDiameter;
return (size_ofPieCircleRadius + size_ofPieCircleRadius * 0.4f * relSize_ofSegmentsNameTexts);
}
int numberOfSegments_inMomentOfLastAutomaticRainbowColorReassignment = 0;
int colorSeedFactor = 11; //if this is set to 1, then the segment colors are one continuous color spectrum pass from the first created segment to the last created segment. This may help to indicate the order in which the segments were created, but in the not-so-seldom-case where the segments size is also ordered (like "first creeated segment is biggest/smallest), then it gets harder to distinguish the color of the segments and associate them with the corresponding text display, since neighboring colors get more and more similar. Setting this "colorSeedFactor" value to something else than 1 "scatters" the color distribution, so that chances are higher that neighboring segments have a clearly different color.
void TryReassignRainbowColorsToAllSegments()
{
for (int i_segment = 0; i_segment < segments_inCreationOrder.Count; i_segment++)
{
bool isTheNewlyCreatedSegment = (i_segment == (segments_inCreationOrder.Count - 1));
if (isTheNewlyCreatedSegment)
{
segments_inCreationOrder[i_segment].color = SeededColorGenerator.GetRainbowColor(i_segment * colorSeedFactor, 1.0f, segments_inCreationOrder.Count, luminanceOfSegmentColors);
}
else
{
Color expectedColorOfSegment_beforeCurrReassignment_ifColorWasAutogenerated = SeededColorGenerator.GetRainbowColor(i_segment * colorSeedFactor, 1.0f, numberOfSegments_inMomentOfLastAutomaticRainbowColorReassignment, luminanceOfSegmentColors);
bool colorWasManuallySetByUser = (UtilitiesDXXL_Colors.IsApproxSameColor(segments_inCreationOrder[i_segment].color, expectedColorOfSegment_beforeCurrReassignment_ifColorWasAutogenerated) == false);
if (colorWasManuallySetByUser == false)
{
segments_inCreationOrder[i_segment].color = SeededColorGenerator.GetRainbowColor(i_segment * colorSeedFactor, 1.0f, segments_inCreationOrder.Count, luminanceOfSegmentColors);
}
}
}
numberOfSegments_inMomentOfLastAutomaticRainbowColorReassignment = segments_inCreationOrder.Count;
}
void ReassignLuminanceToSegmentColors(float oldLuminance, float newLuminance)
{
Color colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated;
Color colorToAssign_ifAutogenerated;
for (int i_segment = 0; i_segment < segments_inCreationOrder.Count; i_segment++)
{
colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.GetRainbowColor(i_segment * colorSeedFactor, 1.0f, numberOfSegments_inMomentOfLastAutomaticRainbowColorReassignment, oldLuminance);
colorToAssign_ifAutogenerated = SeededColorGenerator.GetRainbowColor(i_segment * colorSeedFactor, 1.0f, numberOfSegments_inMomentOfLastAutomaticRainbowColorReassignment, newLuminance);
ReassignLuminanceToSegmentColor(segments_inCreationOrder[i_segment], colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance);
}
colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated = SeededColorGenerator.ForceApproxLuminance(Color.gray, oldLuminance);
colorToAssign_ifAutogenerated = SeededColorGenerator.ForceApproxLuminance(Color.gray, newLuminance);
ReassignLuminanceToSegmentColor(combinedOthersSegment, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, colorToAssign_ifAutogenerated, newLuminance);
}
void ReassignLuminanceToSegmentColor(PieChartSegment concernedSegment, Color colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated, Color colorToAssign_ifAutogenerated, float newLuminance)
{
bool colorWasAutogenerated = UtilitiesDXXL_Colors.IsApproxSameColor(concernedSegment.color, colorThisLineShouldHaveAtPrevLuminance_beforeCurrentColorReassignment_ifAutogenerated);
if (colorWasAutogenerated)
{
concernedSegment.color = colorToAssign_ifAutogenerated;
}
else
{
//color has been manually set by user:
if (UtilitiesDXXL_Math.ApproximatelyZero(concernedSegment.color.r) && UtilitiesDXXL_Math.ApproximatelyZero(concernedSegment.color.g) && UtilitiesDXXL_Math.ApproximatelyZero(concernedSegment.color.b))
{
//-> black colors cannot be forced with luminance, therefore: slight lift, to make it grey, which can be forced:
concernedSegment.color = new Color(0.01f, 0.01f, 0.01f, concernedSegment.color.a);
}
concernedSegment.color = SeededColorGenerator.ForceApproxLuminance(concernedSegment.color, newLuminance);
}
}
public void DrawWarningForMaxLinesPerFrame()
{
string warningText = "<color=#e2aa00FF><size=33><icon=warning></size></color><br><color=red>Max lines exceeded<br>(see log)</color><br> ";
float size_ofMaxLinesText = 0.09f * size_ofPieCircleDiameter;
UtilitiesDXXL_Text.WriteFramed(warningText, Position_worldspace, color, size_ofMaxLinesText, internalRotation, DrawText.TextAnchorDXXL.LowerCenter, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, autoFlipAllText_toFitObsererCamera, 0.0f, false);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 78be5f93f1552be4db2592d6cdba0cb3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,409 @@
namespace DrawXXL
{
using UnityEngine;
public class PieChartSegment
{
private float valueAsFloat;
public float ValueAsFloat
{
get { return valueAsFloat; }
set { Debug.LogError("'" + name + ".ValueAsFloat' cannot be set directly. Use 'pieChart.SetValue(" + name + " , valueToSet)' instead"); }
}
int valueAsInt;
float percentage_0to1;
public string name;
public Color color;
bool hasAtLeastBeenFilledOnceWithFloatInsteadOfInt = false;
PieChartDrawing chart_thisSegmentIsPartOf;
public bool isTooSmallToBeDrawn;
public float angleDeg_insidePie;
public int i_ofThisSegment_insideCreationOrderedList;
float radius_ofPieCircle;
float startingAngleDegCCFromUp;
float turnAngleDegCC;
Vector3 center_to_startPosOfThinOuterBorderLine;
string drawnText;
bool textShouldBeDrawnIntoRightColumn_becauseSpaceAtChartWasTooSmall;
public bool textInRightColumn_shouldBeInsideTheOthersSection;
float startAngleDegCCFromUp_ofTextBlock;
float endAngleDegCCFromUp_ofTextBlock;
Vector3 positionOfText;
float sizeOfText;
DrawText.TextAnchorDXXL textAnchor;
public PieChartSegment(string name, PieChartDrawing parentChart, int i_ofThisSegment_insideCreationOrderedList)
{
this.name = name;
hasAtLeastBeenFilledOnceWithFloatInsteadOfInt = false;
chart_thisSegmentIsPartOf = parentChart;
this.i_ofThisSegment_insideCreationOrderedList = i_ofThisSegment_insideCreationOrderedList;
}
public void AddValue(float addedValue)
{
if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls
{
if (UtilitiesDXXL_Math.FloatIsValid(addedValue))
{
hasAtLeastBeenFilledOnceWithFloatInsteadOfInt = true;
if (chart_thisSegmentIsPartOf.trackNegativeValues == false) { valueAsFloat = Mathf.Max(valueAsFloat, 0.0f); }
valueAsFloat = valueAsFloat + addedValue;
if (chart_thisSegmentIsPartOf.trackNegativeValues == false) { valueAsFloat = Mathf.Max(valueAsFloat, 0.0f); }
valueAsInt = Mathf.RoundToInt(valueAsFloat);
}
else
{
Debug.LogError("Add value to pie chart segment '" + name + "' failed, because added value is " + addedValue);
}
}
}
public void AddValue(int addedValue)
{
if (DrawBasics.usedUnityLineDrawingMethod != DrawBasics.UsedUnityLineDrawingMethod.disabled) //-> preventing memory leaks in builds if someone forgot to remove is "AddValue()" calls
{
if (hasAtLeastBeenFilledOnceWithFloatInsteadOfInt)
{
AddValue((float)addedValue);
}
else
{
if (chart_thisSegmentIsPartOf.trackNegativeValues == false) { valueAsInt = Mathf.Max(valueAsInt, 0); }
valueAsInt = valueAsInt + addedValue;
if (chart_thisSegmentIsPartOf.trackNegativeValues == false) { valueAsInt = Mathf.Max(valueAsInt, 0); }
valueAsFloat = (float)valueAsInt;
}
}
}
public void SetValue(float newValue)
{
if (UtilitiesDXXL_Math.FloatIsValid(newValue))
{
hasAtLeastBeenFilledOnceWithFloatInsteadOfInt = true;
valueAsFloat = newValue;
if (chart_thisSegmentIsPartOf.trackNegativeValues == false) { valueAsFloat = Mathf.Max(valueAsFloat, 0.0f); }
valueAsInt = Mathf.RoundToInt(newValue);
}
else
{
Debug.LogError("Set value of pie chart segment '" + name + "' failed, because new value is " + newValue);
}
}
public void SetValue(int newValue)
{
hasAtLeastBeenFilledOnceWithFloatInsteadOfInt = false;
valueAsInt = newValue;
if (chart_thisSegmentIsPartOf.trackNegativeValues == false) { valueAsInt = Mathf.Max(valueAsInt, 0); }
valueAsFloat = (float)newValue;
}
public void CalcPercentage(float sum_ofAllNonNegativeSegments)
{
if (UtilitiesDXXL_Math.ApproximatelyZero(sum_ofAllNonNegativeSegments))
{
percentage_0to1 = 0.0f;
}
else
{
percentage_0to1 = valueAsFloat / sum_ofAllNonNegativeSegments;
}
isTooSmallToBeDrawn = ((100.0f * percentage_0to1) < chart_thisSegmentIsPartOf.PercentageThreshold_belowWhichSegmentsGetCombinedInto_othersSection);
angleDeg_insidePie = 360.0f * percentage_0to1;
}
public float TryDrawCircledLines(float startingAngleDegCCFromUp, float durationInSec, bool hiddenByNearerObjects)
{
this.startingAngleDegCCFromUp = startingAngleDegCCFromUp;
radius_ofPieCircle = 0.5f * chart_thisSegmentIsPartOf.Size_ofPieCircleDiameter;
if (isTooSmallToBeDrawn == false)
{
float radius_ofBroadFillLine = radius_ofPieCircle * 0.55f;
float width_ofBroadFillLine = radius_ofPieCircle * 0.9f;
Quaternion rotation_fromPieUp_to_segmentStart = Quaternion.AngleAxis(startingAngleDegCCFromUp, chart_thisSegmentIsPartOf.Forward_normalized);
Vector3 center_to_startPosOfBroadLine_normalized = rotation_fromPieUp_to_segmentStart * chart_thisSegmentIsPartOf.Up_normalized;
Vector3 center_to_startPosOfBroadLine = center_to_startPosOfBroadLine_normalized * radius_ofBroadFillLine;
Vector3 startPosOfBroadLine = chart_thisSegmentIsPartOf.Position_worldspace + center_to_startPosOfBroadLine;
turnAngleDegCC = chart_thisSegmentIsPartOf.OrderingIsClockwise() ? (-angleDeg_insidePie) : angleDeg_insidePie;
DrawBasics.LineCircled(startPosOfBroadLine, chart_thisSegmentIsPartOf.Position_worldspace, chart_thisSegmentIsPartOf.Forward_normalized, turnAngleDegCC, color, width_ofBroadFillLine, null, false, true, 45.0f, DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, durationInSec, hiddenByNearerObjects);
center_to_startPosOfThinOuterBorderLine = center_to_startPosOfBroadLine_normalized * radius_ofPieCircle;
Vector3 startPosOfThinOuterBorderLine = chart_thisSegmentIsPartOf.Position_worldspace + center_to_startPosOfThinOuterBorderLine;
DrawBasics.LineCircled(startPosOfThinOuterBorderLine, chart_thisSegmentIsPartOf.Position_worldspace, chart_thisSegmentIsPartOf.Forward_normalized, turnAngleDegCC, color, 0.0f, null, false, true, 45.0f, DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, durationInSec, hiddenByNearerObjects);
float endingAngleDegCCFromUp = startingAngleDegCCFromUp + turnAngleDegCC;
return endingAngleDegCCFromUp;
}
else
{
float endingAngleDegCCFromUp = startingAngleDegCCFromUp;
return endingAngleDegCCFromUp;
}
}
public void TryDrawStraightSegmentBorderLine(Color color_ofPrecedingSegment, float durationInSec, bool hiddenByNearerObjects)
{
if (isTooSmallToBeDrawn == false)
{
float lengthOfStripes = 0.03f * radius_ofPieCircle;
LineWithAlternatingColors_fadeableAnimSpeed.InternalDraw(chart_thisSegmentIsPartOf.Position_worldspace, chart_thisSegmentIsPartOf.Position_worldspace + center_to_startPosOfThinOuterBorderLine, color_ofPrecedingSegment, color, 0.0f, lengthOfStripes, null, 0.0f, null, default(Vector3), true, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, true, true);
}
}
public void PrepareTextDrawing()
{
sizeOfText = 0.05f * radius_ofPieCircle * chart_thisSegmentIsPartOf.RelSize_ofSegmentsNameTexts;
drawnText = GetDrawnText();
if (drawnText == null) { return; }
if (isTooSmallToBeDrawn == false)
{
textInRightColumn_shouldBeInsideTheOthersSection = false;
float segmentMiddleAngleDegCCFromUp = startingAngleDegCCFromUp + 0.5f * turnAngleDegCC;
float segmentMiddleAngleDegCCFromUp_loopedToSpanOf_0to360 = UtilitiesDXXL_Math.Loop_floatIntoSpanFrom_0_to_x(segmentMiddleAngleDegCCFromUp, 360.0f);
Quaternion rotation_fromPieUp_to_segmentCenter = Quaternion.AngleAxis(segmentMiddleAngleDegCCFromUp, chart_thisSegmentIsPartOf.Forward_normalized);
Vector3 center_to_segmentMiddle_normalized = rotation_fromPieUp_to_segmentCenter * chart_thisSegmentIsPartOf.Up_normalized;
//This doesn't write yet, but only fills parsedTextSpecs:
UtilitiesDXXL_Text.Write(drawnText, Vector3.zero, default(Color), sizeOfText, Vector3.right, Vector3.up, DrawText.TextAnchorDXXL.MiddleCenter, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, false, 0.0f, true, true, false, true);
float width_ofTextBlock = DrawText.parsedTextSpecs.widthOfLongestLine;
float height_ofTextBlock = DrawText.parsedTextSpecs.height_wholeTextBlock;
Quaternion rotation_aroundGlobalForward_fromGlobalUp_toSegmentMiddleIfChartIsUnrotatedInsideXYPlane = Quaternion.AngleAxis(segmentMiddleAngleDegCCFromUp, Vector3.forward);
Vector2 center_to_segmentMiddle_unrotatedV3 = rotation_aroundGlobalForward_fromGlobalUp_toSegmentMiddleIfChartIsUnrotatedInsideXYPlane * Vector3.up;
Vector2 center_to_segmentMiddle_unrotatedV2 = new Vector2(center_to_segmentMiddle_unrotatedV3.x, center_to_segmentMiddle_unrotatedV3.y);
Vector2 intersectionOn2DUnitBoundsWithLowLeftAtZero_towardsCircleCenter = InternalDXXL_BoundsCamViewportSpace.GetViewportCenterPlumbIntersectionWithViewportBorder(InternalDXXL_BoundsCamViewportSpace.viewportCenter - center_to_segmentMiddle_unrotatedV2);
Vector2 center_of2DTextBoundsWithLowLeftAtZero = 0.5f * new Vector2(width_ofTextBlock, height_ofTextBlock);
Vector2 intersectionOn2DTextBoundsWithLowLeftAtZero_towardsCircleCenter = new Vector2(intersectionOn2DUnitBoundsWithLowLeftAtZero_towardsCircleCenter.x * width_ofTextBlock, intersectionOn2DUnitBoundsWithLowLeftAtZero_towardsCircleCenter.y * height_ofTextBlock);
float distance_fromTextBlockBoundsIntersectionTowardsCircleCenter_toTextCenter = (intersectionOn2DTextBoundsWithLowLeftAtZero_towardsCircleCenter - center_of2DTextBoundsWithLowLeftAtZero).magnitude;
float distanceOfTextToCircleCenter = radius_ofPieCircle * 1.1f + distance_fromTextBlockBoundsIntersectionTowardsCircleCenter_toTextCenter;
positionOfText = chart_thisSegmentIsPartOf.Position_worldspace + center_to_segmentMiddle_normalized * distanceOfTextToCircleCenter;
textAnchor = DrawText.TextAnchorDXXL.MiddleCenter; //-> this prevents jumping of the text position, compared to a solution where the anchor is at the side of the textBlock that is nearest to the circleCenter
float enclosingBox_paddingSize_relToTextSize = 0.0f;//-> this defines the enclosingBoxVertices that get used by "Get_angleDeg_thatTextWouldCover()"
//again: This doesn't write yet, but only fills parsedTextSpecs:
UtilitiesDXXL_Text.Write(drawnText, positionOfText, default(Color), sizeOfText, chart_thisSegmentIsPartOf.Right_normalized, chart_thisSegmentIsPartOf.Up_normalized, textAnchor, DrawBasics.LineStyle.solid, 0.0f, enclosingBox_paddingSize_relToTextSize, 0.0f, 0.0f, 0.0f, chart_thisSegmentIsPartOf.autoFlipAllText_toFitObsererCamera, 0.0f, true, true, false, true);
float angleDeg_thatTextWouldCover = Get_angleDeg_thatTextWouldCover(segmentMiddleAngleDegCCFromUp_loopedToSpanOf_0to360); //-> this depends on the preceding fake "Write()"-call
float halfAngleDeg_thatTextWouldCover = 0.5f * angleDeg_thatTextWouldCover;
startAngleDegCCFromUp_ofTextBlock = segmentMiddleAngleDegCCFromUp_loopedToSpanOf_0to360 - halfAngleDeg_thatTextWouldCover;
endAngleDegCCFromUp_ofTextBlock = segmentMiddleAngleDegCCFromUp_loopedToSpanOf_0to360 + halfAngleDeg_thatTextWouldCover;
}
else
{
textShouldBeDrawnIntoRightColumn_becauseSpaceAtChartWasTooSmall = true;
textInRightColumn_shouldBeInsideTheOthersSection = true;
}
}
public void TryDrawTextBesideSegment(float durationInSec, bool hiddenByNearerObjects)
{
//-> caller guarantees: "isTooSmallToBeDrawn == false" or "isOthersSection"
if (drawnText == null) { return; }
if (chart_thisSegmentIsPartOf.CheckIfAngleForTextIsAlreadyCovered(startAngleDegCCFromUp_ofTextBlock, endAngleDegCCFromUp_ofTextBlock))
{
textShouldBeDrawnIntoRightColumn_becauseSpaceAtChartWasTooSmall = true;
}
else
{
UtilitiesDXXL_Text.Write(drawnText, positionOfText, color, sizeOfText, chart_thisSegmentIsPartOf.Right_normalized, chart_thisSegmentIsPartOf.Up_normalized, textAnchor, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, chart_thisSegmentIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects, false, false, true);
textShouldBeDrawnIntoRightColumn_becauseSpaceAtChartWasTooSmall = false;
chart_thisSegmentIsPartOf.MarkAngleSpanAsCoveredWithText(startAngleDegCCFromUp_ofTextBlock, endAngleDegCCFromUp_ofTextBlock);
}
}
public void ReportThat_textShouldBeDrawnIntoRightColumn_becauseSpaceAtChartWasTooSmall()
{
textShouldBeDrawnIntoRightColumn_becauseSpaceAtChartWasTooSmall = true;
}
public float TryDrawTextInRightColumnOutsideOthersSection(bool thisIsTheOthersSegment, float vertOffset_ofTextBlock, float durationInSec, bool hiddenByNearerObjects)
{
float vertOffset_ofNextTextBlock = vertOffset_ofTextBlock;
if (drawnText == null) { return vertOffset_ofNextTextBlock; }
if (CheckIfTextIsDrawn_inRightColumnOutsideOthersSection() || thisIsTheOthersSegment)
{
Vector3 topLeftPos_ofTextBlock = Get_topLeftPos_ofTextBlock(vertOffset_ofTextBlock);
UtilitiesDXXL_Text.Write(drawnText, topLeftPos_ofTextBlock, color, sizeOfText, chart_thisSegmentIsPartOf.Right_normalized, chart_thisSegmentIsPartOf.Up_normalized, DrawText.TextAnchorDXXL.UpperLeft, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, chart_thisSegmentIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects, false, false, true);
vertOffset_ofNextTextBlock = Get_vertOffset_ofNextTextBlock(vertOffset_ofTextBlock);
}
return vertOffset_ofNextTextBlock;
}
bool CheckIfTextIsDrawn_inRightColumnOutsideOthersSection()
{
if (textShouldBeDrawnIntoRightColumn_becauseSpaceAtChartWasTooSmall)
{
if (textInRightColumn_shouldBeInsideTheOthersSection == false)
{
if (chart_thisSegmentIsPartOf.mentionZeroSegmentsInLegend || (valueAsFloat > 0.0f))
{
return true;
}
}
}
return false;
}
public float TryDrawTextInRightColumnInsideOthersSection(float vertOffset_ofTextBlock, Color color_ofOthersSegment, float durationInSec, bool hiddenByNearerObjects)
{
float vertOffset_ofNextTextBlock = vertOffset_ofTextBlock;
if (drawnText == null) { return vertOffset_ofNextTextBlock; }
if (textShouldBeDrawnIntoRightColumn_becauseSpaceAtChartWasTooSmall)
{
if (textInRightColumn_shouldBeInsideTheOthersSection)
{
if (chart_thisSegmentIsPartOf.mentionZeroSegmentsInLegend || (valueAsFloat > 0.0f))
{
Vector3 topLeftPos_ofTextBlock = Get_topLeftPos_ofTextBlock(vertOffset_ofTextBlock);
bool autoFlipToPreventMirrorInverted = false;
UtilitiesDXXL_Text.Write("<icon=arrowRight>", topLeftPos_ofTextBlock, color_ofOthersSegment, 2.0f * sizeOfText, chart_thisSegmentIsPartOf.Right_normalized, chart_thisSegmentIsPartOf.Up_normalized, DrawText.TextAnchorDXXL.UpperLeft, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, autoFlipToPreventMirrorInverted, durationInSec, hiddenByNearerObjects, false, false, true);
float horizOffset_dueToArrow = 4.0f * sizeOfText;
Vector3 posOfTextBlock = topLeftPos_ofTextBlock + chart_thisSegmentIsPartOf.Right_normalized * horizOffset_dueToArrow - chart_thisSegmentIsPartOf.Up_normalized * (0.85f * sizeOfText);
UtilitiesDXXL_Text.Write(drawnText, posOfTextBlock, color, sizeOfText, chart_thisSegmentIsPartOf.Right_normalized, chart_thisSegmentIsPartOf.Up_normalized, DrawText.TextAnchorDXXL.UpperLeft, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, chart_thisSegmentIsPartOf.autoFlipAllText_toFitObsererCamera, durationInSec, hiddenByNearerObjects, false, false, true);
vertOffset_ofNextTextBlock = Get_vertOffset_ofNextTextBlock(vertOffset_ofTextBlock);
}
}
}
return vertOffset_ofNextTextBlock;
}
float Get_angleDeg_thatTextWouldCover(float segmentMiddleAngleDegCCFromUp_loopedToSpanOf_0to360)
{
Vector3 maxAngleDefining_textBlockCorner1;
Vector3 maxAngleDefining_textBlockCorner2;
if (segmentMiddleAngleDegCCFromUp_loopedToSpanOf_0to360 < 90.0f)
{
maxAngleDefining_textBlockCorner1 = DrawText.parsedTextSpecs.lowLeftPos_ofEnclosingBox;
maxAngleDefining_textBlockCorner2 = DrawText.parsedTextSpecs.upperRightPos_ofEnclosingBox;
}
else
{
if (segmentMiddleAngleDegCCFromUp_loopedToSpanOf_0to360 < 180.0f)
{
maxAngleDefining_textBlockCorner1 = DrawText.parsedTextSpecs.lowRightPos_ofEnclosingBox;
maxAngleDefining_textBlockCorner2 = DrawText.parsedTextSpecs.upperLeftPos_ofEnclosingBox;
}
else
{
if (segmentMiddleAngleDegCCFromUp_loopedToSpanOf_0to360 < 270.0f)
{
maxAngleDefining_textBlockCorner1 = DrawText.parsedTextSpecs.lowLeftPos_ofEnclosingBox;
maxAngleDefining_textBlockCorner2 = DrawText.parsedTextSpecs.upperRightPos_ofEnclosingBox;
}
else
{
maxAngleDefining_textBlockCorner1 = DrawText.parsedTextSpecs.lowRightPos_ofEnclosingBox;
maxAngleDefining_textBlockCorner2 = DrawText.parsedTextSpecs.upperLeftPos_ofEnclosingBox;
}
}
}
Vector3 circleCenter_toTextBlockCorner1 = maxAngleDefining_textBlockCorner1 - chart_thisSegmentIsPartOf.Position_worldspace;
Vector3 circleCenter_toTextBlockCorner2 = maxAngleDefining_textBlockCorner2 - chart_thisSegmentIsPartOf.Position_worldspace;
return Vector3.Angle(circleCenter_toTextBlockCorner1, circleCenter_toTextBlockCorner2);
}
Vector3 Get_topLeftPos_ofTextBlock(float vertOffset_ofTextBlock)
{
float size_ofPieCircleRadius = 0.5f * chart_thisSegmentIsPartOf.Size_ofPieCircleDiameter;
float offsetDistance_upward = chart_thisSegmentIsPartOf.Get_vertOffset_fromCircleCenter_toTopRightPosOfRightColumn() + vertOffset_ofTextBlock;
float offsetDistance_sideward = (size_ofPieCircleRadius + size_ofPieCircleRadius * 1.05f * chart_thisSegmentIsPartOf.RelSize_ofSegmentsNameTexts);
return (chart_thisSegmentIsPartOf.Position_worldspace + chart_thisSegmentIsPartOf.Up_normalized * offsetDistance_upward + chart_thisSegmentIsPartOf.Right_normalized * offsetDistance_sideward);
}
float Get_vertOffset_ofNextTextBlock(float vertOffset_ofCurrTextBlock)
{
float relDistanceBetweenTextsInsideRightColumn = 0.025f;
return (vertOffset_ofCurrTextBlock - (DrawText.parsedTextSpecs.height_wholeTextBlock + relDistanceBetweenTextsInsideRightColumn * chart_thisSegmentIsPartOf.Size_ofPieCircleDiameter));
}
string GetDrawnText()
{
if ((chart_thisSegmentIsPartOf.showSegmentNames == true) && (chart_thisSegmentIsPartOf.showSegmentValues == true) && (chart_thisSegmentIsPartOf.showSegmentPercentages == true))
{
//-> show all
return (name + "<br>" + (hasAtLeastBeenFilledOnceWithFloatInsteadOfInt ? valueAsFloat : valueAsInt) + "<br>" + GetPercentageDisplay());
}
else
{
if ((chart_thisSegmentIsPartOf.showSegmentNames == false) && (chart_thisSegmentIsPartOf.showSegmentValues == true) && (chart_thisSegmentIsPartOf.showSegmentPercentages == true))
{
return ("" + (hasAtLeastBeenFilledOnceWithFloatInsteadOfInt ? valueAsFloat : valueAsInt) + "<br>" + GetPercentageDisplay());
}
else
{
if ((chart_thisSegmentIsPartOf.showSegmentNames == true) && (chart_thisSegmentIsPartOf.showSegmentValues == false) && (chart_thisSegmentIsPartOf.showSegmentPercentages == true))
{
return (name + "<br>" + GetPercentageDisplay());
}
else
{
if ((chart_thisSegmentIsPartOf.showSegmentNames == true) && (chart_thisSegmentIsPartOf.showSegmentValues == true) && (chart_thisSegmentIsPartOf.showSegmentPercentages == false))
{
return (name + "<br>" + (hasAtLeastBeenFilledOnceWithFloatInsteadOfInt ? valueAsFloat : valueAsInt));
}
else
{
if ((chart_thisSegmentIsPartOf.showSegmentNames == true) && (chart_thisSegmentIsPartOf.showSegmentValues == false) && (chart_thisSegmentIsPartOf.showSegmentPercentages == false))
{
return name;
}
else
{
if ((chart_thisSegmentIsPartOf.showSegmentNames == false) && (chart_thisSegmentIsPartOf.showSegmentValues == true) && (chart_thisSegmentIsPartOf.showSegmentPercentages == false))
{
return ("" + (hasAtLeastBeenFilledOnceWithFloatInsteadOfInt ? valueAsFloat : valueAsInt));
}
else
{
if ((chart_thisSegmentIsPartOf.showSegmentNames == false) && (chart_thisSegmentIsPartOf.showSegmentValues == false) && (chart_thisSegmentIsPartOf.showSegmentPercentages == true))
{
return GetPercentageDisplay();
}
else
{
//-> show nothing
if (((chart_thisSegmentIsPartOf.showSegmentNames == false) && (chart_thisSegmentIsPartOf.showSegmentValues == false) && (chart_thisSegmentIsPartOf.showSegmentPercentages == false)) == false)
{
UtilitiesDXXL_Log.PrintErrorCode("29-" + chart_thisSegmentIsPartOf.showSegmentNames + "-" + chart_thisSegmentIsPartOf.showSegmentValues + "-" + chart_thisSegmentIsPartOf.showSegmentPercentages);
}
return null;
}
}
}
}
}
}
}
}
string GetPercentageDisplay()
{
float value;
if (chart_thisSegmentIsPartOf.postDecimalPositions_ofPercentageDisplay <= 0)
{
value = Mathf.Round(100.0f * percentage_0to1);
}
else
{
float postDecimalPositions_ofPercentageDisplay_asFloat = (float)chart_thisSegmentIsPartOf.postDecimalPositions_ofPercentageDisplay;
float factor1 = Mathf.Pow(0.1f, postDecimalPositions_ofPercentageDisplay_asFloat);
float factor2 = 100.0f * Mathf.Pow(10.0f, postDecimalPositions_ofPercentageDisplay_asFloat);
value = factor1 * Mathf.Round(factor2 * percentage_0to1);
}
return "<size=15>" + value + " %</size>";
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bc081852df8d85745917b02aa7471345
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ea334b5da36419547b452d3e2e7dbfa7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,39 @@
namespace DrawXXL
{
public struct InternalDXXL_PieAngleSpan
{
public float startAngleDegCCFromUp;
public float endAngleDegCCFromUp;
public bool DoesIntersect(float startAngleDegCCFromUp_ofSpanThatIsCheckedIfItIntersectsWithThisSpan, float endAngleDegCCFromUp_ofSpanThatIsCheckedIfItIntersectsWithThisSpan)
{
//This function expects:
//-> startAngleDegCCFromUp is smaller than endAngleDegCCFromUp
//-> at least one angle lies between 0 and 360, and the other angle is not looped into this span, but is either negative or bigger thatn 360
//(both is guaranteed by "PieChartSegment.PrepareTextDrawing")
if (startAngleDegCCFromUp_ofSpanThatIsCheckedIfItIntersectsWithThisSpan < startAngleDegCCFromUp)
{
if (endAngleDegCCFromUp_ofSpanThatIsCheckedIfItIntersectsWithThisSpan < startAngleDegCCFromUp)
{
return false;
}
else
{
return true;
}
}
else
{
if (startAngleDegCCFromUp_ofSpanThatIsCheckedIfItIntersectsWithThisSpan < endAngleDegCCFromUp)
{
return true;
}
else
{
return false;
}
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: abed9bbbb2db23c40a707aeb07e0bde0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: