stapelBalkendiagramm Prozentual und Summe in kw
This commit is contained in:
@@ -99,6 +99,252 @@ function scene:show( event )
|
||||
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
|
||||
local function reloadDataFromSevenDays()
|
||||
if not currentCookie or not devices or not selectedDate then
|
||||
@@ -152,6 +398,9 @@ function scene:show( event )
|
||||
print("===============================================================\n")
|
||||
-- Zeige neue Daten
|
||||
print("✓ Daten erfolgreich geladen")
|
||||
|
||||
-- Zeige Balkendiagramm
|
||||
displayBarChart(currentDataSets)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user