stapelBalkendiagramm Prozentual und Summe in kw
This commit is contained in:
@@ -99,6 +99,252 @@ function scene:show( event )
|
|||||||
print("Cookie:" .. tostring(currentCookie))
|
print("Cookie:" .. tostring(currentCookie))
|
||||||
|
|
||||||
|
|
||||||
|
-- Funktion zur Anzeige des Balkendiagramms
|
||||||
|
local function displayBarChart(dataSets)
|
||||||
|
-- Entferne alte Diagramm-Anzeigen
|
||||||
|
for i = sceneGroup.numChildren, 1, -1 do
|
||||||
|
local child = sceneGroup[i]
|
||||||
|
if child._isChartDisplay then
|
||||||
|
child:removeSelf()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not dataSets or type(dataSets) ~= "table" then
|
||||||
|
print("Keine Daten zum Anzeigen")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Definiere Farben für die Devices
|
||||||
|
local deviceColors = {
|
||||||
|
["Traun"] = {0.2, 0.4, 0.9}, -- Blau
|
||||||
|
["Lannach"] = {0.3, 0.8, 0.4}, -- Grün
|
||||||
|
["Sarleinsbach"] = {0.95, 0.6, 0.2} -- Orange
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Parameter für das Diagramm
|
||||||
|
local chartX = display.contentCenterX
|
||||||
|
local chartY = 150
|
||||||
|
local chartWidth = display.contentWidth - 40
|
||||||
|
local chartHeight = 180
|
||||||
|
|
||||||
|
-- Hintergrund für das Diagramm
|
||||||
|
local chartBg = display.newRoundedRect(sceneGroup, chartX, chartY, chartWidth, chartHeight, 8)
|
||||||
|
chartBg:setFillColor(1, 1, 1)
|
||||||
|
chartBg.strokeWidth = 2
|
||||||
|
chartBg:setStrokeColor(0.7, 0.7, 0.7)
|
||||||
|
chartBg._isChartDisplay = true
|
||||||
|
|
||||||
|
-- Titel
|
||||||
|
local titleText = display.newText({
|
||||||
|
parent = sceneGroup,
|
||||||
|
text = "Wochenübersicht (kW)",
|
||||||
|
x = chartX,
|
||||||
|
y = chartY - chartHeight/2 - 15,
|
||||||
|
fontSize = 16,
|
||||||
|
font = native.systemFontBold
|
||||||
|
})
|
||||||
|
titleText:setFillColor(0.2, 0.2, 0.2)
|
||||||
|
titleText._isChartDisplay = true
|
||||||
|
|
||||||
|
-- Organisiere Daten nach Tag
|
||||||
|
local dayData = {} -- { ["2024-05-20"] = { Traun = value, Lannach = value, Sarleinsbach = value } }
|
||||||
|
local maxValue = 0
|
||||||
|
|
||||||
|
for deviceName, dataSet in pairs(dataSets) do
|
||||||
|
if not dataSet.error and type(dataSet) == "table" and #dataSet > 0 then
|
||||||
|
for _, meter in ipairs(dataSet) do
|
||||||
|
if meter.values and #meter.values > 0 then
|
||||||
|
for _, valueData in ipairs(meter.values) do
|
||||||
|
if valueData.value and valueData.datetime then
|
||||||
|
local date = valueData.datetime:match("(%d%d%d%d%-%d%d%-%d%d)")
|
||||||
|
if date then
|
||||||
|
if not dayData[date] then
|
||||||
|
dayData[date] = {}
|
||||||
|
end
|
||||||
|
dayData[date][deviceName] = valueData.value
|
||||||
|
maxValue = math.max(maxValue, valueData.value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
break -- Nur das erste Meter pro Device
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Sortiere Tage
|
||||||
|
local sortedDays = {}
|
||||||
|
for day in pairs(dayData) do
|
||||||
|
table.insert(sortedDays, day)
|
||||||
|
end
|
||||||
|
table.sort(sortedDays)
|
||||||
|
|
||||||
|
if #sortedDays == 0 then
|
||||||
|
local noDataText = display.newText({
|
||||||
|
parent = sceneGroup,
|
||||||
|
text = "Keine Daten zum Anzeigen",
|
||||||
|
x = chartX,
|
||||||
|
y = chartY,
|
||||||
|
fontSize = 14
|
||||||
|
})
|
||||||
|
noDataText:setFillColor(0.5, 0.5, 0.5)
|
||||||
|
noDataText._isChartDisplay = true
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Berechne Diagramm-Parameter
|
||||||
|
local graphLeft = chartX - chartWidth/2 + 30
|
||||||
|
local graphRight = chartX + chartWidth/2 - 10
|
||||||
|
local graphTop = chartY - chartHeight/2 + 25
|
||||||
|
local graphBottom = chartY + chartHeight/2 - 35
|
||||||
|
local graphWidth = graphRight - graphLeft
|
||||||
|
local graphHeight = graphBottom - graphTop
|
||||||
|
|
||||||
|
-- Zeichne Y-Achse
|
||||||
|
local yAxis = display.newLine(sceneGroup, graphLeft, graphTop, graphLeft, graphBottom)
|
||||||
|
yAxis:setStrokeColor(0.5, 0.5, 0.5)
|
||||||
|
yAxis.strokeWidth = 2
|
||||||
|
yAxis._isChartDisplay = true
|
||||||
|
|
||||||
|
-- Zeichne X-Achse
|
||||||
|
local xAxis = display.newLine(sceneGroup, graphLeft, graphBottom, graphRight, graphBottom)
|
||||||
|
xAxis:setStrokeColor(0.5, 0.5, 0.5)
|
||||||
|
xAxis.strokeWidth = 2
|
||||||
|
xAxis._isChartDisplay = true
|
||||||
|
|
||||||
|
-- Y-Achsen-Beschriftung
|
||||||
|
local maxLabel = display.newText({
|
||||||
|
parent = sceneGroup,
|
||||||
|
text = string.format("%.0f", maxValue),
|
||||||
|
x = graphLeft - 15,
|
||||||
|
y = graphTop,
|
||||||
|
fontSize = 9
|
||||||
|
})
|
||||||
|
maxLabel:setFillColor(0.4, 0.4, 0.4)
|
||||||
|
maxLabel._isChartDisplay = true
|
||||||
|
|
||||||
|
local zeroLabel = display.newText({
|
||||||
|
parent = sceneGroup,
|
||||||
|
text = "0",
|
||||||
|
x = graphLeft - 15,
|
||||||
|
y = graphBottom,
|
||||||
|
fontSize = 9
|
||||||
|
})
|
||||||
|
zeroLabel:setFillColor(0.4, 0.4, 0.4)
|
||||||
|
zeroLabel._isChartDisplay = true
|
||||||
|
|
||||||
|
-- Zeichne Balken für jeden Tag
|
||||||
|
local dayWidth = graphWidth / #sortedDays
|
||||||
|
local barSpacing = 4
|
||||||
|
local barWidth = dayWidth - barSpacing * 2
|
||||||
|
|
||||||
|
for i, day in ipairs(sortedDays) do
|
||||||
|
local dayX = graphLeft + (i - 0.5) * dayWidth
|
||||||
|
local data = dayData[day]
|
||||||
|
|
||||||
|
-- Datum-Label
|
||||||
|
local dayLabel = display.newText({
|
||||||
|
parent = sceneGroup,
|
||||||
|
text = day:match("%d%d%-%d%d$"), -- Nur MM-DD
|
||||||
|
x = dayX,
|
||||||
|
y = graphBottom + 12,
|
||||||
|
fontSize = 8
|
||||||
|
})
|
||||||
|
dayLabel:setFillColor(0.3, 0.3, 0.3)
|
||||||
|
dayLabel._isChartDisplay = true
|
||||||
|
|
||||||
|
-- Berechne Gesamtwert für diesen Tag
|
||||||
|
local totalValue = 0
|
||||||
|
local deviceOrder = {"Traun", "Lannach", "Sarleinsbach"}
|
||||||
|
for _, deviceName in ipairs(deviceOrder) do
|
||||||
|
totalValue = totalValue + (data[deviceName] or 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
if totalValue > 0 then
|
||||||
|
-- Zeichne gestapelten Balken - prozentual zur vollen Diagrammhöhe
|
||||||
|
local currentY = graphBottom
|
||||||
|
|
||||||
|
for _, deviceName in ipairs(deviceOrder) do
|
||||||
|
local value = data[deviceName] or 0
|
||||||
|
if value > 0 then
|
||||||
|
-- Berechne Segment-Höhe proportional zum Anteil am Gesamtwert
|
||||||
|
-- Balken nutzt die volle Höhe, Segmente sind prozentual
|
||||||
|
local percentage = value / totalValue
|
||||||
|
local segmentHeight = percentage * graphHeight
|
||||||
|
local segmentY = currentY - segmentHeight/2
|
||||||
|
|
||||||
|
-- Segment
|
||||||
|
local segment = display.newRect(sceneGroup, dayX, segmentY, barWidth, segmentHeight)
|
||||||
|
local color = deviceColors[deviceName] or {0.5, 0.5, 0.5}
|
||||||
|
segment:setFillColor(unpack(color))
|
||||||
|
segment.strokeWidth = 1
|
||||||
|
segment:setStrokeColor(0.9, 0.9, 0.9)
|
||||||
|
segment._isChartDisplay = true
|
||||||
|
|
||||||
|
-- Wert-Label im Segment (wenn genug Platz)
|
||||||
|
if segmentHeight > 12 then
|
||||||
|
local valueLabel = display.newText({
|
||||||
|
parent = sceneGroup,
|
||||||
|
text = string.format("%d\n%.0f%%", value, percentage * 100),
|
||||||
|
x = dayX,
|
||||||
|
y = segmentY,
|
||||||
|
fontSize = 7,
|
||||||
|
font = native.systemFontBold
|
||||||
|
})
|
||||||
|
valueLabel:setFillColor(1, 1, 1)
|
||||||
|
valueLabel._isChartDisplay = true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Bewege Y-Position nach oben für nächstes Segment
|
||||||
|
currentY = currentY - segmentHeight
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Gesamtwert über dem Balken
|
||||||
|
local totalLabel = display.newText({
|
||||||
|
parent = sceneGroup,
|
||||||
|
text = string.format("%d", totalValue),
|
||||||
|
x = dayX,
|
||||||
|
y = graphTop - 8,
|
||||||
|
fontSize = 8,
|
||||||
|
font = native.systemFontBold
|
||||||
|
})
|
||||||
|
totalLabel:setFillColor(0.2, 0.2, 0.2)
|
||||||
|
totalLabel._isChartDisplay = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Legende
|
||||||
|
local legendY = chartY + chartHeight/2 + 20
|
||||||
|
local legendDevices = {
|
||||||
|
{name = "Traun", color = deviceColors["Traun"]},
|
||||||
|
{name = "Lannach", color = deviceColors["Lannach"]},
|
||||||
|
{name = "Sarleinsbach", color = deviceColors["Sarleinsbach"]}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, legend in ipairs(legendDevices) do
|
||||||
|
local legendX = chartX - 90 + ((i - 1) * 90)
|
||||||
|
|
||||||
|
-- Farbbox
|
||||||
|
local colorBox = display.newRect(sceneGroup, legendX - 20, legendY, 12, 8)
|
||||||
|
colorBox:setFillColor(unpack(legend.color))
|
||||||
|
colorBox._isChartDisplay = true
|
||||||
|
|
||||||
|
-- Device Name
|
||||||
|
local legendText = display.newText({
|
||||||
|
parent = sceneGroup,
|
||||||
|
text = legend.name,
|
||||||
|
x = legendX + 10,
|
||||||
|
y = legendY,
|
||||||
|
fontSize = 10
|
||||||
|
})
|
||||||
|
legendText:setFillColor(0.3, 0.3, 0.3)
|
||||||
|
legendText._isChartDisplay = true
|
||||||
|
end
|
||||||
|
|
||||||
|
print("✓ Balkendiagramm erstellt für " .. #sortedDays .. " Tage")
|
||||||
|
end
|
||||||
|
|
||||||
-- Funktion zum Neuladen der Daten
|
-- Funktion zum Neuladen der Daten
|
||||||
local function reloadDataFromSevenDays()
|
local function reloadDataFromSevenDays()
|
||||||
if not currentCookie or not devices or not selectedDate then
|
if not currentCookie or not devices or not selectedDate then
|
||||||
@@ -152,6 +398,9 @@ function scene:show( event )
|
|||||||
print("===============================================================\n")
|
print("===============================================================\n")
|
||||||
-- Zeige neue Daten
|
-- Zeige neue Daten
|
||||||
print("✓ Daten erfolgreich geladen")
|
print("✓ Daten erfolgreich geladen")
|
||||||
|
|
||||||
|
-- Zeige Balkendiagramm
|
||||||
|
displayBarChart(currentDataSets)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user