The need for charts on CoronaSDK

Hello all, 

I’m starting this topic because after searching a lot on Internet and looking at the different options, seems like there is no easy wat to create charts.

Even when CoronaSDK is mostly used for games, I think it would be nice to improve the support for other kind of apps, including business apps where charts can be really useful thing.

I understand that is maybe is not a trivial thing to create that and maybe does not need to be the most complete  API but… I think most of us will use it with different purposes.

At least, to have bar charts and pie charts would be a good starting point.

I know that I can just create my own library about that but… is not worth of being implemented by Corona directly?

Would not be nice to be able to do transition.to to that object? to fill the charts nicely? Will not be used by you with a lot of nice purposes?

Just my thought about it… Hoopoe can have a good discussion about :slight_smile:

Thanks a lot in advance.

Best regards,

Juanjo

Well, I think that’s a bit personal. For me and my type of projects charts would be meaningless and thus useless. If Corona would want to cover the market of business apps more, it would be interesting. If the focus remains on games, not so much.

Either way, I do think that everything is in place to roll your own, and I prefer a lean and unbloated SDK that is extensible with plugins, as it is now.

For the record, a Bar chart object should be SUPER-easy to make.

  1. You may suggest any new feature you want and get it voted on here:

http://feedback.coronalabs.com/forums/188732-corona-sdk-feature-requests-feedback

  1. There are libraries in existence for ‘pie-chart’ like visual elements.  So, while you wait for votes on your suggestion, you could co-opt the code at the links below for your own purposes:
  1.  There was an old library here for graphing:  http://github.com/GlitchGames/GGChart

Note: Threre is a bug in the library.  To fix it, open GGChart.lua and change this:

end end return GGChart

to this:

--end end return GGChart

Ohhh thanks a lot! I was thinking about submitting it as a request but I wanted to be sure that is something that other users find useful :slight_smile:

I have checked me of the third party libraries but I was thinking more on something “native” on corona to improve the business development.

Anyway, I really appreciate all your comment.

Thanks a lot.

There are loads of HTML5/JS/CCS3 open source charting packages. Could you not create a local environment and open a webview in corona?

Too bad things are so busy on my side, because I think I would have fun knocking out a charting plugin/module for Corona!

Yes, using webView we can show the charts but what about, for example, generating some nice charts about stats in a game? Won’t be nice to have something easier form Corona directly?

Hi Juan,

Charts for a game? I thought you needed charts for a business purpose? I didn’t feel this should be native for business purposes, but for game purposes it definitely should not be in there! Game graphics need to be blingy and highly customized to the game’s design theme. Nothing that needs to be native.

Sorry, I was just thinking on different options, in my case, is for business purposes but I guess it can be applied for different goals :slight_smile:

I really think that CoronaSDK is made mainly for games… but you can also develop business apps (like I do and other people as well). From my point of view is useful to show data or stats.

About using them on game as well… well, I think is another option… most of the games have bar charts for life or other stuff so… why not?

I think it can be like a the button widget… is there, you can use it… or not. In my case… I’ve never use it but I guess is just my preference while other users use it all time.

Can we have a widget to create charts? Probably yes… depends if people need it, want it and CoronaSDK staff think that is useful.

I’ll tell you what, Juan: making a bar chart object is something I could see myself enjoying. It’s a bit busy now, but second week of october I’ll give things a whirl. Any special features you’re thinking of?

Wow that is really kind from your side! Super thanks in advance! I guess I will not be the only one super, super, super happy!

Well… honestly I’m not sure but I guess that if some of us make some petitions maybe can this become a real plugin :slight_smile:

From my side I would validate the option to do bars and pie charts and also with animation so can be “filled up”. Needs to be possible to choose colors and to have legends (optional) or lines that describe the content (mostly for pie charts).

I will add an example here that will be my dreams :slight_smile:

http://www.kfundonline.com/wp-content/uploads/2013/07/13-14-Exp-Pie-Chart-1024x835.jpg

I guess that in a chart the information about it is the most important so being able to see the values it will be a main feature.

Apart from that… imagination is the limit… using gradients, being able to choose the color of the text, detect clicks,… probably my expectations are so high!!! Now you made me dream awake :smiley:

Thanks again! And of course… no rush at all… The fact that you offered yourself is more than I was expecting! :slight_smile:

