using Base import Luxor as L """ Colour of a component given its fluctuations """ function colour_of_diff(diff::Real)::Tuple{Real,Real,Real} if diff > 0 return (0.5,1,0.5) else return (1,0.5,0.5) end end component_text_size = 20 @kwdef struct Component pos::Tuple{UInt, UInt} size::Tuple{UInt, UInt} name::String diff::Real end sector_title_font_size = 16 sector_title_height = 20 @kwdef struct Sector name::String pos::Tuple{UInt, UInt} size::Tuple{UInt, UInt} components::Array{Component} end @kwdef struct CompositionDiagram sectors::Array{Sector} end """ Draws stock index composition chart """ function draw(diagram::CompositionDiagram, size=(800, 600)) L.Drawing(size[1], size[2], :png) L.background("black") for sector in diagram.sectors L.sethue("gray") L.rect(L.Point(sector.pos), sector.size[1], sector.size[2], action = :fillpreserve) L.setline(2) L.strokepath() L.sethue("white") L.setfont("Helvetica", sector_title_font_size) L.settext( sector.name, L.Point(sector.pos), halign="left", valign="top", ) L.setfont("Helvetica", component_text_size) for component in sector.components pos = sector.pos .+ component.pos L.setcolor(colour_of_diff(component.diff)) L.rect(L.Point(pos), component.size[1], component.size[2], action = :fillpreserve) L.sethue("white") L.setline(5) L.strokepath() L.settext( component.name, L.Point(pos .+ component.size ./ 2), halign="center", valign="bottom", ) L.settext( "$(component.diff)%", L.Point(pos .+ component.size ./ 2), halign="center", valign="top", ) end end L.finish() end diagram = CompositionDiagram( sectors=[ Sector( name="technology", pos=(0,0), size=(200,300), components=[ Component(pos=(0,20), size=(200,200),name="AAPL", diff=0.5), Component(pos=(0,200), size=(200,100),name="GOOG", diff=-0.3), ], ), Sector( name="resources", pos=(200,0), size=(200,200), components=[ Component(pos=(0,20), size=(200,150),name="OIL", diff=0.1), ], ), ], ) draw(diagram)