Alright, we’re getting there! Working with a bit of axis indications already. I tried to get this on GitHub but man that’s some complicated shizzle, so for now it’s just text, copy-pasted.
main.lua:
-- main.lua ----------- display.setStatusBar( display.HiddenStatusBar ) -- hide the status bar local smartUI = require("smartUI") local BG = display.newRect(768,1024,1536, 2048) BG:setFillColor(.8,.8,.8) local barChartData = { {100,50,400,80,75,20}, {20,85,250,500,50,300}, } local barChart = smartUI.newBarChart(768,1024,1400,800, barChartData, 50, 20) -- (xCenter, yCenter, width, height, barChartData, padding, spacing)
and smartUI.lua:
-- smartUI.lua -------------- local smartUI = {} smartUI.barGradients = { { type='gradient', color1={0,.6,.8}, color2={0,.3,.4}, direction='down' }, { type='gradient', color1={.6,.0,.8}, color2={.3,.0,.4}, direction='down' }, { type='gradient', color1={.3,.2,.4}, color2={.8,.6,.3}, direction='down' } } smartUI.newBarChart = function(xCenter, yCenter, width, height, barChartData, padding, spacing) local newBarChart = {} -- parse data to see what is the highest value in the chart local highestBarValue = 0 for i = 1, #barChartData do for j = 1, #barChartData[i] do if barChartData[i][j] \> highestBarValue then highestBarValue = barChartData[i][j] end end end -- define ratio: highest Bar Value divided by nearest upward power of 10 from this value local powerOf10Rounded = math.pow(10, math.ceil(math.log10(highestBarValue))) local ratio = highestBarValue/powerOf10Rounded local heightGridDivider if ratio \> 0 and ratio \<= 0.12 then ratio = 0.12 heightGridDivider = 6 elseif ratio \> 0.12 and ratio \<=0.15 then ratio = 0.15 heightGridDivider = 5 elseif ratio \> 0.15 and ratio \<= 0.2 then ratio = 0.2 heightGridDivider = 4 elseif ratio \> 0.2 and ratio \<= 0.25 then ratio = 0.25 heightGridDivider = 5 elseif ratio \> 0.25 and ratio \<= 0.4 then ratio = 0.4 heightGridDivider = 4 elseif ratio \> 0.4 and ratio \<= 0.5 then ratio = 0.5 heightGridDivider = 5 elseif ratio \> 0.5 and ratio \<= 0.6 then ratio = 0.6 heightGridDivider = 6 elseif ratio \> 0.5 and ratio \<= 0.8 then ratio = 0.8 heightGridDivider = 4 elseif ratio \> 0.8 and ratio \<= 1 then ratio = 1 heightGridDivider = 5 else -- alert error end local highAxisValue = ratio\*powerOf10Rounded newBarChart.mainGroup = display.newGroup() newBarChart.mainGroup.x = xCenter newBarChart.mainGroup.y = yCenter newBarChart.backGround = display.newRect(newBarChart.mainGroup, 0, 0, width, height) if padding == nil then padding = 50 end if spacing == nil then spacing = 10 end local widthMinusPadding = width - 2\*padding local numberOfBarsPerGroup = #barChartData local numberOfBarGroups = #barChartData[1] local widthPerBarGroup = widthMinusPadding / numberOfBarGroups local widthPerBar = (widthPerBarGroup - spacing\*(numberOfBarsPerGroup+1)) / numberOfBarsPerGroup -- 2 bars in a group means 3 times spacing: left, center and right newBarChart.barGroups = {} local yScaleRatio = (height-2\*padding) / highAxisValue for i = 1, numberOfBarGroups do local index = #newBarChart.barGroups+1 newBarChart.barGroups[index] = display.newGroup() newBarChart.mainGroup:insert(newBarChart.barGroups[index]) local xCenterForBarGroup = - width/2 + padding + (widthPerBarGroup\*i) - widthPerBarGroup/2 newBarChart.barGroups[index].x = xCenterForBarGroup for j = 1, numberOfBarsPerGroup do local temp = display.newRect(newBarChart.barGroups[index], 0,0,widthPerBar,1) -- x,y,width, height temp:setFillColor(smartUI.barGradients[j]) temp.anchorY = 1 temp.y = height/2 - padding temp.x = -widthPerBarGroup/2 + spacing\*j + (widthPerBar\*j) - widthPerBar/2 temp.yScale = .001 transition.to(temp, {time = 300, delay = (i-1)\*50, yScale = barChartData[j][i]\*yScaleRatio, transition = easing.inOutQuad}) end end -- draw horizontal gridlines newBarChart.gridGroup = display.newGroup() newBarChart.mainGroup:insert(newBarChart.gridGroup) local heightRatio = highestBarValue / (height - 2\*padding) for i = 1, (heightGridDivider) do local gridLine = display.newRect(0, (height/2-padding)-i\*(height-2\*padding)/heightGridDivider, width-2\*padding, 2) gridLine:setFillColor(0,0,0) newBarChart.gridGroup:insert(gridLine) local gridText = display.newText(newBarChart.gridGroup, i\*(highAxisValue/heightGridDivider), (-width/2)+padding+spacing/2, (height/2-padding)-i\*(height-2\*padding)/heightGridDivider+20, native.systemFont, 32) gridText.anchorX = 0 gridText:setFillColor(0,0,0) end -- draw H and V axis newBarChart.axisGroup = display.newGroup() newBarChart.mainGroup:insert(newBarChart.axisGroup) newBarChart.verticalAxis = display.newRect(-width/2 + padding,0,4,height - padding\*2) newBarChart.verticalAxis:setFillColor(.5,.5,.5) newBarChart.axisGroup:insert(newBarChart.verticalAxis) newBarChart.horizontalAxis = display.newRect(0,height/2 - padding,width-2\*padding,4) newBarChart.horizontalAxis:setFillColor(.5,.5,.5) newBarChart.axisGroup:insert(newBarChart.horizontalAxis) -- return newBarChart end -- smartUI.newBarChart() -- -- return smartUI
Everything seems to be working well and gracefully so far. Still work in progress so stay tuned for updates!