Best regards,

Just started on a rough barChart late yesterday, as part of a broader UI package. I’ll keep you guys posted!

Cheers,

Thomas

Super thanks… I do not know enough words to say it… Best community ever… and with a huge difference! :slight_smile:

Don’t thank me yet! ;)  There’s plenty of stuff to be done and I can’t give priority to this, so it might take some time!

If you’re interested, here’s my code so far:

for main.lua:

-- main.lua ----------- display.setStatusBar( display.HiddenStatusBar ) -- hide the status bar local smartUI = require("smartUI") local barChartData = { {100,50,350,80,75}, {20,85,250,100,50} } local barChart = smartUI.newBarChart(768,1024,1400,500, barChartData, 50, 15) -- (xCenter, yCenter, width, height, barChartData, padding, spacing)

and for 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' } } smartUI.newBarChart = function(xCenter, yCenter, width, height, barChartData, padding, spacing) local newBarChart = {} newBarChart.mainGroup = display.newGroup() newBarChart.mainGroup.x = xCenter newBarChart.mainGroup.y = yCenter newBarChart.backGround = display.newRect(newBarChart.mainGroup, 0, 0, width, height) --newBarChart.backGround.alpha = 0.5 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 = {} 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,100) -- 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]/100, transition = easing.inOutQuad}) end end newBarChart.axisGroup = display.newGroup() newBarChart.mainGroup:insert(newBarChart.axisGroup) -- return newBarChart end -- smartUI.newBarChart() -- -- return smartUI

This is a great start! I like the format. Keep up the great work!

Thanks Ed for the code fix. The GGChart still works pretty nicely.

Here’s a quick usage main.lua to copy.

[lua]–main.lua
local GGChart = require( “GGChart” )

—[[
local lineChart = GGChart:new
{
   type = “line”,
   mode = “standard”, --“standard”, “spark”, “xy”
   title = “Random Line Chart”,
   legend = “Green|Red|Purple”,
   legendPosition = “b”,
   dataColours = “008000,FF0000,9b59b6”,
   data = “t:0,10,20,30,40,50,60,70,80,90,100|0,5,15,20,10,50,40,85,90,95,100|40,50,80,85,90,95,100,100,100,100,100”,
   width = 320,
   height = 150,
   margins = { 20, 10, 0, 50 },
   x = 300,
   y = 200
}
–]]

—[[ CHANGE THE MODE TO GET THE 3D EFFECT
local pieChart = GGChart:new
{
   type = “pie”,
   title = “Sample Distribution - Percent”,
   legend = “39.1|41.2|9.2|6.5|4”,
   legendPosition = “r”,
   width = 320,
   height = 150,
   labels = “iOS|Android|Amazon|Nook|Windows”,
   data = “t:39.1,41.2,9.2,6.5,4”,
   mode = “2d”, --“2d”, “3d”, “concentric”
   dataColours = “e67e22|2980b9|c0392b|84BA2F|9b59b6”,
   scale = { 0, 100 },
   margins = { 20, 0, 0, 20 },
   x = 300,
   y = 400
}
–]]

—[[
local qrCode = GGChart:new
{
   type = “qr”,
   data = “http://www.coronalabs.com”,
   width = 100,
   margin = 1,
   background = “bg,s,FFFFFF”,
   errorCorrectionLevel = “L”,
   x = 200,
   y = 600
}
–]][/lua]

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!

OMG… impressive work!!! I do not know enough words… really thanks for this sir! Be sure I will not be the only one entering here everyday! :slight_smile:

Super, super thanks!

Thanks Juanjo!

My roadmap, if I find the time (and that’s a big if), is the following:

  1. Add a basic lineChart object

  2. Add a basic pieChart object

  3. Add legend objects

  4. Add functionality to redraw values, and clean removal and disposal of objects

  5. Add functionality to define or modify scale and offset on the Y axis

  6. Add some other UI elements, and better color (scheme) management.

If anyone has requests that seem valuable, feel free to post them here. I can’t guarantee development, but I’ll sure try!

There is nothing I can say just that A SUPER BIG THANKS!

For sure it will be used and a lot of people will be happy! Maybe one day will be implemented in Corona too :slight_smile:

If one day you go to Norway, let me know and you will have a beer :slight_smile: