Complete re-write for the mythic+ chart shown in the end of the run
This commit is contained in:
+27
-22
@@ -2,53 +2,58 @@
|
|||||||
--documentation: see the header of the file charts.lua
|
--documentation: see the header of the file charts.lua
|
||||||
|
|
||||||
|
|
||||||
--1º example: making a simple chart, just copy and paste this code into a lua file and run it
|
--1º example: making a simple chart with two lines, just copy and paste this code into a lua file and run it
|
||||||
do
|
do
|
||||||
local ChartFrameTest = ChartFrameExample1 or DetailsFramework:CreateGraphicLineFrame(UIParent, "ChartFrameExample1")
|
local ChartFrameTest = ChartFrameExample1 or DetailsFramework:CreateGraphicMultiLineFrame(UIParent, "ChartFrameExample1")
|
||||||
ChartFrameTest:SetPoint("left", UIParent, "left", 10, 0) --set the position of the chart
|
ChartFrameTest:SetPoint("left", UIParent, "left", 10, 0) --set the position of the chart
|
||||||
ChartFrameTest:SetSize(800, 600) --set the size of the chart
|
ChartFrameTest:SetSize(800, 600) --set the size of the chart
|
||||||
DetailsFramework:ApplyStandardBackdrop(ChartFrameTest) --apply a backdrop to this example hence see the frame size
|
DetailsFramework:ApplyStandardBackdrop(ChartFrameTest) --apply a backdrop to this example hence see the frame size
|
||||||
|
|
||||||
--set the data (required)
|
--add a line:
|
||||||
local data = {1, 2, 30, 25, 6, 5, 4, 8, 7, 4, 1, 12, 15, 24, 18, 17, 14, 15, 8, 4, 14, 42, 22, 25, 30, 35, 39, 8, 7, 4, 1, 2, 5, 4, 8, 7, 4, 12, 12, 4}
|
local data = {1, 2, 30, 25, 6, 5, 4, 8, 7, 4, 1, 12, 15, 24, 18, 17, 14, 15, 8, 4, 14, 42, 22, 25, 30, 35, 39, 8, 7, 4, 1, 2, 5, 4, 8, 7, 4, 12, 12, 4}
|
||||||
local smoothnessLevel = 1 --(optional, default: 1)
|
local smoothingMethod = "sma" --(optional, default: "sma")
|
||||||
ChartFrameTest:SetData(data, smoothnessLevel)
|
local smoothnessLevel = 3 --(optional, default: 1)
|
||||||
|
local name = "Line 1" --(optional, default: none)
|
||||||
|
local red, green, blue, alpha = 1, 1, 1, 1 --(optional, default: 1, 1, 1, 1)
|
||||||
|
|
||||||
|
ChartFrameTest:AddData(data, smoothingMethod, smoothnessLevel, name, red, green, blue, alpha)
|
||||||
|
|
||||||
|
--add another line:
|
||||||
|
data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||||||
|
smoothingMethod = "loess" --using a different smoothing method
|
||||||
|
smoothnessLevel = 50
|
||||||
|
name = "Line 2"
|
||||||
|
local color = "red" --using a string with the color name
|
||||||
|
ChartFrameTest:AddData(data, smoothingMethod, smoothnessLevel, name, color)
|
||||||
|
|
||||||
--draw the chart
|
--draw the chart
|
||||||
ChartFrameTest:Plot()
|
ChartFrameTest:Plot()
|
||||||
end
|
end
|
||||||
|
|
||||||
--2º example: setting the color, thickness and scale of the line:
|
--2º example: thickness and scale of the line:
|
||||||
do
|
do
|
||||||
local ChartFrameTest = ChartFrameExample2 or DetailsFramework:CreateGraphicLineFrame(UIParent, "ChartFrameExample2")
|
local ChartFrameTest = ChartFrameExample2 or DetailsFramework:CreateGraphicMultiLineFrame(UIParent, "ChartFrameExample2")
|
||||||
ChartFrameTest:SetPoint("left", UIParent, "left", 10, 0) --set the position of the chart
|
ChartFrameTest:SetPoint("left", UIParent, "left", 10, 0) --set the position of the chart
|
||||||
ChartFrameTest:SetSize(800, 600) --set the size of the chart
|
ChartFrameTest:SetSize(800, 600) --set the size of the chart
|
||||||
DetailsFramework:ApplyStandardBackdrop(ChartFrameTest) --apply a backdrop to this example hence see the frame size
|
DetailsFramework:ApplyStandardBackdrop(ChartFrameTest) --apply a backdrop to this example hence see the frame size
|
||||||
|
|
||||||
|
--add the data (required)
|
||||||
|
local data = {1, 2, 30, 25, 6, 5, 4, 8, 7, 4, 1, 12, 15, 24 ,18, 17 ,14, 15, 8 , 4, 14, 42, 22, 25, 30, 35, 39, 8, 7, 4, 1, 2, 5, 4 ,8, 7 ,4, 12, 12 , 4}
|
||||||
|
ChartFrameTest:AddData(data)
|
||||||
|
|
||||||
--set the line thickness (optional, default: 2)
|
--set the line thickness (optional, default: 2)
|
||||||
local lineThickness = 3
|
local lineThickness = 3
|
||||||
ChartFrameTest:SetLineThickness(lineThickness)
|
ChartFrameTest:SetLineThickness(lineThickness)
|
||||||
|
|
||||||
--set the chart color (optional, default: "white")
|
|
||||||
local lineColor = {r = 1, g = 1, b = 0} --set it to "yellow"
|
|
||||||
ChartFrameTest:SetColor(lineColor) --using {r = 1, g = 1, b = 0}
|
|
||||||
ChartFrameTest:SetColor("yellow") --using the color name
|
|
||||||
ChartFrameTest:SetColor(1, 1, 0) --passing the rgb directly
|
|
||||||
ChartFrameTest:SetColor({1, 1, 0}) --using an index table
|
|
||||||
|
|
||||||
--set the data (required)
|
|
||||||
local data = {1, 2, 30, 25, 6, 5, 4, 8, 7, 4, 1, 12, 15, 24 ,18, 17 ,14, 15, 8 , 4, 14, 42, 22, 25, 30, 35, 39, 8, 7, 4, 1, 2, 5, 4 ,8, 7 ,4, 12, 12 , 4}
|
|
||||||
local smoothnessLevel = 1 --(optional, default: 1)
|
|
||||||
ChartFrameTest:SetData(data, smoothnessLevel)
|
|
||||||
|
|
||||||
--height modifier, if for some reason need to scale the chart height
|
--height modifier, if for some reason need to scale the chart height
|
||||||
local heightScale = 1 --(optional, default: 1)
|
local heightScale = 1.2 --(optional, default: 1)
|
||||||
--draw the chart
|
--draw the chart
|
||||||
ChartFrameTest:Plot(heightScale)
|
ChartFrameTest:Plot(heightScale)
|
||||||
end
|
end
|
||||||
|
|
||||||
--3º example: setting the axes lines and labels
|
--3º example: setting the axes lines and labels
|
||||||
do
|
do
|
||||||
local ChartFrameTest = ChartFrameExample3 or DetailsFramework:CreateGraphicLineFrame(UIParent, "ChartFrameExample3")
|
local ChartFrameTest = ChartFrameExample3 or DetailsFramework:CreateGraphicMultiLineFrame(UIParent, "ChartFrameExample3")
|
||||||
ChartFrameTest:SetPoint("left", UIParent, "left", 10, 0)
|
ChartFrameTest:SetPoint("left", UIParent, "left", 10, 0)
|
||||||
ChartFrameTest:SetSize(800, 600)
|
ChartFrameTest:SetSize(800, 600)
|
||||||
DetailsFramework:ApplyStandardBackdrop(ChartFrameTest)
|
DetailsFramework:ApplyStandardBackdrop(ChartFrameTest)
|
||||||
@@ -76,7 +81,7 @@ do
|
|||||||
|
|
||||||
--setting the data, doesn't matter if it is set at the top or right before Plot()
|
--setting the data, doesn't matter if it is set at the top or right before Plot()
|
||||||
local data = {1, 2, 30, 25, 6, 5, 4, 8, 7, 4, 1, 12, 15, 24 ,18, 17 ,14, 15, 8 , 4, 14, 42, 22, 25, 30, 35, 39, 8, 7, 4, 1, 2, 5, 4 ,8, 7 ,4, 12, 12 , 4}
|
local data = {1, 2, 30, 25, 6, 5, 4, 8, 7, 4, 1, 12, 15, 24 ,18, 17 ,14, 15, 8 , 4, 14, 42, 22, 25, 30, 35, 39, 8, 7, 4, 1, 2, 5, 4 ,8, 7 ,4, 12, 12 , 4}
|
||||||
ChartFrameTest:SetData(data) --smoothnessLevel is absent here, it'll use 1 as default
|
ChartFrameTest:AddData(data)
|
||||||
ChartFrameTest:Plot()
|
ChartFrameTest:Plot()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
+525
-90
@@ -33,7 +33,16 @@ local _
|
|||||||
---| "number" same as timer, but the number is not comverted to time
|
---| "number" same as timer, but the number is not comverted to time
|
||||||
---| "value" a fixed table with values is passed by the SetXAxisData() function
|
---| "value" a fixed table with values is passed by the SetXAxisData() function
|
||||||
|
|
||||||
|
---@class df_chartline : line
|
||||||
|
---@field thickness number
|
||||||
|
|
||||||
---@class df_chartshared: table
|
---@class df_chartshared: table
|
||||||
|
---@field fillOrder table<number, number[]> the order of the lines to be filled, this table is shared by all charts
|
||||||
|
---@field bFillChart boolean if the chart lines should be filled or not
|
||||||
|
---@field fillChartLineThickness number the thickness of the fill line
|
||||||
|
---@field bRunningInBackground boolean true if there is a proccess happening asynchronously
|
||||||
|
---@field waitForBackgroundProcessTicker timer a ticker to check if all background process finished
|
||||||
|
---@field amountOfBackgroundProcess number the amount of background processes happening
|
||||||
---@field yAxisLine line the vertical line which can be anchored in the left or right side of the frame, if the chart is a multi chart, this line is shared by all charts
|
---@field yAxisLine line the vertical line which can be anchored in the left or right side of the frame, if the chart is a multi chart, this line is shared by all charts
|
||||||
---@field xAxisLine line the horizontal line which can be anchored in the top or bottom side of the frame, if the chart is a multi chart, this line is shared by all charts
|
---@field xAxisLine line the horizontal line which can be anchored in the top or bottom side of the frame, if the chart is a multi chart, this line is shared by all charts
|
||||||
---@field xAxisDataNumber any if the data type of the x axis is "number" or "time"
|
---@field xAxisDataNumber any if the data type of the x axis is "number" or "time"
|
||||||
@@ -49,12 +58,17 @@ local _
|
|||||||
---@field smoothnessLevel number default: 0, the smoothness level of the chart lines, 0 is no smoothness
|
---@field smoothnessLevel number default: 0, the smoothness level of the chart lines, 0 is no smoothness
|
||||||
---@field backdropIndicators chart_backdropindicator[]
|
---@field backdropIndicators chart_backdropindicator[]
|
||||||
---@field nextBackdropIndicator number tell which is the next backdrop indicator to be used
|
---@field nextBackdropIndicator number tell which is the next backdrop indicator to be used
|
||||||
|
---@field SetFillChart fun(self: df_chartshared, bFill: boolean, lineThickness:number?) set if the chart lines should be filled or not
|
||||||
|
---@field GetFillState fun(self: df_chartshared) : boolean, number return if the chart lines should be filled or not
|
||||||
|
---@field ShrinkData fun(self: df_chartmulti|df_chart, data: table, skrinkBy: number, bJustDrop: boolean?) : table
|
||||||
|
---@field HasBackgroundProcess fun(self: df_chartmulti|df_chart) : boolean return true if there is a proccess happening asynchronously
|
||||||
|
---@field SetBackgroundProcessState fun(self: df_chartmulti|df_chart, bRunning: boolean) set if there is a proccess happening asynchronously
|
||||||
---@field CreateBackdropIndicator fun(self: df_chartmulti|df_chart, index: number) : chart_backdropindicator create a new backdrop indicator
|
---@field CreateBackdropIndicator fun(self: df_chartmulti|df_chart, index: number) : chart_backdropindicator create a new backdrop indicator
|
||||||
---@field GetBackdropIndicator fun(self: df_chartmulti|df_chart) : chart_backdropindicator get a backdrop indicator by index
|
---@field GetBackdropIndicator fun(self: df_chartmulti|df_chart) : chart_backdropindicator get a backdrop indicator by index
|
||||||
---@field ResetBackdropIndicators fun(self: df_chartmulti|df_chart) reset all backdrop indicators
|
---@field ResetBackdropIndicators fun(self: df_chartmulti|df_chart) reset all backdrop indicators
|
||||||
---@field SetAxesColor fun(self: df_chartmulti, red: number|string|table|nil, green: number|nil, blue: number|nil, alpha: number|nil) : boolean set the color of both axis lines
|
---@field SetAxesColor fun(self: df_chartmulti, red: number|string|table|nil, green: number|nil, blue: number|nil, alpha: number|nil) : boolean set the color of both axis lines
|
||||||
---@field SetAxesThickness fun(self: df_chartmulti, thickness: number) : boolean set the thickness of both axis lines
|
---@field SetAxesThickness fun(self: df_chartmulti, thickness: number) : boolean set the thickness of both axis lines
|
||||||
---@field CreateAxesLines fun(self: df_chartmulti|df_chart, xOffset: number, yOffset: number, whichSide: "left"|"right", thickness: number, amountYLabels: number, amountXLabels: number, red: any, green: number|nil, blue: number|nil, alpha: number|nil)
|
---@field CreateAxesLines fun(self: df_chartmulti|df_chart, xOffset: number, yOffset: number, whichSide: "left"|"right", thickness: number, amountYLabels: number, amountXLabels: number, red: any, green: number|nil, blue: number|nil, alpha: number|nil) create the x and y axis lines with their labels, offsets are the distance from left and bottom
|
||||||
---@field SetXAxisDataType fun(self: df_chartmulti|df_chart, dataType: x_axisdatatype) : boolean set the data type of the x axis, if time, the x axis will be a time axis, if value, the x axis will be a value axis
|
---@field SetXAxisDataType fun(self: df_chartmulti|df_chart, dataType: x_axisdatatype) : boolean set the data type of the x axis, if time, the x axis will be a time axis, if value, the x axis will be a value axis
|
||||||
---@field SetXAxisData fun(self: df_chartmulti|df_chart, data: any) set the data of the x axis, if time, the x axis will be a time axis, if value, the x axis will be a value axis
|
---@field SetXAxisData fun(self: df_chartmulti|df_chart, data: any) set the data of the x axis, if time, the x axis will be a time axis, if value, the x axis will be a value axis
|
||||||
---@field SharedContrustor fun(self: df_chartmulti|df_chart) set default values for fields used on both chart types
|
---@field SharedContrustor fun(self: df_chartmulti|df_chart) set default values for fields used on both chart types
|
||||||
@@ -78,13 +92,15 @@ end
|
|||||||
|
|
||||||
---@class df_chart: frame, df_data, df_value, df_chartshared
|
---@class df_chart: frame, df_data, df_value, df_chartshared
|
||||||
---@field _dataInfo df_data
|
---@field _dataInfo df_data
|
||||||
|
---@field average number
|
||||||
|
---@field depth number
|
||||||
---@field color number[] red green blue alpha
|
---@field color number[] red green blue alpha
|
||||||
---@field height number
|
---@field height number
|
||||||
---@field nextLine number
|
---@field nextLine number
|
||||||
---@field minValue number
|
---@field minValue number
|
||||||
---@field maxValue number
|
---@field maxValue number
|
||||||
---@field data number[]
|
---@field data number[]
|
||||||
---@field lines line[]
|
---@field lines df_chartline[]
|
||||||
---@field fixedLineWidth number
|
---@field fixedLineWidth number
|
||||||
---@field chartName string
|
---@field chartName string
|
||||||
---@field dataPoint_OnEnterFunc fun(self: df_chart, onEnterFunc: function, ...) set the function to be called when the mouse hover over a data point in the chart
|
---@field dataPoint_OnEnterFunc fun(self: df_chart, onEnterFunc: function, ...) set the function to be called when the mouse hover over a data point in the chart
|
||||||
@@ -93,8 +109,8 @@ end
|
|||||||
---@field dataPoint_OnLeavePayload any[] set the payload to be passed to the function set by DataPoint_OnLeaveFunc
|
---@field dataPoint_OnLeavePayload any[] set the payload to be passed to the function set by DataPoint_OnLeaveFunc
|
||||||
---@field GetOnEnterLeaveFunctions fun(self: df_chart) : function, any[], function, any[] return the functions and payloads set by DataPoint_OnEnterFunc and DataPoint_OnLeaveFunc
|
---@field GetOnEnterLeaveFunctions fun(self: df_chart) : function, any[], function, any[] return the functions and payloads set by DataPoint_OnEnterFunc and DataPoint_OnLeaveFunc
|
||||||
---@field ChartFrameConstructor fun(self: df_chart) set the default values for the chart frame
|
---@field ChartFrameConstructor fun(self: df_chart) set the default values for the chart frame
|
||||||
---@field GetLine fun(self: df_chart) : line return a line and also internally handle next line
|
---@field GetLine fun(self: df_chart) : df_chartline return a line and also internally handle next line
|
||||||
---@field GetLines fun(self: df_chart) : line[] return a table with all lines already created
|
---@field GetLines fun(self: df_chart) : df_chartline[] return a table with all lines already created
|
||||||
---@field GetLineWidth fun(self: df_chart) : number calculate the width of each drawn line
|
---@field GetLineWidth fun(self: df_chart) : number calculate the width of each drawn line
|
||||||
---@field SetLineWidth fun(self: df_chart, width: number) set the line width to a fixed value
|
---@field SetLineWidth fun(self: df_chart, width: number) set the line width to a fixed value
|
||||||
---@field GetAmountLines fun(self: df_chart) : number return the amount of lines in use
|
---@field GetAmountLines fun(self: df_chart) : number return the amount of lines in use
|
||||||
@@ -106,7 +122,7 @@ end
|
|||||||
---@field SetLineThickness fun(self: df_chart, thickness: number) set the line thickness
|
---@field SetLineThickness fun(self: df_chart, thickness: number) set the line thickness
|
||||||
---@field CalcYAxisPointForValue fun(self: df_chart, value: number, plotFrameHeightScaled: number) : number
|
---@field CalcYAxisPointForValue fun(self: df_chart, value: number, plotFrameHeightScaled: number) : number
|
||||||
---@field UpdateFrameSizeCache fun(self: df_chart)
|
---@field UpdateFrameSizeCache fun(self: df_chart)
|
||||||
---@field Plot fun(self: df_chart, yPointScale: number|nil, bUpdateLabels: boolean|nil) draw the graphic using lines and following the data set by SetData() or AddData() in multi chart
|
---@field Plot fun(self: df_chart, yPointScale: number|nil, bUpdateLabels: boolean|nil, lineId:number?) draw the graphic using lines and following the data set by SetData() or AddData() in multi chart
|
||||||
|
|
||||||
---@class df_chartmulti : df_chart, df_chartshared
|
---@class df_chartmulti : df_chart, df_chartshared
|
||||||
---@field chartFrames df_chart[]
|
---@field chartFrames df_chart[]
|
||||||
@@ -117,7 +133,7 @@ end
|
|||||||
---@field MultiChartFrameConstructor fun(self: df_chartmulti)
|
---@field MultiChartFrameConstructor fun(self: df_chartmulti)
|
||||||
---@field GetCharts fun(self: df_chartmulti) : df_chart[]
|
---@field GetCharts fun(self: df_chartmulti) : df_chart[]
|
||||||
---@field GetChart fun(self: df_chartmulti) : df_chart
|
---@field GetChart fun(self: df_chartmulti) : df_chart
|
||||||
---@field AddData fun(self: df_chartmulti, data: table, name: string, red: any, green: number|nil, blue: number|nil, alpha: number|nil)
|
---@field AddData fun(self: df_chartmulti, data: table, smoothingMethod: string|nil, smoothnessLevel:number, name: string, red: any, green: number|nil, blue: number|nil, alpha: number|nil)
|
||||||
---@field GetAmountCharts fun(self: df_chartmulti): number
|
---@field GetAmountCharts fun(self: df_chartmulti): number
|
||||||
---@field HideCharts fun(self: df_chartmulti)
|
---@field HideCharts fun(self: df_chartmulti)
|
||||||
---@field Reset fun(self: df_chartmulti)
|
---@field Reset fun(self: df_chartmulti)
|
||||||
@@ -190,7 +206,6 @@ local createHorizontalAxisLabels = function(parent, amountLabels, labelsTable, r
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---create the x and y axis lines with their labels
|
|
||||||
---@param self df_chart|df_chartmulti
|
---@param self df_chart|df_chartmulti
|
||||||
---@param xOffset number
|
---@param xOffset number
|
||||||
---@param yOffset number
|
---@param yOffset number
|
||||||
@@ -342,8 +357,84 @@ local updateLabelValues = function(self)
|
|||||||
end
|
end
|
||||||
|
|
||||||
detailsFramework.ChartFrameSharedMixin = {
|
detailsFramework.ChartFrameSharedMixin = {
|
||||||
---set the color of both axis lines
|
---set if the chart lines should be filled or not, when filled, an extra line is drawn at the bottom of the chart to close the fill
|
||||||
|
---@param self df_chartshared
|
||||||
|
---@param bFill boolean
|
||||||
|
---@param lineThickness number?
|
||||||
|
SetFillChart = function(self, bFill, lineThickness)
|
||||||
|
lineThickness = lineThickness or 1
|
||||||
|
self.bFillChart = bFill
|
||||||
|
self.fillChartLineThickness = lineThickness
|
||||||
|
end,
|
||||||
|
|
||||||
|
---return if the chart lines should be filled or not
|
||||||
|
---@param self df_chartshared
|
||||||
|
---@return boolean
|
||||||
|
---@return number
|
||||||
|
GetFillState = function(self)
|
||||||
|
return self.bFillChart, self.fillChartLineThickness
|
||||||
|
end,
|
||||||
|
|
||||||
|
---receives a table containing the data to be plotted in the chart, returns a new table with the data reduced by the skrinkBy value
|
||||||
|
---if bJustDrop is true, the data will be reduced by dropping values, if false, the data will be reduced by averaging the values
|
||||||
---@param self df_chart|df_chartmulti
|
---@param self df_chart|df_chartmulti
|
||||||
|
---@param data table
|
||||||
|
---@param skrinkBy number
|
||||||
|
---@param bJustDrop boolean
|
||||||
|
---@return table
|
||||||
|
ShrinkData = function(self, data, skrinkBy, bJustDrop)
|
||||||
|
local newData = {}
|
||||||
|
local dataSize = #data
|
||||||
|
|
||||||
|
local tinsert = table.insert
|
||||||
|
|
||||||
|
if (bJustDrop) then
|
||||||
|
if (true) then
|
||||||
|
--make a for loop to drop the values by random, for example, is shrink is 3 and index is 9, it will drop at random two values of: 9 10 or 11
|
||||||
|
else
|
||||||
|
--it will shrink the data by dropping values each skrinkBy indexes
|
||||||
|
for i = 1, dataSize, skrinkBy do
|
||||||
|
tinsert(newData, data[i])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
--it will shrink the data by making an average of the values and add to newTable, shrinkBy controls how many values will be averaged
|
||||||
|
for i = 1, dataSize, skrinkBy do
|
||||||
|
local sum = 0
|
||||||
|
for o = 0, skrinkBy - 1 do
|
||||||
|
sum = sum + (data[i + o] or 0) --attempt to perform arithmetic on field '?' (a nil value)
|
||||||
|
end
|
||||||
|
tinsert(newData, sum / skrinkBy)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return newData
|
||||||
|
end,
|
||||||
|
|
||||||
|
---return if there is a proccess happening asynchronously
|
||||||
|
---@param self df_chartmulti
|
||||||
|
---@return boolean
|
||||||
|
HasBackgroundProcess = function(self)
|
||||||
|
return self.bRunningInBackground
|
||||||
|
end,
|
||||||
|
|
||||||
|
---set if there is a proccess happening asynchronously
|
||||||
|
---@param self df_chartmulti
|
||||||
|
---@param bRunning boolean
|
||||||
|
SetBackgroundProcessState = function(self, bRunning)
|
||||||
|
if (bRunning) then
|
||||||
|
self.amountOfBackgroundProcess = self.amountOfBackgroundProcess + 1
|
||||||
|
self.bRunningInBackground = bRunning
|
||||||
|
else
|
||||||
|
self.amountOfBackgroundProcess = self.amountOfBackgroundProcess - 1
|
||||||
|
if (self.amountOfBackgroundProcess == 0) then
|
||||||
|
self.bRunningInBackground = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
---set the color of both axis lines
|
||||||
|
---@param self df_chartmulti
|
||||||
---@param red any
|
---@param red any
|
||||||
---@param green number|nil
|
---@param green number|nil
|
||||||
---@param blue number|nil
|
---@param blue number|nil
|
||||||
@@ -372,7 +463,7 @@ detailsFramework.ChartFrameSharedMixin = {
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
---set the thickness of both axis lines
|
---set the thickness of both axis lines
|
||||||
---@param self df_chart|df_chartmulti
|
---@param self df_chartmulti
|
||||||
---@param thickness number
|
---@param thickness number
|
||||||
---@return boolean bThicknessChanged return true if the thickness was set, false if the axis lines are not created yet
|
---@return boolean bThicknessChanged return true if the thickness was set, false if the axis lines are not created yet
|
||||||
SetAxesThickness = function(self, thickness)
|
SetAxesThickness = function(self, thickness)
|
||||||
@@ -385,7 +476,7 @@ detailsFramework.ChartFrameSharedMixin = {
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
---create the x and y axis lines with their labels
|
---create the x and y axis lines with their labels
|
||||||
---@param self df_chart|df_chartmulti
|
---@param self df_chartmulti
|
||||||
---@param xOffset number
|
---@param xOffset number
|
||||||
---@param yOffset number
|
---@param yOffset number
|
||||||
---@param whichSide "left"|"right"
|
---@param whichSide "left"|"right"
|
||||||
@@ -401,20 +492,20 @@ detailsFramework.ChartFrameSharedMixin = {
|
|||||||
return createAxesLines(self, xOffset, yOffset, whichSide, thickness, amountYLabels, amountXLabels, red, green, blue, alpha)
|
return createAxesLines(self, xOffset, yOffset, whichSide, thickness, amountYLabels, amountXLabels, red, green, blue, alpha)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
---@param self df_chartmulti|df_chart
|
---@param self df_chartmulti
|
||||||
---@param ... any
|
---@param ... any
|
||||||
SetXAxisData = function(self, ...)
|
SetXAxisData = function(self, ...)
|
||||||
setXAxisData(self, ...)
|
setXAxisData(self, ...)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
---@param self df_chartmulti|df_chart
|
---@param self df_chartmulti
|
||||||
---@param dataType x_axisdatatype
|
---@param dataType x_axisdatatype
|
||||||
SetXAxisDataType = function(self, dataType)
|
SetXAxisDataType = function(self, dataType)
|
||||||
setXAxisDataType(self, dataType)
|
setXAxisDataType(self, dataType)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
---create a new backdrop indicator, this is called from the function GetBackdropIndicator
|
---create a new backdrop indicator, this is called from the function GetBackdropIndicator
|
||||||
---@param self df_chartmulti|df_chart
|
---@param self df_chartmulti
|
||||||
---@return chart_backdropindicator
|
---@return chart_backdropindicator
|
||||||
CreateBackdropIndicator = function(self, nextIndicatorIndex)
|
CreateBackdropIndicator = function(self, nextIndicatorIndex)
|
||||||
---@type chart_backdropindicator
|
---@type chart_backdropindicator
|
||||||
@@ -444,7 +535,7 @@ detailsFramework.ChartFrameSharedMixin = {
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
---reset the backdrop indicators by hidding all of them
|
---reset the backdrop indicators by hidding all of them
|
||||||
---@param self df_chartmulti|df_chart
|
---@param self df_chartmulti
|
||||||
ResetBackdropIndicators = function(self)
|
ResetBackdropIndicators = function(self)
|
||||||
for i = 1, #self.backdropIndicators do
|
for i = 1, #self.backdropIndicators do
|
||||||
local thisBackdropIndicator = self.backdropIndicators[i]
|
local thisBackdropIndicator = self.backdropIndicators[i]
|
||||||
@@ -455,7 +546,7 @@ detailsFramework.ChartFrameSharedMixin = {
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
---get a backdrop indicator, if it doesn't exist, create a new one
|
---get a backdrop indicator, if it doesn't exist, create a new one
|
||||||
---@param self df_chartmulti|df_chart
|
---@param self df_chartmulti
|
||||||
---@return chart_backdropindicator
|
---@return chart_backdropindicator
|
||||||
GetBackdropIndicator = function(self)
|
GetBackdropIndicator = function(self)
|
||||||
local nextIndicator = self.nextBackdropIndicator
|
local nextIndicator = self.nextBackdropIndicator
|
||||||
@@ -469,7 +560,7 @@ detailsFramework.ChartFrameSharedMixin = {
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
---add a backdrop indicator to the chart
|
---add a backdrop indicator to the chart
|
||||||
---@param self df_chartmulti|df_chart
|
---@param self df_chartmulti
|
||||||
---@param label string this is a text to be displayed on the left side of the indicator and on the top right corner of the chart panel
|
---@param label string this is a text to be displayed on the left side of the indicator and on the top right corner of the chart panel
|
||||||
---@param timeStart number the start time of the indicator
|
---@param timeStart number the start time of the indicator
|
||||||
---@param timeEnd number the end time of the indicator
|
---@param timeEnd number the end time of the indicator
|
||||||
@@ -497,7 +588,7 @@ detailsFramework.ChartFrameSharedMixin = {
|
|||||||
---when Plot() is called, this function will be called to show the backdrop indicators
|
---when Plot() is called, this function will be called to show the backdrop indicators
|
||||||
---it gets the x_axisdatatype or if not existant defaults to "time", calculate the area in pixels using the plot area width and the plot area 'time'
|
---it gets the x_axisdatatype or if not existant defaults to "time", calculate the area in pixels using the plot area width and the plot area 'time'
|
||||||
---then set the texture color, label texts and show the small squere indicators in the top right of the plot area
|
---then set the texture color, label texts and show the small squere indicators in the top right of the plot area
|
||||||
---@param self df_chartmulti|df_chart
|
---@param self df_chartmulti
|
||||||
ShowBackdropIndicators = function(self)
|
ShowBackdropIndicators = function(self)
|
||||||
--get the x axis data type
|
--get the x axis data type
|
||||||
local xDataType = self.xAxisDataType or "time"
|
local xDataType = self.xAxisDataType or "time"
|
||||||
@@ -546,6 +637,117 @@ detailsFramework.ChartFrameSharedMixin = {
|
|||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local fillerLines_InAvailable = {}
|
||||||
|
local fillerLines_InUse = {}
|
||||||
|
|
||||||
|
---@class df_chartlazypayload : table
|
||||||
|
---@field self df_chartmulti
|
||||||
|
---@field currentDataIndex number
|
||||||
|
---@field executionsPerFrame number
|
||||||
|
---@field dataSize number
|
||||||
|
---@field currentXPoint number
|
||||||
|
---@field currentYPoint number
|
||||||
|
---@field eachLineWidth number
|
||||||
|
---@field plotFrameHeightScaled number
|
||||||
|
---@field r number
|
||||||
|
---@field g number
|
||||||
|
---@field b number
|
||||||
|
---@field lineId number
|
||||||
|
---@field bUpdateLabels boolean
|
||||||
|
---@field bFillChart boolean
|
||||||
|
---@field fillLineThickness number
|
||||||
|
|
||||||
|
--this is the function which is called by the schedules lazy execution system
|
||||||
|
local lazyChartUpdate = function(payload, iterationCount, maxIterations)
|
||||||
|
---@cast payload df_chartlazypayload
|
||||||
|
|
||||||
|
local self = payload.self
|
||||||
|
---@cast self df_chart
|
||||||
|
|
||||||
|
local currentDataIndex = payload.currentDataIndex
|
||||||
|
local dataSize = payload.dataSize
|
||||||
|
local currentXPoint = payload.currentXPoint
|
||||||
|
local currentYPoint = payload.currentYPoint
|
||||||
|
local eachLineWidth = payload.eachLineWidth
|
||||||
|
local plotFrameHeightScaled = payload.plotFrameHeightScaled
|
||||||
|
local r = payload.r
|
||||||
|
local g = payload.g
|
||||||
|
local b = payload.b
|
||||||
|
local lineId = payload.lineId
|
||||||
|
local bUpdateLabels = payload.bUpdateLabels
|
||||||
|
local bFillChart = payload.bFillChart
|
||||||
|
local fillLineThickness = payload.fillLineThickness
|
||||||
|
|
||||||
|
local executionsPerFrame = payload.executionsPerFrame
|
||||||
|
currentDataIndex = currentDataIndex + executionsPerFrame
|
||||||
|
|
||||||
|
for i = 1, payload.executionsPerFrame do
|
||||||
|
local value, dataIndex = self:GetDataNextValue()
|
||||||
|
if (not value) then
|
||||||
|
--the data stream has ended
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local line = self:GetLine()
|
||||||
|
line:SetColorTexture(r, g, b)
|
||||||
|
|
||||||
|
if (line.thickness ~= self.lineThickness) then
|
||||||
|
line:SetThickness(self.lineThickness)
|
||||||
|
line.thickness = self.lineThickness
|
||||||
|
end
|
||||||
|
|
||||||
|
--get the start points
|
||||||
|
local startX = currentXPoint
|
||||||
|
local startY = currentYPoint
|
||||||
|
currentXPoint = currentXPoint + eachLineWidth
|
||||||
|
--end point
|
||||||
|
local endX = currentXPoint
|
||||||
|
currentYPoint = self:CalcYAxisPointForValue(value, plotFrameHeightScaled)
|
||||||
|
local endY = currentYPoint
|
||||||
|
|
||||||
|
local length = detailsFramework:GetVectorLength(endX - startX, endY - startY)
|
||||||
|
--make sure the magnitude of the difference between previous point to current point is at least 1.5
|
||||||
|
if (length < 1.5) then
|
||||||
|
local diffX = endX - startX
|
||||||
|
local diffY = endY - startY
|
||||||
|
|
||||||
|
local diffLength = detailsFramework:GetVectorLength(diffX, diffY)
|
||||||
|
local scaleFactor = 1.5 / diffLength
|
||||||
|
|
||||||
|
diffX = diffX * scaleFactor
|
||||||
|
diffY = diffY * scaleFactor
|
||||||
|
|
||||||
|
endX = endX + diffX
|
||||||
|
endY = endY + diffY
|
||||||
|
end
|
||||||
|
|
||||||
|
--the start point starts where the latest point finished
|
||||||
|
line:SetStartPoint("bottomleft", startX, startY)
|
||||||
|
line:SetEndPoint("bottomleft", endX, endY)
|
||||||
|
|
||||||
|
if (bFillChart) then
|
||||||
|
if (lineId) then
|
||||||
|
local fillLine = table.remove(fillerLines_InAvailable)
|
||||||
|
if (not fillLine) then
|
||||||
|
fillLine = self.plotFrame:CreateLine(nil, "overlay")
|
||||||
|
fillLine:SetThickness(fillLineThickness)
|
||||||
|
fillerLines_InUse[#fillerLines_InUse+1] = fillLine
|
||||||
|
else
|
||||||
|
fillerLines_InUse[#fillerLines_InUse+1] = fillLine
|
||||||
|
end
|
||||||
|
|
||||||
|
fillLine:SetStartPoint("bottomleft", endX, endY)
|
||||||
|
fillLine:SetEndPoint("bottomleft", endX, 0)
|
||||||
|
fillLine:SetDrawLayer("overlay", self.depth)
|
||||||
|
fillLine:SetColorTexture(r, g, b, 0.15 + (self.depth/10))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
payload.currentXPoint = currentXPoint
|
||||||
|
payload.currentYPoint = currentYPoint
|
||||||
|
end
|
||||||
|
|
||||||
detailsFramework.ChartFrameMixin = {
|
detailsFramework.ChartFrameMixin = {
|
||||||
---set the default values for the chart frame
|
---set the default values for the chart frame
|
||||||
---@param self df_chart
|
---@param self df_chart
|
||||||
@@ -557,6 +759,8 @@ detailsFramework.ChartFrameMixin = {
|
|||||||
self.data = {}
|
self.data = {}
|
||||||
self.lines = {}
|
self.lines = {}
|
||||||
self.color = {1, 1, 1, 1}
|
self.color = {1, 1, 1, 1}
|
||||||
|
self.amountOfBackgroundProcess = 0
|
||||||
|
|
||||||
--OnSizeChanged
|
--OnSizeChanged
|
||||||
self:SetScript("OnSizeChanged", self.OnSizeChanged)
|
self:SetScript("OnSizeChanged", self.OnSizeChanged)
|
||||||
|
|
||||||
@@ -593,14 +797,17 @@ detailsFramework.ChartFrameMixin = {
|
|||||||
|
|
||||||
---internally handle next line
|
---internally handle next line
|
||||||
---@param self df_chart
|
---@param self df_chart
|
||||||
|
---@return df_chartline
|
||||||
GetLine = function(self)
|
GetLine = function(self)
|
||||||
---@type line
|
---@type df_chartline
|
||||||
local line = self.lines[self.nextLine]
|
local line = self.lines[self.nextLine]
|
||||||
|
|
||||||
if (not line) then
|
if (not line) then
|
||||||
---@type line
|
---@type line
|
||||||
line = self.plotFrame:CreateLine(nil, "overlay", nil, 5)
|
local newLine = self.plotFrame:CreateLine(nil, "overlay", nil, 5)
|
||||||
self.lines[self.nextLine] = line
|
---@cast newLine df_chartline
|
||||||
|
self.lines[self.nextLine] = newLine
|
||||||
|
line = newLine
|
||||||
end
|
end
|
||||||
|
|
||||||
self.nextLine = self.nextLine + 1
|
self.nextLine = self.nextLine + 1
|
||||||
@@ -610,7 +817,7 @@ detailsFramework.ChartFrameMixin = {
|
|||||||
|
|
||||||
---return all lines created for this chart
|
---return all lines created for this chart
|
||||||
---@param self df_chart
|
---@param self df_chart
|
||||||
---@return line[]
|
---@return df_chartline[]
|
||||||
GetLines = function(self)
|
GetLines = function(self)
|
||||||
return self.lines
|
return self.lines
|
||||||
end,
|
end,
|
||||||
@@ -717,14 +924,12 @@ detailsFramework.ChartFrameMixin = {
|
|||||||
---@param self df_chart
|
---@param self df_chart
|
||||||
---@param yPointScale number|nil
|
---@param yPointScale number|nil
|
||||||
---@param bUpdateLabels boolean|nil
|
---@param bUpdateLabels boolean|nil
|
||||||
Plot = function(self, yPointScale, bUpdateLabels)
|
Plot = function(self, yPointScale, bUpdateLabels, lineId)
|
||||||
--debug
|
lineId = lineId or 1
|
||||||
--self:SetData({38, 26, 12, 63, 100, 96, 42, 94, 25, 75, 61, 54, 71, 40, 34, 100, 66, 90, 39, 13, 99, 18, 72, 18, 83, 45, 56, 24, 33, 85, 95, 71, 15, 66, 19, 58, 52, 9, 83, 99, 100, 4, 3, 56, 6, 80, 94, 7, 40, 55, 98, 92, 20, 9, 35, 89, 72, 7, 13, 81, 29, 78, 55, 70, 12, 33, 39, 3, 84, 31, 10, 53, 51, 69, 66, 58, 71, 60, 31, 71, 27, 76, 21, 75, 15, 89, 2, 81, 72, 78, 74, 80, 97, 10, 59, 0, 31, 5, 1, 82, 71, 89, 78, 94, 74, 20, 65, 72, 56, 40, 92, 91, 40, 79, 4, 56, 18, 88, 88, 20, 20, 10, 47, 26, 80, 26, 75, 21, 57, 10, 67, 66, 84, 83, 14, 47, 83, 9, 7, 73, 63, 32, 64, 20, 40, 3, 46, 54, 17, 37, 82, 66, 65, 22, 12, 1, 100, 41, 1, 72, 38, 41, 71, 69, 88, 34, 10, 50, 9, 25, 19, 27, 3, 13, 40, 75, 3, 11, 93, 58, 81, 80, 93, 25, 74, 68, 91, 87, 79, 48, 66, 53, 64, 18, 51, 19, 32, 4, 21, 43})
|
|
||||||
|
|
||||||
self:UpdateFrameSizeCache()
|
self:UpdateFrameSizeCache()
|
||||||
|
|
||||||
--max amount of data is the max amount of point the chart will have
|
--max amount of data is the max amount of point the chart will have
|
||||||
local maxLines = self:GetDataSize()
|
local dataSize = self:GetDataSize()
|
||||||
|
|
||||||
--calculate where the first point height will be
|
--calculate where the first point height will be
|
||||||
local firstValue = self:GetDataFirstValue()
|
local firstValue = self:GetDataFirstValue()
|
||||||
@@ -739,29 +944,29 @@ detailsFramework.ChartFrameMixin = {
|
|||||||
|
|
||||||
self:ResetDataIndex()
|
self:ResetDataIndex()
|
||||||
|
|
||||||
print(maxLines)
|
local r, g, b = unpack(self.color)
|
||||||
|
|
||||||
for i = 1, maxLines do
|
local bFillChart, fillLineThickness = self:GetFillState()
|
||||||
local line = self:GetLine()
|
|
||||||
|
|
||||||
line:SetTexture(unpack(self.color))
|
local payload = {
|
||||||
|
executionsPerFrame = 50,
|
||||||
|
self = self,
|
||||||
|
currentDataIndex = 1,
|
||||||
|
dataSize = dataSize,
|
||||||
|
currentXPoint = currentXPoint,
|
||||||
|
currentYPoint = currentYPoint,
|
||||||
|
eachLineWidth = eachLineWidth,
|
||||||
|
plotFrameHeightScaled = plotFrameHeightScaled,
|
||||||
|
r = r,
|
||||||
|
g = g,
|
||||||
|
b = b,
|
||||||
|
lineId = lineId,
|
||||||
|
bUpdateLabels = bUpdateLabels,
|
||||||
|
bFillChart = bFillChart,
|
||||||
|
fillLineThickness = fillLineThickness,
|
||||||
|
}
|
||||||
|
|
||||||
if (line.thickness ~= self.lineThickness) then
|
detailsFramework.Schedules.LazyExecute(lazyChartUpdate, payload)
|
||||||
line:SetThickness(self.lineThickness)
|
|
||||||
line.thickness = self.lineThickness
|
|
||||||
end
|
|
||||||
|
|
||||||
--the start point starts where the latest point finished
|
|
||||||
line:SetStartPoint("bottomleft", currentXPoint, currentYPoint)
|
|
||||||
|
|
||||||
--move x
|
|
||||||
currentXPoint = currentXPoint + eachLineWidth
|
|
||||||
|
|
||||||
--end point
|
|
||||||
local value = self:GetDataNextValue()
|
|
||||||
currentYPoint = self:CalcYAxisPointForValue(value, plotFrameHeightScaled)
|
|
||||||
line:SetEndPoint("bottomleft", currentXPoint, currentYPoint)
|
|
||||||
end
|
|
||||||
|
|
||||||
self:ShowBackdropIndicators()
|
self:ShowBackdropIndicators()
|
||||||
|
|
||||||
@@ -771,6 +976,198 @@ detailsFramework.ChartFrameMixin = {
|
|||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--https://en.wikipedia.org/wiki/Local_regression
|
||||||
|
local calcLOESS = function(data, span, mainFrame, chartFrame)
|
||||||
|
local lazyLOESSUpdate = function(payload, iterationCount, maxIterations)
|
||||||
|
local data = payload.data
|
||||||
|
local span = payload.span
|
||||||
|
local lastDataIndex = payload.lastDataIndex
|
||||||
|
local result = payload.result
|
||||||
|
local halfSpan = payload.halfSpan
|
||||||
|
local sumTotal = payload.sumTotal
|
||||||
|
|
||||||
|
local currentDataIndex = payload.currentDataIndex
|
||||||
|
payload.currentDataIndex = currentDataIndex + payload.executionsPerFrame
|
||||||
|
|
||||||
|
local max = math.max
|
||||||
|
local min = math.min
|
||||||
|
local abs = math.abs
|
||||||
|
local tinsert = table.insert
|
||||||
|
|
||||||
|
for i = currentDataIndex, currentDataIndex + payload.executionsPerFrame do
|
||||||
|
--define the local neighborhood
|
||||||
|
local neighborhood = {}
|
||||||
|
for o = max(1, i - halfSpan), min(lastDataIndex, i + halfSpan) do
|
||||||
|
tinsert(neighborhood, {x = o, y = data[o]})
|
||||||
|
end
|
||||||
|
|
||||||
|
sumTotal = sumTotal + data[i]
|
||||||
|
|
||||||
|
--calculate weights based on distance from target point
|
||||||
|
local weights = {}
|
||||||
|
for _, point in ipairs(neighborhood) do
|
||||||
|
local distance = abs(i - point.x)
|
||||||
|
local weight = (1 - (distance / (halfSpan + 1)) ^ 3) ^ 3
|
||||||
|
weights[point.x] = weight
|
||||||
|
end
|
||||||
|
|
||||||
|
--fit a weighted linear regression to the neighborhood
|
||||||
|
local sum_w = 0
|
||||||
|
local sum_wx = 0
|
||||||
|
local sum_wy = 0
|
||||||
|
local sum_wxx = 0
|
||||||
|
local sum_wxy = 0
|
||||||
|
|
||||||
|
for _, point in ipairs(neighborhood) do
|
||||||
|
local w = weights[point.x]
|
||||||
|
sum_w = sum_w + w
|
||||||
|
sum_wx = sum_wx + w * point.x
|
||||||
|
sum_wy = sum_wy + w * point.y
|
||||||
|
sum_wxx = sum_wxx + w * point.x * point.x
|
||||||
|
sum_wxy = sum_wxy + w * point.x * point.y
|
||||||
|
end
|
||||||
|
|
||||||
|
local denominator = sum_w * sum_wxx - sum_wx * sum_wx
|
||||||
|
local intercept = (sum_wy * sum_wxx - sum_wx * sum_wxy) / denominator
|
||||||
|
local slope = (sum_w * sum_wxy - sum_wx * sum_wy) / denominator
|
||||||
|
|
||||||
|
--predict the smoothed value at the target point
|
||||||
|
result[i] = max(0, intercept + slope * i)
|
||||||
|
|
||||||
|
--check if can finishe the execution
|
||||||
|
if (i == lastDataIndex) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
payload.sumTotal = sumTotal
|
||||||
|
end
|
||||||
|
|
||||||
|
local result = {}
|
||||||
|
local dataSize = #data
|
||||||
|
local halfSpan = math.floor(span / 2)
|
||||||
|
|
||||||
|
local payload = {
|
||||||
|
currentDataIndex = 1,
|
||||||
|
sumTotal = 0,
|
||||||
|
lastDataIndex = dataSize,
|
||||||
|
executionsPerFrame = 100,
|
||||||
|
data = data,
|
||||||
|
span = span,
|
||||||
|
result = result,
|
||||||
|
halfSpan = halfSpan,
|
||||||
|
}
|
||||||
|
|
||||||
|
---@type df_schedule
|
||||||
|
local schedules = detailsFramework.Schedules
|
||||||
|
|
||||||
|
local onEndLazyExecution = function(payload)
|
||||||
|
chartFrame:SetDataRaw(payload.result)
|
||||||
|
|
||||||
|
chartFrame.average = payload.sumTotal / dataSize
|
||||||
|
|
||||||
|
local minValue, maxValue = chartFrame:GetDataMinMaxValues()
|
||||||
|
chartFrame:SetMinMaxValues(minValue, maxValue)
|
||||||
|
--clear the lines
|
||||||
|
chartFrame:HideLines()
|
||||||
|
mainFrame:SetBackgroundProcessState(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
mainFrame:SetBackgroundProcessState(true)
|
||||||
|
schedules.LazyExecute(lazyLOESSUpdate, payload, 999, onEndLazyExecution)
|
||||||
|
end
|
||||||
|
|
||||||
|
--simple moving average
|
||||||
|
---@param data table
|
||||||
|
---@param averageSize number
|
||||||
|
---@param mainFrame df_chartmulti
|
||||||
|
---@param chartFrame df_chart
|
||||||
|
---@param bAddZeroPadding boolean?
|
||||||
|
local calcSMA = function(data, averageSize, mainFrame, chartFrame, bAddZeroPadding)
|
||||||
|
if (bAddZeroPadding) then
|
||||||
|
--fill the start of the data with zeros
|
||||||
|
for i = 1, averageSize - 1 do
|
||||||
|
--insert at index 1 a zero
|
||||||
|
table.insert(data, 1, 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local lazySMAUpdate = function(payload, iterationCount, maxIterations)
|
||||||
|
local averageSize = payload.averageSize
|
||||||
|
local result = payload.result
|
||||||
|
local data = payload.data
|
||||||
|
local lastDataIndex = payload.lastDataIndex
|
||||||
|
local sum = payload.sum
|
||||||
|
local sumTotal = payload.sumTotal
|
||||||
|
local bAddZeroPadding = payload.bAddZeroPadding
|
||||||
|
|
||||||
|
local currentDataIndex = payload.currentDataIndex
|
||||||
|
payload.currentDataIndex = currentDataIndex + payload.executionsPerFrame
|
||||||
|
|
||||||
|
local tinsert = table.insert
|
||||||
|
|
||||||
|
for i = currentDataIndex, currentDataIndex + payload.executionsPerFrame do
|
||||||
|
sum = sum + data[i]
|
||||||
|
sumTotal = sumTotal + data[i]
|
||||||
|
if (i >= averageSize) then
|
||||||
|
if (i > averageSize) then
|
||||||
|
sum = sum - data[i - averageSize]
|
||||||
|
end
|
||||||
|
tinsert(result, max(0, sum / averageSize))
|
||||||
|
end
|
||||||
|
|
||||||
|
--check if can finishe the execution
|
||||||
|
if (i == lastDataIndex) then
|
||||||
|
if (bAddZeroPadding) then
|
||||||
|
--remove from the data the zeros added at the start
|
||||||
|
for o = 1, averageSize - 1 do
|
||||||
|
--remove from the data the zero added at the first index
|
||||||
|
table.remove(data, 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
payload.sumTotal = sumTotal
|
||||||
|
payload.sum = sum
|
||||||
|
end
|
||||||
|
|
||||||
|
--return result
|
||||||
|
local result = {}
|
||||||
|
local dataSize = #data
|
||||||
|
|
||||||
|
local payload = {
|
||||||
|
sum = 0,
|
||||||
|
sumTotal = 0,
|
||||||
|
currentDataIndex = 1,
|
||||||
|
lastDataIndex = dataSize,
|
||||||
|
executionsPerFrame = 300,
|
||||||
|
data = data,
|
||||||
|
result = result,
|
||||||
|
averageSize = averageSize,
|
||||||
|
bAddZeroPadding = bAddZeroPadding,
|
||||||
|
}
|
||||||
|
|
||||||
|
---@type df_schedule
|
||||||
|
local schedules = detailsFramework.Schedules
|
||||||
|
|
||||||
|
local onEndLazyExecution = function(payload)
|
||||||
|
chartFrame:SetDataRaw(payload.result)
|
||||||
|
|
||||||
|
chartFrame.average = payload.sumTotal / dataSize
|
||||||
|
|
||||||
|
local minValue, maxValue = chartFrame:GetDataMinMaxValues()
|
||||||
|
chartFrame:SetMinMaxValues(minValue, maxValue)
|
||||||
|
--clear the lines
|
||||||
|
chartFrame:HideLines()
|
||||||
|
mainFrame:SetBackgroundProcessState(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
mainFrame:SetBackgroundProcessState(true)
|
||||||
|
schedules.LazyExecute(lazySMAUpdate, payload, 999, onEndLazyExecution)
|
||||||
|
end
|
||||||
|
|
||||||
---create a chart frame object
|
---create a chart frame object
|
||||||
---@param parent frame
|
---@param parent frame
|
||||||
---@param name string|nil
|
---@param name string|nil
|
||||||
@@ -788,41 +1185,31 @@ local createChartFrame = function(parent, name)
|
|||||||
chartFrame:ValueConstructor()
|
chartFrame:ValueConstructor()
|
||||||
chartFrame:ChartFrameConstructor()
|
chartFrame:ChartFrameConstructor()
|
||||||
|
|
||||||
--when a new data is set, update the min and max values
|
--when a new data is set, starting an background process to smooth the data
|
||||||
local onSetDataCallback = function(data, smoothnessLevel)
|
local onSetDataCallback = function(data, payload)
|
||||||
local newData = {}
|
local smoothnessMethod = payload.smoothnessMethod or ""
|
||||||
|
local smoothnessLevel = payload.smoothnessLevel
|
||||||
|
local mainFrame = payload.mainFrame
|
||||||
|
|
||||||
smoothnessLevel = smoothnessLevel or 0
|
smoothnessLevel = smoothnessLevel or 0
|
||||||
|
smoothnessMethod = string.lower(smoothnessMethod)
|
||||||
|
|
||||||
if (smoothnessLevel > 0) then
|
if (smoothnessMethod == "loess") then
|
||||||
smoothnessLevel = smoothnessLevel + 2
|
calcLOESS(data, smoothnessLevel, mainFrame, chartFrame)
|
||||||
|
|
||||||
for i = 1, #data do
|
elseif (smoothnessMethod == "sma") then
|
||||||
local thisValue = 0
|
calcSMA(data, smoothnessLevel, mainFrame, chartFrame)
|
||||||
local amountDataAdded = 0
|
|
||||||
|
|
||||||
--calculate the sum within the window
|
elseif (smoothnessMethod == "smaz") then
|
||||||
for o = i - math.floor(smoothnessLevel / 2), i + math.floor(smoothnessLevel / 2) do
|
local bAddZeroPadding = true
|
||||||
if o >= 1 and o <= #data then
|
calcSMA(data, smoothnessLevel, mainFrame, chartFrame, bAddZeroPadding)
|
||||||
thisValue = thisValue + data[o]
|
|
||||||
amountDataAdded = amountDataAdded + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--calculate the average and store in the smoothedData value
|
|
||||||
local average = thisValue / amountDataAdded
|
|
||||||
table.insert(newData, average)
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
newData = data
|
chartFrame:SetDataRaw(data)
|
||||||
|
local minValue, maxValue = chartFrame:GetDataMinMaxValues()
|
||||||
|
chartFrame:SetMinMaxValues(minValue, maxValue)
|
||||||
|
--clear the lines
|
||||||
|
chartFrame:HideLines()
|
||||||
end
|
end
|
||||||
|
|
||||||
chartFrame:SetDataRaw(newData)
|
|
||||||
|
|
||||||
local minValue, maxValue = chartFrame:GetDataMinMaxValues()
|
|
||||||
chartFrame:SetMinMaxValues(minValue, maxValue)
|
|
||||||
--clear the lines
|
|
||||||
chartFrame:HideLines()
|
|
||||||
end
|
end
|
||||||
chartFrame:AddDataChangeCallback(onSetDataCallback)
|
chartFrame:AddDataChangeCallback(onSetDataCallback)
|
||||||
|
|
||||||
@@ -831,13 +1218,6 @@ local createChartFrame = function(parent, name)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function detailsFramework:CreateGraphicLineFrame(parent, name)
|
|
||||||
---@type df_chart
|
|
||||||
local newGraphicFrame = createChartFrame(parent, name)
|
|
||||||
return newGraphicFrame
|
|
||||||
end
|
|
||||||
|
|
||||||
detailsFramework.MultiChartFrameMixin = {
|
detailsFramework.MultiChartFrameMixin = {
|
||||||
MultiChartFrameConstructor = function(self)
|
MultiChartFrameConstructor = function(self)
|
||||||
self.nextChartselframe = 1
|
self.nextChartselframe = 1
|
||||||
@@ -846,6 +1226,7 @@ detailsFramework.MultiChartFrameMixin = {
|
|||||||
self.nextChartFrame = 1
|
self.nextChartFrame = 1
|
||||||
self.chartFrames = {}
|
self.chartFrames = {}
|
||||||
self.lineNameIndicators = {}
|
self.lineNameIndicators = {}
|
||||||
|
self.amountOfBackgroundProcess = 0
|
||||||
|
|
||||||
chartFrameSharedConstructor(self)
|
chartFrameSharedConstructor(self)
|
||||||
end,
|
end,
|
||||||
@@ -857,27 +1238,29 @@ detailsFramework.MultiChartFrameMixin = {
|
|||||||
---add a new chart data and create a new chart frame if necessary to the multi chart
|
---add a new chart data and create a new chart frame if necessary to the multi chart
|
||||||
---@param self df_chartmulti
|
---@param self df_chartmulti
|
||||||
---@param data table
|
---@param data table
|
||||||
|
---@param smoothingMethod string|nil
|
||||||
---@param smoothnessLevel number|nil
|
---@param smoothnessLevel number|nil
|
||||||
---@param name string|nil
|
---@param name string|nil
|
||||||
---@param red any
|
---@param red any
|
||||||
---@param green number|nil
|
---@param green number|nil
|
||||||
---@param blue number|nil
|
---@param blue number|nil
|
||||||
---@param alpha number|nil
|
---@param alpha number|nil
|
||||||
AddData = function(self, data, smoothnessLevel, name, red, green, blue, alpha)
|
AddData = function(self, data, smoothingMethod, smoothnessLevel, name, red, green, blue, alpha)
|
||||||
assert(type(data) == "table", "MultiChartFrame:AddData() usage: AddData(table)")
|
assert(type(data) == "table", "MultiChartFrame:AddData() usage: AddData(table)")
|
||||||
local chartFrame = self:GetChart()
|
local chartFrame = self:GetChart()
|
||||||
|
|
||||||
red, green, blue, alpha = detailsFramework:ParseColors(red, green, blue, alpha)
|
red, green, blue, alpha = detailsFramework:ParseColors(red, green, blue, alpha)
|
||||||
chartFrame:SetColor(red, green, blue, alpha)
|
chartFrame:SetColor(red, green, blue, alpha)
|
||||||
chartFrame:SetData(data, smoothnessLevel)
|
|
||||||
|
|
||||||
chartFrame.chartName = name or ""
|
chartFrame.chartName = name or ""
|
||||||
|
|
||||||
self:SetMaxValueIfBigger(chartFrame:GetMaxValue())
|
local payload = {
|
||||||
self:SetMinValueIfLower(chartFrame:GetMinValue())
|
smoothnessMethod = smoothingMethod or "sma",
|
||||||
|
smoothnessLevel = smoothnessLevel or 3,
|
||||||
|
mainFrame = self,
|
||||||
|
}
|
||||||
|
|
||||||
local dataAmount = chartFrame:GetDataSize()
|
--setting the data will start a background process to smooth the data
|
||||||
self:SetMaxDataSize(dataAmount)
|
chartFrame:SetData(data, payload)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
---internally handle next line
|
---internally handle next line
|
||||||
@@ -1023,14 +1406,58 @@ detailsFramework.MultiChartFrameMixin = {
|
|||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
---@param self df_chartmulti
|
||||||
|
WaitForBackgroundProcess = function(self)
|
||||||
|
--start a ticker to check if the background process is done
|
||||||
|
if (not self.waitForBackgroundProcessTicker) then
|
||||||
|
self.waitForBackgroundProcessTicker = C_Timer.NewTicker(0.1, function()
|
||||||
|
if (not self:HasBackgroundProcess()) then
|
||||||
|
self.waitForBackgroundProcessTicker:Cancel()
|
||||||
|
self.waitForBackgroundProcessTicker = nil
|
||||||
|
self:Plot()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
---draw all the charts added to the multi chart frame
|
---draw all the charts added to the multi chart frame
|
||||||
---@param multiChartFrame df_chartmulti
|
---@param multiChartFrame df_chartmulti
|
||||||
Plot = function(multiChartFrame)
|
Plot = function(multiChartFrame)
|
||||||
|
--check if there is a background process ongoing
|
||||||
|
if (multiChartFrame:HasBackgroundProcess()) then
|
||||||
|
multiChartFrame:WaitForBackgroundProcess()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local allCharts = multiChartFrame:GetCharts()
|
||||||
|
local bFillChart, fillLineThickness = multiChartFrame:GetFillState()
|
||||||
|
---@type table<number, {average: number, chartIndex: number}>
|
||||||
|
local biggestAverage = {}
|
||||||
|
|
||||||
|
--set the min/max values of the multi chart frame
|
||||||
|
for i = 1, multiChartFrame:GetAmountCharts() do
|
||||||
|
local chartFrame = allCharts[i]
|
||||||
|
multiChartFrame:SetMaxValueIfBigger(chartFrame:GetMaxValue())
|
||||||
|
multiChartFrame:SetMinValueIfLower(chartFrame:GetMinValue())
|
||||||
|
|
||||||
|
local dataAmount = chartFrame:GetDataSize()
|
||||||
|
multiChartFrame:SetMaxDataSize(dataAmount)
|
||||||
|
|
||||||
|
if (bFillChart) then
|
||||||
|
chartFrame:SetFillChart(true, fillLineThickness)
|
||||||
|
end
|
||||||
|
|
||||||
|
--get the average of this chart
|
||||||
|
biggestAverage[i] = {average = chartFrame.average, chartIndex = i}
|
||||||
|
end
|
||||||
|
|
||||||
|
--sort the averages by the biggest average placing the biggest average in the first position
|
||||||
|
table.sort(biggestAverage, function(a, b) return a.average > b.average end)
|
||||||
|
|
||||||
local minValue, multiChartMaxValue = multiChartFrame:GetMinMaxValues()
|
local minValue, multiChartMaxValue = multiChartFrame:GetMinMaxValues()
|
||||||
local plotAreaWidth = multiChartFrame.plotFrame:GetWidth() --if there's no axis, the plotFrame has no width
|
local plotAreaWidth = multiChartFrame.plotFrame:GetWidth() --if there's no axis, the plotFrame has no width
|
||||||
local maxDataSize = multiChartFrame:GetMaxDataSize() --it's not clearing when a new boss is selected
|
local maxDataSize = multiChartFrame:GetMaxDataSize() --it's not clearing when a new boss is selected
|
||||||
local eachLineWidth = plotAreaWidth / maxDataSize
|
local eachLineWidth = plotAreaWidth / maxDataSize
|
||||||
local allCharts = multiChartFrame:GetCharts()
|
|
||||||
|
|
||||||
for i = 1, multiChartFrame:GetAmountCharts() do
|
for i = 1, multiChartFrame:GetAmountCharts() do
|
||||||
local chartFrame = allCharts[i]
|
local chartFrame = allCharts[i]
|
||||||
@@ -1043,11 +1470,19 @@ detailsFramework.MultiChartFrameMixin = {
|
|||||||
chartFrame:SetLineThickness(multiChartFrame.lineThickness)
|
chartFrame:SetLineThickness(multiChartFrame.lineThickness)
|
||||||
chartFrame:SetLineWidth(eachLineWidth)
|
chartFrame:SetLineWidth(eachLineWidth)
|
||||||
|
|
||||||
|
for o = 1, #biggestAverage do
|
||||||
|
local thisAverageTable = biggestAverage[o]
|
||||||
|
if (thisAverageTable.chartIndex == i) then
|
||||||
|
chartFrame.depth = o
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--get the percentage of how small this data is compared to the biggest data
|
--get the percentage of how small this data is compared to the biggest data
|
||||||
--this percentage is then used to scale down the to fit correctly the fontStrings showing the value metrics
|
--this percentage is then used to scale down the to fit correctly the fontStrings showing the value metrics
|
||||||
local yPointScale = chartFrame.maxValue / multiChartMaxValue
|
local yPointScale = chartFrame.maxValue / multiChartMaxValue
|
||||||
local bUpdateLabels = false
|
local bUpdateLabels = false
|
||||||
chartFrame:Plot(yPointScale, bUpdateLabels)
|
chartFrame:Plot(yPointScale, bUpdateLabels, i)
|
||||||
end
|
end
|
||||||
|
|
||||||
multiChartFrame:ShowBackdropIndicators()
|
multiChartFrame:ShowBackdropIndicators()
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
local dversion = 556
|
local dversion = 557
|
||||||
local major, minor = "DetailsFramework-1.0", dversion
|
local major, minor = "DetailsFramework-1.0", dversion
|
||||||
local DF, oldminor = LibStub:NewLibrary(major, minor)
|
local DF, oldminor = LibStub:NewLibrary(major, minor)
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -474,7 +474,7 @@ detailsFramework.SortFunctions = {
|
|||||||
---@field GetDataMinMaxValueFromSubTable fun(self: df_data, key: string) : number, number when data uses sub tables, get the min max values from a specific index or key, if the value stored is number, return the min and max values
|
---@field GetDataMinMaxValueFromSubTable fun(self: df_data, key: string) : number, number when data uses sub tables, get the min max values from a specific index or key, if the value stored is number, return the min and max values
|
||||||
---@field SetData fun(self: df_data, data: table, anyValue: any)
|
---@field SetData fun(self: df_data, data: table, anyValue: any)
|
||||||
---@field SetDataRaw fun(self: df_data, data: table) set the data without triggering callback
|
---@field SetDataRaw fun(self: df_data, data: table) set the data without triggering callback
|
||||||
---@field GetDataNextValue fun(self: df_data) : any
|
---@field GetDataNextValue fun(self: df_data) : any, number get the next value from the data table, return the value and the index
|
||||||
---@field ResetDataIndex fun(self: df_data)
|
---@field ResetDataIndex fun(self: df_data)
|
||||||
|
|
||||||
---mixin to use with DetailsFramework:Mixin(table, detailsFramework.DataMixin)
|
---mixin to use with DetailsFramework:Mixin(table, detailsFramework.DataMixin)
|
||||||
@@ -543,11 +543,12 @@ detailsFramework.DataMixin = {
|
|||||||
---get the next value from the data table
|
---get the next value from the data table
|
||||||
---@param self table
|
---@param self table
|
||||||
---@return any
|
---@return any
|
||||||
|
---@return number
|
||||||
GetDataNextValue = function(self)
|
GetDataNextValue = function(self)
|
||||||
local currentValue = self._dataInfo.dataCurrentIndex
|
local currentValue = self._dataInfo.dataCurrentIndex
|
||||||
local value = self:GetData()[currentValue]
|
local value = self:GetData()[currentValue]
|
||||||
self._dataInfo.dataCurrentIndex = self._dataInfo.dataCurrentIndex + 1
|
self._dataInfo.dataCurrentIndex = self._dataInfo.dataCurrentIndex + 1
|
||||||
return value
|
return value, currentValue
|
||||||
end,
|
end,
|
||||||
|
|
||||||
---reset the data index, making GetDataNextValue() return the first value again
|
---reset the data index, making GetDataNextValue() return the first value again
|
||||||
|
|||||||
@@ -25,17 +25,20 @@ function mythicDungeonCharts.ShowChart()
|
|||||||
mythicDungeonCharts.Frame = CreateFrame("frame", "DetailsMythicDungeonChartFrame", UIParent, "BackdropTemplate")
|
mythicDungeonCharts.Frame = CreateFrame("frame", "DetailsMythicDungeonChartFrame", UIParent, "BackdropTemplate")
|
||||||
local dungeonChartFrame = mythicDungeonCharts.Frame
|
local dungeonChartFrame = mythicDungeonCharts.Frame
|
||||||
|
|
||||||
dungeonChartFrame:SetSize(1200, 620)
|
--get the screen width
|
||||||
dungeonChartFrame:SetPoint("center", UIParent, "center", 0, 0)
|
local screenWidth = GetScreenWidth()
|
||||||
|
|
||||||
|
dungeonChartFrame:SetSize(screenWidth - 200, 400)
|
||||||
|
dungeonChartFrame:SetPoint("center", UIParent, "center", 0, 200)
|
||||||
dungeonChartFrame:SetFrameStrata("DIALOG")
|
dungeonChartFrame:SetFrameStrata("DIALOG")
|
||||||
dungeonChartFrame:EnableMouse(true)
|
dungeonChartFrame:EnableMouse(true)
|
||||||
dungeonChartFrame:SetMovable(true)
|
dungeonChartFrame:SetMovable(true)
|
||||||
detailsFramework:ApplyStandardBackdrop(dungeonChartFrame)
|
detailsFramework:ApplyStandardBackdrop(dungeonChartFrame)
|
||||||
|
dungeonChartFrame.__background:SetAlpha(0.834)
|
||||||
|
|
||||||
--minimized frame
|
--minimized frame
|
||||||
mythicDungeonCharts.FrameMinimized = CreateFrame("frame", "DetailsMythicDungeonChartFrameminimized", UIParent, "BackdropTemplate")
|
mythicDungeonCharts.FrameMinimized = CreateFrame("frame", "DetailsMythicDungeonChartFrameminimized", UIParent, "BackdropTemplate")
|
||||||
local fMinimized = mythicDungeonCharts.FrameMinimized
|
local fMinimized = mythicDungeonCharts.FrameMinimized
|
||||||
|
|
||||||
fMinimized:SetSize(160, 24)
|
fMinimized:SetSize(160, 24)
|
||||||
fMinimized:SetPoint("center", UIParent, "center", 0, 0)
|
fMinimized:SetPoint("center", UIParent, "center", 0, 0)
|
||||||
fMinimized:SetFrameStrata("LOW")
|
fMinimized:SetFrameStrata("LOW")
|
||||||
@@ -90,44 +93,17 @@ function mythicDungeonCharts.ShowChart()
|
|||||||
LibWindow.MakeDraggable(fMinimized)
|
LibWindow.MakeDraggable(fMinimized)
|
||||||
LibWindow.SavePosition(fMinimized)
|
LibWindow.SavePosition(fMinimized)
|
||||||
|
|
||||||
dungeonChartFrame.ChartFrame = detailsFramework:CreateChartPanel(dungeonChartFrame, 1200, 600, "DetailsMythicDungeonChartGraphicFrame")
|
local chartFrame = detailsFramework:CreateGraphicMultiLineFrame(dungeonChartFrame, "DetailsMythicDungeonChartGraphicFrame")
|
||||||
dungeonChartFrame.ChartFrame:SetPoint("topleft", dungeonChartFrame, "topleft", 5, -20)
|
chartFrame:SetPoint("topleft", dungeonChartFrame, "topleft", 1, -20)
|
||||||
|
chartFrame:SetSize(dungeonChartFrame:GetWidth(), dungeonChartFrame:GetHeight() - 20)
|
||||||
dungeonChartFrame.ChartFrame.FrameInUse = {}
|
chartFrame:EnableMouse(false)
|
||||||
dungeonChartFrame.ChartFrame.FrameFree = {}
|
|
||||||
dungeonChartFrame.ChartFrame.TextureID = 1
|
|
||||||
|
|
||||||
dungeonChartFrame.ChartFrame.ShowHeader = true
|
|
||||||
dungeonChartFrame.ChartFrame.HeaderOnlyIndicator = true
|
|
||||||
dungeonChartFrame.ChartFrame.HeaderShowOverlays = false
|
|
||||||
|
|
||||||
dungeonChartFrame.ChartFrame.Graphic.DrawLine = mythicDungeonCharts.CustomDrawLine
|
|
||||||
|
|
||||||
dungeonChartFrame.ChartFrame:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
|
||||||
dungeonChartFrame.ChartFrame:SetBackdropColor(0, 0, 0, 0.0)
|
|
||||||
dungeonChartFrame.ChartFrame:SetBackdropBorderColor(0, 0, 0, 0)
|
|
||||||
|
|
||||||
dungeonChartFrame.ChartFrame:EnableMouse(false)
|
|
||||||
|
|
||||||
dungeonChartFrame.ChartFrame.CloseButton:Hide()
|
|
||||||
|
|
||||||
dungeonChartFrame.BossWidgetsFrame = CreateFrame("frame", "$parentBossFrames", dungeonChartFrame, "BackdropTemplate")
|
|
||||||
dungeonChartFrame.BossWidgetsFrame:SetFrameLevel(dungeonChartFrame:GetFrameLevel()+10)
|
|
||||||
dungeonChartFrame.BossWidgetsFrame.Widgets = {}
|
|
||||||
|
|
||||||
dungeonChartFrame.BossWidgetsFrame.GraphPin = dungeonChartFrame.BossWidgetsFrame:CreateTexture(nil, "overlay")
|
|
||||||
dungeonChartFrame.BossWidgetsFrame.GraphPin:SetTexture([[Interface\BUTTONS\UI-RadioButton]])
|
|
||||||
dungeonChartFrame.BossWidgetsFrame.GraphPin:SetTexCoord(17/64, 32/64, 0, 1)
|
|
||||||
dungeonChartFrame.BossWidgetsFrame.GraphPin:SetSize(16, 16)
|
|
||||||
|
|
||||||
dungeonChartFrame.BossWidgetsFrame.GraphPinGlow = dungeonChartFrame.BossWidgetsFrame:CreateTexture(nil, "artwork")
|
|
||||||
dungeonChartFrame.BossWidgetsFrame.GraphPinGlow:SetTexture([[Interface\Calendar\EventNotificationGlow]])
|
|
||||||
dungeonChartFrame.BossWidgetsFrame.GraphPinGlow:SetTexCoord(0, 1, 0, 1)
|
|
||||||
dungeonChartFrame.BossWidgetsFrame.GraphPinGlow:SetSize(14, 14)
|
|
||||||
dungeonChartFrame.BossWidgetsFrame.GraphPinGlow:SetBlendMode("ADD")
|
|
||||||
dungeonChartFrame.BossWidgetsFrame.GraphPinGlow:SetPoint("center", dungeonChartFrame.BossWidgetsFrame.GraphPin, "center", 0, 0)
|
|
||||||
|
|
||||||
dungeonChartFrame:Hide()
|
dungeonChartFrame:Hide()
|
||||||
|
dungeonChartFrame.ChartFrame = chartFrame
|
||||||
|
|
||||||
|
local red, green, blue, opacity = 1, 1, 1, 1
|
||||||
|
chartFrame:CreateAxesLines(48, 20, "left", 1, 10, 10, red, green, blue, opacity)
|
||||||
|
chartFrame:SetXAxisDataType("time")
|
||||||
|
chartFrame:SetLineThickness(2)
|
||||||
|
|
||||||
function dungeonChartFrame.ShowChartFrame()
|
function dungeonChartFrame.ShowChartFrame()
|
||||||
if (dungeonChartFrame.IsMinimized) then
|
if (dungeonChartFrame.IsMinimized) then
|
||||||
@@ -139,150 +115,18 @@ function mythicDungeonCharts.ShowChart()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local closeButton = CreateFrame("button", "$parentCloseButton", dungeonChartFrame, "UIPanelCloseButton")
|
mythicDungeonCharts.CreateCloseMinimizeButtons(dungeonChartFrame)
|
||||||
closeButton:GetNormalTexture():SetDesaturated(true)
|
mythicDungeonCharts.CreateBossWidgets(dungeonChartFrame)
|
||||||
closeButton:SetWidth(24)
|
end --finished created the chart frame
|
||||||
closeButton:SetHeight(24)
|
|
||||||
closeButton:SetPoint("topright", dungeonChartFrame, "topright", 0, -1)
|
|
||||||
closeButton:SetFrameLevel(dungeonChartFrame:GetFrameLevel()+16)
|
|
||||||
|
|
||||||
local minimizeButton = CreateFrame("button", "$parentCloseButton", dungeonChartFrame, "UIPanelCloseButton")
|
local dungeonChartFrame = mythicDungeonCharts.Frame
|
||||||
minimizeButton:GetNormalTexture():SetDesaturated(true)
|
|
||||||
minimizeButton:SetWidth(24)
|
|
||||||
minimizeButton:SetHeight(24)
|
|
||||||
minimizeButton:SetPoint("right", closeButton, "left", 2, 0)
|
|
||||||
minimizeButton:SetFrameLevel(dungeonChartFrame:GetFrameLevel()+16)
|
|
||||||
minimizeButton:SetNormalTexture([[Interface\BUTTONS\UI-Panel-HideButton-Up]])
|
|
||||||
minimizeButton:SetPushedTexture([[Interface\BUTTONS\UI-Panel-HideButton-Down]])
|
|
||||||
minimizeButton:SetHighlightTexture([[Interface\BUTTONS\UI-Panel-MinimizeButton-Highlight]])
|
|
||||||
|
|
||||||
local closeButtonWhenMinimized = CreateFrame("button", "$parentCloseButton", fMinimized, "UIPanelCloseButton")
|
---@type df_chartmulti
|
||||||
closeButtonWhenMinimized:GetNormalTexture():SetDesaturated(true)
|
local chartFrame = dungeonChartFrame.ChartFrame
|
||||||
closeButtonWhenMinimized:SetWidth(24)
|
|
||||||
closeButtonWhenMinimized:SetHeight(24)
|
|
||||||
closeButtonWhenMinimized:SetPoint("topright", fMinimized, "topright", 0, -1)
|
|
||||||
closeButtonWhenMinimized:SetFrameLevel(fMinimized:GetFrameLevel()+16)
|
|
||||||
|
|
||||||
local minimizeButtonWhenMinimized = CreateFrame("button", "$parentCloseButton", fMinimized, "UIPanelCloseButton")
|
chartFrame:Reset()
|
||||||
minimizeButtonWhenMinimized:GetNormalTexture():SetDesaturated(true)
|
|
||||||
minimizeButtonWhenMinimized:SetWidth(24)
|
|
||||||
minimizeButtonWhenMinimized:SetHeight(24)
|
|
||||||
minimizeButtonWhenMinimized:SetPoint("right", closeButtonWhenMinimized, "left", 2, 0)
|
|
||||||
minimizeButtonWhenMinimized:SetFrameLevel(fMinimized:GetFrameLevel()+16)
|
|
||||||
minimizeButtonWhenMinimized:SetNormalTexture([[Interface\BUTTONS\UI-Panel-HideButton-Up]])
|
|
||||||
minimizeButtonWhenMinimized:SetPushedTexture([[Interface\BUTTONS\UI-Panel-HideButton-Down]])
|
|
||||||
minimizeButtonWhenMinimized:SetHighlightTexture([[Interface\BUTTONS\UI-Panel-MinimizeButton-Highlight]])
|
|
||||||
|
|
||||||
closeButtonWhenMinimized:SetScript("OnClick", function()
|
|
||||||
dungeonChartFrame.IsMinimized = false
|
|
||||||
fMinimized:Hide()
|
|
||||||
minimizeButtonWhenMinimized:SetNormalTexture([[Interface\BUTTONS\UI-Panel-HideButton-Up]])
|
|
||||||
minimizeButtonWhenMinimized:SetPushedTexture([[Interface\BUTTONS\UI-Panel-HideButton-Down]])
|
|
||||||
end)
|
|
||||||
|
|
||||||
--replace the default click function
|
|
||||||
local minimize_func = function(self)
|
|
||||||
if (dungeonChartFrame.IsMinimized) then
|
|
||||||
dungeonChartFrame.IsMinimized = false
|
|
||||||
fMinimized:Hide()
|
|
||||||
dungeonChartFrame:Show()
|
|
||||||
minimizeButtonWhenMinimized:SetNormalTexture([[Interface\BUTTONS\UI-Panel-HideButton-Up]])
|
|
||||||
minimizeButtonWhenMinimized:SetPushedTexture([[Interface\BUTTONS\UI-Panel-HideButton-Down]])
|
|
||||||
else
|
|
||||||
dungeonChartFrame.IsMinimized = true
|
|
||||||
dungeonChartFrame:Hide()
|
|
||||||
fMinimized:Show()
|
|
||||||
minimizeButtonWhenMinimized:SetNormalTexture([[Interface\BUTTONS\UI-Panel-CollapseButton-Up]])
|
|
||||||
minimizeButtonWhenMinimized:SetPushedTexture([[Interface\BUTTONS\UI-Panel-CollapseButton-Up]])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
minimizeButton:SetScript("OnClick", minimize_func)
|
|
||||||
minimizeButtonWhenMinimized:SetScript("OnClick", minimize_func)
|
|
||||||
|
|
||||||
--enabled box
|
|
||||||
-- /run _G.DetailsMythicDungeonChartHandler.ShowChart(); DetailsMythicDungeonChartFrame.ShowChartFrame()
|
|
||||||
local on_switch_enable = function(_, _, state)
|
|
||||||
Details.mythic_plus.show_damage_graphic = state
|
|
||||||
end
|
|
||||||
local enabledSwitch, enabledLabel = detailsFramework:CreateSwitch(dungeonChartFrame, on_switch_enable, Details.mythic_plus.show_damage_graphic, _, _, _, _, _, _, _, _, _, "Enabled", detailsFramework:GetTemplate("switch", "OPTIONS_CHECKBOX_BRIGHT_TEMPLATE"), "GameFontHighlightLeft")
|
|
||||||
enabledSwitch:SetAsCheckBox()
|
|
||||||
enabledSwitch.tooltip = "Show this chart at the end of a mythic dungeon run.\n\nIf disabled, you can reactivate it again at the options panel > streamer settings."
|
|
||||||
|
|
||||||
if (enabledLabel) then
|
|
||||||
enabledLabel:SetPoint("right", minimizeButton, "left", -22, 0)
|
|
||||||
enabledSwitch:SetSize(16, 16)
|
|
||||||
detailsFramework:SetFontColor(enabledLabel, "gray")
|
|
||||||
end
|
|
||||||
|
|
||||||
enabledSwitch.checked_texture:SetVertexColor(.75, .75, .75)
|
|
||||||
|
|
||||||
local leftDivisorLine = dungeonChartFrame.BossWidgetsFrame:CreateTexture(nil, "overlay")
|
|
||||||
leftDivisorLine:SetSize(2, dungeonChartFrame.ChartFrame.Graphic:GetHeight())
|
|
||||||
leftDivisorLine:SetTexture(1, 1, 1, 1)
|
|
||||||
leftDivisorLine:SetPoint("bottomleft", dungeonChartFrame.ChartFrame.Graphic.TextFrame, "bottomleft", -2, 0)
|
|
||||||
|
|
||||||
local bottomDivisorLine = dungeonChartFrame.BossWidgetsFrame:CreateTexture(nil, "overlay")
|
|
||||||
bottomDivisorLine:SetSize(dungeonChartFrame.ChartFrame.Graphic:GetWidth(), 2)
|
|
||||||
bottomDivisorLine:SetTexture(1, 1, 1, 1)
|
|
||||||
bottomDivisorLine:SetPoint("bottomleft", dungeonChartFrame.ChartFrame.Graphic.TextFrame, "bottomleft", 0, 0)
|
|
||||||
|
|
||||||
dungeonChartFrame.ChartFrame.Graphic:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
|
||||||
dungeonChartFrame.ChartFrame.Graphic:SetBackdropColor(.5, .50, .50, 0.8)
|
|
||||||
dungeonChartFrame.ChartFrame.Graphic:SetBackdropBorderColor(0, 0, 0, 0.5)
|
|
||||||
|
|
||||||
function dungeonChartFrame.ChartFrame.RefreshBossTimeline(self, bossTable, elapsedTime)
|
|
||||||
for i, bossTable in ipairs(mythicDungeonCharts.ChartTable.BossDefeated) do
|
|
||||||
local bossWidget = dungeonChartFrame.BossWidgetsFrame.Widgets [i]
|
|
||||||
|
|
||||||
if (not bossWidget) then
|
|
||||||
local newBossWidget = CreateFrame("frame", "$parentBossWidget" .. i, dungeonChartFrame.BossWidgetsFrame, "BackdropTemplate")
|
|
||||||
newBossWidget:SetSize(64, 32)
|
|
||||||
newBossWidget:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
|
||||||
newBossWidget:SetBackdropColor(0, 0, 0, 0.1)
|
|
||||||
newBossWidget:SetBackdropBorderColor(0, 0, 0, 0)
|
|
||||||
|
|
||||||
local bossAvatar = detailsFramework:CreateImage(newBossWidget, "", 64, 32, "border")
|
|
||||||
bossAvatar:SetPoint("bottomleft", newBossWidget, "bottomleft", 0, 0)
|
|
||||||
newBossWidget.AvatarTexture = bossAvatar
|
|
||||||
|
|
||||||
local verticalLine = Details:GetFramework():CreateImage(newBossWidget, "", 1, dungeonChartFrame.ChartFrame.Graphic:GetHeight(), "overlay")
|
|
||||||
verticalLine:SetTexture(1, 1, 1, 0.3)
|
|
||||||
verticalLine:SetPoint("bottomleft", newBossWidget, "bottomright", 0, 0)
|
|
||||||
|
|
||||||
local timeText = detailsFramework:CreateLabel(newBossWidget)
|
|
||||||
timeText:SetPoint("bottomright", newBossWidget, "bottomright", 0, 0)
|
|
||||||
newBossWidget.TimeText = timeText
|
|
||||||
|
|
||||||
local timeBackground = Details:GetFramework():CreateImage(newBossWidget, "", 30, 12, "artwork")
|
|
||||||
timeBackground:SetTexture(0, 0, 0, 0.5)
|
|
||||||
timeBackground:SetPoint("topleft", timeText, "topleft", -2, 2)
|
|
||||||
timeBackground:SetPoint("bottomright", timeText, "bottomright", 2, 0)
|
|
||||||
|
|
||||||
dungeonChartFrame.BossWidgetsFrame.Widgets [i] = newBossWidget
|
|
||||||
bossWidget = newBossWidget
|
|
||||||
end
|
|
||||||
|
|
||||||
local chartLength = dungeonChartFrame.ChartFrame.Graphic:GetWidth()
|
|
||||||
local secondsPerPixel = chartLength / elapsedTime
|
|
||||||
local xPosition = bossTable[1] * secondsPerPixel
|
|
||||||
|
|
||||||
bossWidget:SetPoint("bottomright", dungeonChartFrame.ChartFrame.Graphic, "bottomleft", xPosition, 0)
|
|
||||||
|
|
||||||
bossWidget.TimeText:SetText(detailsFramework:IntegerToTimer(bossTable[1]))
|
|
||||||
|
|
||||||
if (bossTable[2].bossimage) then
|
|
||||||
bossWidget.AvatarTexture:SetTexture(bossTable[2].bossimage)
|
|
||||||
else
|
|
||||||
local bossAvatar = Details:GetBossPortrait(nil, nil, bossTable[2].name, bossTable[2].ej_instance_id)
|
|
||||||
bossWidget.AvatarTexture:SetTexture(bossAvatar)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
mythicDungeonCharts.Frame.ChartFrame:Reset()
|
|
||||||
|
|
||||||
|
--check if there is a valid chart table
|
||||||
if (not mythicDungeonCharts.ChartTable) then
|
if (not mythicDungeonCharts.ChartTable) then
|
||||||
if (Details222.Debug.MythicPlusChartWindowDebug) then
|
if (Details222.Debug.MythicPlusChartWindowDebug) then
|
||||||
--development
|
--development
|
||||||
@@ -295,12 +139,12 @@ function mythicDungeonCharts.ShowChart()
|
|||||||
|
|
||||||
else
|
else
|
||||||
mythicDungeonCharts:Debug("no valid data and no saved data, canceling")
|
mythicDungeonCharts:Debug("no valid data and no saved data, canceling")
|
||||||
mythicDungeonCharts.Frame:Hide()
|
dungeonChartFrame:Hide()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
mythicDungeonCharts.Frame:Hide()
|
dungeonChartFrame:Hide()
|
||||||
mythicDungeonCharts:Debug("no data found, canceling")
|
mythicDungeonCharts:Debug("no data found, canceling")
|
||||||
|
|
||||||
if (verbosemode) then
|
if (verbosemode) then
|
||||||
@@ -315,9 +159,9 @@ function mythicDungeonCharts.ShowChart()
|
|||||||
|
|
||||||
mythicDungeonCharts.PlayerGraphIndex = {}
|
mythicDungeonCharts.PlayerGraphIndex = {}
|
||||||
|
|
||||||
|
--add the lines to the chart (one line per player)
|
||||||
for playerName, playerTable in pairs(charts) do
|
for playerName, playerTable in pairs(charts) do
|
||||||
local chartData = playerTable.ChartData
|
local chartData = playerTable.ChartData
|
||||||
local lineName = playerTable.Name
|
|
||||||
|
|
||||||
classDuplicated[playerTable.Class] = (classDuplicated[playerTable.Class] or 0) + 1
|
classDuplicated[playerTable.Class] = (classDuplicated[playerTable.Class] or 0) + 1
|
||||||
|
|
||||||
@@ -334,46 +178,51 @@ function mythicDungeonCharts.ShowChart()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local combatTime = mythicDungeonCharts.ChartTable.ElapsedTime
|
local combatTime = mythicDungeonCharts.ChartTable.ElapsedTime
|
||||||
local texture = "line"
|
|
||||||
|
|
||||||
--lowess smooth
|
local opacity = 1
|
||||||
--chartData = mythicDungeonCharts.LowessSmoothing (chartData, 75)
|
local smoothnessLevel = 50
|
||||||
chartData = mythicDungeonCharts.Frame.ChartFrame:CalcLowessSmoothing(chartData, 75)
|
local smoothnessLevel = 20
|
||||||
|
local smoothMethod = "loess"
|
||||||
|
local smoothMethod = "sma"
|
||||||
|
|
||||||
local maxValue = 0
|
local chartSize = #chartData
|
||||||
for i = 1, #chartData do
|
|
||||||
if (chartData [i] > maxValue) then
|
local shrinkBy = 1
|
||||||
maxValue = chartData[i]
|
if (chartSize >= 600) then
|
||||||
end
|
shrinkBy = math.max(2, math.floor(chartSize/400))
|
||||||
end
|
end
|
||||||
chartData.max_value = maxValue
|
|
||||||
|
|
||||||
mythicDungeonCharts.Frame.ChartFrame:AddLine(chartData, lineColor, lineName, combatTime, texture, "SMA")
|
local reducedData = chartFrame:ShrinkData(chartData, shrinkBy)
|
||||||
|
|
||||||
|
chartFrame:SetFillChart(true, 5)
|
||||||
|
chartFrame:AddData(reducedData, smoothMethod, smoothnessLevel, playerName, lineColor[1], lineColor[2], lineColor[3], opacity)
|
||||||
|
chartFrame:SetXAxisData(combatTime)
|
||||||
table.insert(mythicDungeonCharts.PlayerGraphIndex, playerName)
|
table.insert(mythicDungeonCharts.PlayerGraphIndex, playerName)
|
||||||
end
|
end
|
||||||
|
|
||||||
mythicDungeonCharts.Frame.ChartFrame:RefreshBossTimeline(mythicDungeonCharts.ChartTable.BossDefeated, mythicDungeonCharts.ChartTable.ElapsedTime)
|
mythicDungeonCharts.RefreshBossTimeline(dungeonChartFrame, mythicDungeonCharts.ChartTable.ElapsedTime)
|
||||||
|
|
||||||
--generate boss time table
|
--generate boss time table
|
||||||
local bossTimeTable = {}
|
local bossTimeTable = {}
|
||||||
for i, bossTable in ipairs(mythicDungeonCharts.ChartTable.BossDefeated) do
|
for i, bossTable in ipairs(mythicDungeonCharts.ChartTable.BossDefeated) do
|
||||||
local combatTime = bossTable [3] or math.random(10, 30)
|
local combatTime = bossTable [3] or math.random(10, 30)
|
||||||
|
|
||||||
table.insert(bossTimeTable, bossTable[1])
|
table.insert(bossTimeTable, bossTable[1])
|
||||||
table.insert(bossTimeTable, bossTable[1] - combatTime)
|
table.insert(bossTimeTable, bossTable[1] - combatTime)
|
||||||
end
|
end
|
||||||
|
|
||||||
mythicDungeonCharts.Frame.ChartFrame:AddOverlay(bossTimeTable, {1, 1, 1, 0.05}, "Show Boss", "")
|
--chartFrame:AddOverlay(bossTimeTable, {1, 1, 1, 0.05}, "Show Boss", "")
|
||||||
|
|
||||||
--local phrase = " Average Dps (under development)\npress Escape to hide, Details! Alpha Build." .. _detalhes.build_counter .. "." .. _detalhes.realversion
|
--local phrase = " Average Dps (under development)\npress Escape to hide, Details! Alpha Build." .. _detalhes.build_counter .. "." .. _detalhes.realversion
|
||||||
local phrase = "Details!: Average Dps for "
|
local phrase = "Details!: Average Dps for "
|
||||||
|
|
||||||
mythicDungeonCharts.Frame.ChartFrame:SetTitle("")
|
--chartFrame:SetTitle("")
|
||||||
detailsFramework:SetFontSize(mythicDungeonCharts.Frame.ChartFrame.chart_title, 14)
|
--detailsFramework:SetFontSize(chartFrame.chart_title, 14)
|
||||||
|
|
||||||
mythicDungeonCharts.Frame.TitleText:SetText(mythicDungeonCharts.ChartTable.DungeonName and phrase .. mythicDungeonCharts.ChartTable.DungeonName or phrase)
|
dungeonChartFrame.TitleText:SetText(mythicDungeonCharts.ChartTable.DungeonName and phrase .. mythicDungeonCharts.ChartTable.DungeonName or phrase)
|
||||||
|
|
||||||
mythicDungeonCharts.Frame.ShowChartFrame()
|
dungeonChartFrame.ShowChartFrame()
|
||||||
|
|
||||||
|
chartFrame:Plot()
|
||||||
|
|
||||||
if (verbosemode) then
|
if (verbosemode) then
|
||||||
mythicDungeonCharts:Debug("mythicDungeonCharts.ShowChart() success")
|
mythicDungeonCharts:Debug("mythicDungeonCharts.ShowChart() success")
|
||||||
@@ -421,124 +270,6 @@ local PixelFrameOnLeave = function(self)
|
|||||||
timer.ShowID = showID
|
timer.ShowID = showID
|
||||||
end
|
end
|
||||||
|
|
||||||
local TAXIROUTE_LINEFACTOR = 128 / 126 -- Multiplying factor for texture coordinates
|
|
||||||
local TAXIROUTE_LINEFACTOR_2 = TAXIROUTE_LINEFACTOR / 2 -- Half of that
|
|
||||||
|
|
||||||
function mythicDungeonCharts:CustomDrawLine (C, sx, sy, ex, ey, w, color, layer, linetexture, graphIndex)
|
|
||||||
local relPoint = "BOTTOMLEFT"
|
|
||||||
|
|
||||||
if sx == ex then
|
|
||||||
if sy == ey then
|
|
||||||
return
|
|
||||||
else
|
|
||||||
return self:DrawVLine(C, sx, sy, ey, w, color, layer)
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif sy == ey then
|
|
||||||
return self:DrawHLine(C, sx, ex, sy, w, color, layer)
|
|
||||||
end
|
|
||||||
|
|
||||||
if not C.GraphLib_Lines then
|
|
||||||
C.GraphLib_Lines = {}
|
|
||||||
C.GraphLib_Lines_Used = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
local T = tremove(C.GraphLib_Lines) or C:CreateTexture(nil, "ARTWORK")
|
|
||||||
|
|
||||||
if linetexture then --this data series texture
|
|
||||||
T:SetTexture(linetexture)
|
|
||||||
|
|
||||||
elseif C.CustomLine then --overall chart texture
|
|
||||||
T:SetTexture(C.CustomLine)
|
|
||||||
|
|
||||||
else --no texture assigned, use default
|
|
||||||
T:SetTexture(TextureDirectory.."line")
|
|
||||||
end
|
|
||||||
|
|
||||||
table.insert(C.GraphLib_Lines_Used, T)
|
|
||||||
|
|
||||||
T:SetDrawLayer(layer or "ARTWORK")
|
|
||||||
|
|
||||||
T:SetVertexColor(color[1], color[2], color[3], color[4])
|
|
||||||
-- Determine dimensions and center point of line
|
|
||||||
local dx, dy = ex - sx, ey - sy
|
|
||||||
local cx, cy = (sx + ex) / 2, (sy + ey) / 2
|
|
||||||
|
|
||||||
-- Normalize direction if necessary
|
|
||||||
if (dx < 0) then
|
|
||||||
dx, dy = -dx, -dy
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Calculate actual length of line
|
|
||||||
local l = sqrt((dx * dx) + (dy * dy))
|
|
||||||
|
|
||||||
-- Sin and Cosine of rotation, and combination (for later)
|
|
||||||
local s, c = -dy / l, dx / l
|
|
||||||
local sc = s * c
|
|
||||||
|
|
||||||
-- Calculate bounding box size and texture coordinates
|
|
||||||
local Bwid, Bhgt, BLx, BLy, TLx, TLy, TRx, TRy, BRx, BRy
|
|
||||||
if (dy >= 0) then
|
|
||||||
Bwid = ((l * c) - (w * s)) * TAXIROUTE_LINEFACTOR_2
|
|
||||||
Bhgt = ((w * c) - (l * s)) * TAXIROUTE_LINEFACTOR_2
|
|
||||||
BLx, BLy, BRy = (w / l) * sc, s * s, (l / w) * sc
|
|
||||||
BRx, TLx, TLy, TRx = 1 - BLy, BLy, 1 - BRy, 1 - BLx
|
|
||||||
TRy = BRx
|
|
||||||
else
|
|
||||||
Bwid = ((l * c) + (w * s)) * TAXIROUTE_LINEFACTOR_2
|
|
||||||
Bhgt = ((w * c) + (l * s)) * TAXIROUTE_LINEFACTOR_2
|
|
||||||
BLx, BLy, BRx = s * s, -(l / w) * sc, 1 + (w / l) * sc
|
|
||||||
BRy, TLx, TLy, TRy = BLx, 1 - BRx, 1 - BLx, 1 - BLy
|
|
||||||
TRx = TLy
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Thanks Blizzard for adding (-)10000 as a hard-cap and throwing errors!
|
|
||||||
-- The cap was added in 3.1.0 and I think it was upped in 3.1.1
|
|
||||||
-- (way less chance to get the error)
|
|
||||||
if TLx > 10000 then TLx = 10000 elseif TLx < -10000 then TLx = -10000 end
|
|
||||||
if TLy > 10000 then TLy = 10000 elseif TLy < -10000 then TLy = -10000 end
|
|
||||||
if BLx > 10000 then BLx = 10000 elseif BLx < -10000 then BLx = -10000 end
|
|
||||||
if BLy > 10000 then BLy = 10000 elseif BLy < -10000 then BLy = -10000 end
|
|
||||||
if TRx > 10000 then TRx = 10000 elseif TRx < -10000 then TRx = -10000 end
|
|
||||||
if TRy > 10000 then TRy = 10000 elseif TRy < -10000 then TRy = -10000 end
|
|
||||||
if BRx > 10000 then BRx = 10000 elseif BRx < -10000 then BRx = -10000 end
|
|
||||||
if BRy > 10000 then BRy = 10000 elseif BRy < -10000 then BRy = -10000 end
|
|
||||||
|
|
||||||
-- Set texture coordinates and anchors
|
|
||||||
T:ClearAllPoints()
|
|
||||||
T:SetTexCoord(TLx, TLy, BLx, BLy, TRx, TRy, BRx, BRy)
|
|
||||||
T:SetPoint("BOTTOMLEFT", C, relPoint, cx - Bwid, cy - Bhgt)
|
|
||||||
T:SetPoint("TOPRIGHT", C, relPoint, cx + Bwid, cy + Bhgt)
|
|
||||||
T:Show()
|
|
||||||
|
|
||||||
local playerName = mythicDungeonCharts.PlayerGraphIndex [graphIndex]
|
|
||||||
if (mythicDungeonCharts.Frame.ChartFrame.TextureID % 3 == 0 and playerName) then
|
|
||||||
|
|
||||||
local pixelFrame = tremove(mythicDungeonCharts.Frame.ChartFrame.FrameFree)
|
|
||||||
if (not pixelFrame) then
|
|
||||||
local newFrame = CreateFrame("frame", nil, mythicDungeonCharts.Frame.ChartFrame, "BackdropTemplate")
|
|
||||||
newFrame:SetSize(1, 1)
|
|
||||||
|
|
||||||
--newFrame:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 2, tile = true})
|
|
||||||
--newFrame:SetBackdropColor(0, 0, 0, 1)
|
|
||||||
newFrame:SetScript("OnEnter", PixelFrameOnEnter)
|
|
||||||
newFrame:SetScript("OnLeave", PixelFrameOnLeave)
|
|
||||||
|
|
||||||
pixelFrame = newFrame
|
|
||||||
end
|
|
||||||
|
|
||||||
pixelFrame:SetPoint("BOTTOMLEFT", C, relPoint, cx - Bwid, cy - Bhgt)
|
|
||||||
pixelFrame:SetPoint("TOPRIGHT", C, relPoint, cx + Bwid, cy + Bhgt)
|
|
||||||
|
|
||||||
table.insert(mythicDungeonCharts.Frame.ChartFrame.FrameInUse, pixelFrame)
|
|
||||||
pixelFrame.PlayerName = playerName
|
|
||||||
pixelFrame.Height = ey
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
mythicDungeonCharts.Frame.ChartFrame.TextureID = mythicDungeonCharts.Frame.ChartFrame.TextureID + 1
|
|
||||||
return T
|
|
||||||
end
|
|
||||||
|
|
||||||
mythicDungeonCharts.ClassColors = {
|
mythicDungeonCharts.ClassColors = {
|
||||||
["HUNTER1"] = { r = 0.67, g = 0.83, b = 0.45, colorStr = "ffabd473" },
|
["HUNTER1"] = { r = 0.67, g = 0.83, b = 0.45, colorStr = "ffabd473" },
|
||||||
@@ -592,4 +323,140 @@ mythicDungeonCharts.ClassColors = {
|
|||||||
|
|
||||||
if (Details222.Debug.MythicPlusChartWindowDebug) then
|
if (Details222.Debug.MythicPlusChartWindowDebug) then
|
||||||
--C_Timer.After(1, mythicDungeonCharts.ShowChart)
|
--C_Timer.After(1, mythicDungeonCharts.ShowChart)
|
||||||
|
end
|
||||||
|
|
||||||
|
function mythicDungeonCharts.RefreshBossTimeline(dungeonChartFrame, elapsedTime)
|
||||||
|
---@type df_chartmulti
|
||||||
|
local chartFrame = dungeonChartFrame.ChartFrame
|
||||||
|
|
||||||
|
for i, bossTable in ipairs(mythicDungeonCharts.ChartTable.BossDefeated) do
|
||||||
|
local bossWidget = dungeonChartFrame.BossWidgetsFrame.Widgets[i]
|
||||||
|
|
||||||
|
if (not bossWidget) then
|
||||||
|
local newBossWidget = CreateFrame("frame", "$parentBossWidget" .. i, dungeonChartFrame.BossWidgetsFrame, "BackdropTemplate")
|
||||||
|
newBossWidget:SetSize(64, 32)
|
||||||
|
newBossWidget:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||||||
|
newBossWidget:SetBackdropColor(0, 0, 0, 0.1)
|
||||||
|
newBossWidget:SetBackdropBorderColor(0, 0, 0, 0)
|
||||||
|
|
||||||
|
local bossAvatar = detailsFramework:CreateImage(newBossWidget, "", 64, 32, "border")
|
||||||
|
bossAvatar:SetPoint("bottomleft", newBossWidget, "bottomleft", 0, 0)
|
||||||
|
bossAvatar:SetScale(1.0)
|
||||||
|
newBossWidget.AvatarTexture = bossAvatar
|
||||||
|
|
||||||
|
local verticalLine = detailsFramework:CreateImage(newBossWidget, "", 1, chartFrame:GetHeight() - 25, "overlay")
|
||||||
|
verticalLine:SetColorTexture(1, 1, 1, 0.3)
|
||||||
|
verticalLine:SetPoint("bottomleft", newBossWidget, "bottomright", 0, 0)
|
||||||
|
|
||||||
|
local timeText = detailsFramework:CreateLabel(newBossWidget)
|
||||||
|
timeText:SetPoint("bottomright", newBossWidget, "bottomright", 0, 0)
|
||||||
|
newBossWidget.TimeText = timeText
|
||||||
|
|
||||||
|
local timeBackground = detailsFramework:CreateImage(newBossWidget, "", 30, 12, "artwork")
|
||||||
|
timeBackground:SetColorTexture(0, 0, 0, 0.8)
|
||||||
|
timeBackground:SetPoint("topleft", timeText, "topleft", -2, 2)
|
||||||
|
timeBackground:SetPoint("bottomright", timeText, "bottomright", 2, 0)
|
||||||
|
|
||||||
|
dungeonChartFrame.BossWidgetsFrame.Widgets[i] = newBossWidget
|
||||||
|
bossWidget = newBossWidget
|
||||||
|
end
|
||||||
|
|
||||||
|
local chartLength = chartFrame:GetWidth()
|
||||||
|
local secondsPerPixel = chartLength / elapsedTime
|
||||||
|
local xPosition = bossTable[1] * secondsPerPixel
|
||||||
|
|
||||||
|
bossWidget:SetPoint("bottomright", chartFrame, "bottomleft", xPosition, 22)
|
||||||
|
|
||||||
|
bossWidget.TimeText:SetText(detailsFramework:IntegerToTimer(bossTable[1]))
|
||||||
|
|
||||||
|
if (bossTable[2].bossimage) then
|
||||||
|
bossWidget.AvatarTexture:SetTexture(bossTable[2].bossimage)
|
||||||
|
else
|
||||||
|
local bossAvatar = Details:GetBossPortrait(nil, nil, bossTable[2].name, bossTable[2].ej_instance_id)
|
||||||
|
bossWidget.AvatarTexture:SetTexture(bossAvatar)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function mythicDungeonCharts.CreateCloseMinimizeButtons(dungeonChartFrame)
|
||||||
|
local fMinimized = mythicDungeonCharts.FrameMinimized
|
||||||
|
|
||||||
|
local closeButton = CreateFrame("button", "$parentCloseButton", dungeonChartFrame, "UIPanelCloseButton")
|
||||||
|
closeButton:GetNormalTexture():SetDesaturated(true)
|
||||||
|
closeButton:SetWidth(24)
|
||||||
|
closeButton:SetHeight(24)
|
||||||
|
closeButton:SetPoint("topright", dungeonChartFrame, "topright", 0, -1)
|
||||||
|
closeButton:SetFrameLevel(dungeonChartFrame:GetFrameLevel()+16)
|
||||||
|
|
||||||
|
local minimizeButton = CreateFrame("button", "$parentCloseButton", dungeonChartFrame, "UIPanelCloseButton")
|
||||||
|
minimizeButton:GetNormalTexture():SetDesaturated(true)
|
||||||
|
minimizeButton:SetWidth(24)
|
||||||
|
minimizeButton:SetHeight(24)
|
||||||
|
minimizeButton:SetPoint("right", closeButton, "left", 2, 0)
|
||||||
|
minimizeButton:SetFrameLevel(dungeonChartFrame:GetFrameLevel()+16)
|
||||||
|
minimizeButton:SetNormalTexture([[Interface\BUTTONS\UI-Panel-HideButton-Up]])
|
||||||
|
minimizeButton:SetPushedTexture([[Interface\BUTTONS\UI-Panel-HideButton-Down]])
|
||||||
|
minimizeButton:SetHighlightTexture([[Interface\BUTTONS\UI-Panel-MinimizeButton-Highlight]])
|
||||||
|
|
||||||
|
local closeButtonWhenMinimized = CreateFrame("button", "$parentCloseButton", fMinimized, "UIPanelCloseButton")
|
||||||
|
closeButtonWhenMinimized:GetNormalTexture():SetDesaturated(true)
|
||||||
|
closeButtonWhenMinimized:SetWidth(24)
|
||||||
|
closeButtonWhenMinimized:SetHeight(24)
|
||||||
|
closeButtonWhenMinimized:SetPoint("topright", fMinimized, "topright", 0, -1)
|
||||||
|
closeButtonWhenMinimized:SetFrameLevel(fMinimized:GetFrameLevel()+16)
|
||||||
|
|
||||||
|
local minimizeButtonWhenMinimized = CreateFrame("button", "$parentCloseButton", fMinimized, "UIPanelCloseButton")
|
||||||
|
minimizeButtonWhenMinimized:GetNormalTexture():SetDesaturated(true)
|
||||||
|
minimizeButtonWhenMinimized:SetWidth(24)
|
||||||
|
minimizeButtonWhenMinimized:SetHeight(24)
|
||||||
|
minimizeButtonWhenMinimized:SetPoint("right", closeButtonWhenMinimized, "left", 2, 0)
|
||||||
|
minimizeButtonWhenMinimized:SetFrameLevel(fMinimized:GetFrameLevel()+16)
|
||||||
|
minimizeButtonWhenMinimized:SetNormalTexture([[Interface\BUTTONS\UI-Panel-HideButton-Up]])
|
||||||
|
minimizeButtonWhenMinimized:SetPushedTexture([[Interface\BUTTONS\UI-Panel-HideButton-Down]])
|
||||||
|
minimizeButtonWhenMinimized:SetHighlightTexture([[Interface\BUTTONS\UI-Panel-MinimizeButton-Highlight]])
|
||||||
|
|
||||||
|
closeButtonWhenMinimized:SetScript("OnClick", function()
|
||||||
|
dungeonChartFrame.IsMinimized = false
|
||||||
|
fMinimized:Hide()
|
||||||
|
minimizeButtonWhenMinimized:SetNormalTexture([[Interface\BUTTONS\UI-Panel-HideButton-Up]])
|
||||||
|
minimizeButtonWhenMinimized:SetPushedTexture([[Interface\BUTTONS\UI-Panel-HideButton-Down]])
|
||||||
|
end)
|
||||||
|
|
||||||
|
--replace the default click function
|
||||||
|
local minimize_func = function(self)
|
||||||
|
if (dungeonChartFrame.IsMinimized) then
|
||||||
|
dungeonChartFrame.IsMinimized = false
|
||||||
|
fMinimized:Hide()
|
||||||
|
dungeonChartFrame:Show()
|
||||||
|
minimizeButtonWhenMinimized:SetNormalTexture([[Interface\BUTTONS\UI-Panel-HideButton-Up]])
|
||||||
|
minimizeButtonWhenMinimized:SetPushedTexture([[Interface\BUTTONS\UI-Panel-HideButton-Down]])
|
||||||
|
else
|
||||||
|
dungeonChartFrame.IsMinimized = true
|
||||||
|
dungeonChartFrame:Hide()
|
||||||
|
fMinimized:Show()
|
||||||
|
minimizeButtonWhenMinimized:SetNormalTexture([[Interface\BUTTONS\UI-Panel-CollapseButton-Up]])
|
||||||
|
minimizeButtonWhenMinimized:SetPushedTexture([[Interface\BUTTONS\UI-Panel-CollapseButton-Up]])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
minimizeButton:SetScript("OnClick", minimize_func)
|
||||||
|
minimizeButtonWhenMinimized:SetScript("OnClick", minimize_func)
|
||||||
|
end
|
||||||
|
|
||||||
|
function mythicDungeonCharts.CreateBossWidgets(dungeonChartFrame)
|
||||||
|
dungeonChartFrame.BossWidgetsFrame = CreateFrame("frame", "$parentBossFrames", dungeonChartFrame, "BackdropTemplate")
|
||||||
|
dungeonChartFrame.BossWidgetsFrame:SetFrameLevel(dungeonChartFrame:GetFrameLevel()+10)
|
||||||
|
dungeonChartFrame.BossWidgetsFrame.Widgets = {}
|
||||||
|
|
||||||
|
dungeonChartFrame.BossWidgetsFrame.GraphPin = dungeonChartFrame.BossWidgetsFrame:CreateTexture(nil, "overlay")
|
||||||
|
dungeonChartFrame.BossWidgetsFrame.GraphPin:SetTexture([[Interface\BUTTONS\UI-RadioButton]])
|
||||||
|
dungeonChartFrame.BossWidgetsFrame.GraphPin:SetTexCoord(17/64, 32/64, 0, 1)
|
||||||
|
dungeonChartFrame.BossWidgetsFrame.GraphPin:SetSize(16, 16)
|
||||||
|
|
||||||
|
dungeonChartFrame.BossWidgetsFrame.GraphPinGlow = dungeonChartFrame.BossWidgetsFrame:CreateTexture(nil, "artwork")
|
||||||
|
dungeonChartFrame.BossWidgetsFrame.GraphPinGlow:SetTexture([[Interface\Calendar\EventNotificationGlow]])
|
||||||
|
dungeonChartFrame.BossWidgetsFrame.GraphPinGlow:SetTexCoord(0, 1, 0, 1)
|
||||||
|
dungeonChartFrame.BossWidgetsFrame.GraphPinGlow:SetSize(14, 14)
|
||||||
|
dungeonChartFrame.BossWidgetsFrame.GraphPinGlow:SetBlendMode("ADD")
|
||||||
|
dungeonChartFrame.BossWidgetsFrame.GraphPinGlow:SetPoint("center", dungeonChartFrame.BossWidgetsFrame.GraphPin, "center", 0, 0)
|
||||||
end
|
end
|
||||||
Reference in New Issue
Block a user