Jump to content

Line chart


abu5lf

Recommended Posts

  • MTA Team

You have to use DirectX functions. First draw all the background and then draw all the values into that chart.

I am not going into the maths, because that's your job (you can still ask for small help on the calculation).

Link to comment
You have to use DirectX functions. First draw all the background and then draw all the values into that chart.

I am not going into the maths, because that's your job (you can still ask for small help on the calculation).

I know this functions, but I'm bad on maths.

Can you give me e.g?

Link to comment
  • MTA Team

Pick a width and a height. Find the lowest and highest values in the range. Divide the width by the amount of values you have for that range to get the width per column. Divide the the height by some random number you pick and to get a height per row.

Then iterate through your values. Calculate the height for your chartvalue by doing chart_height * (row_value / highest_row_value). You can also save the last height to connect the last point with the next point.

Need more?

Edited by Guest
Link to comment

I have the following code:

width, height = 450, 300 -- Pick a width and a height. 
lowWidth , higheight = { 1, 450 }, { 1, 300 } -- Find the lowest and highest values in the range 
  
function lineChart( ) 
    row_value = width / ( lowWidth[1] / lowWidth[2] ) / ( higheight[1] / higheight[2] ) -- Divide the width by the amount of values you have for that range to get the width per column 
    highest_row_value = height / math.random( 100 ) -- Divide the the height by some random number you pick and to get a height per row. 
    chart_height = ( row_value + highest_row_value ) 
  
    value = chart_height * (row_value / highest_row_value)-- Calculate the height for your chartvalue by doing chart_height * (row_value / highest_row_value). You can also save the last height to connect the last point with the next point. 
    dxDrawRectangle( 200, 200, width, height, tocolor( 100, 100, 100, 200 ) ) 
    dxDrawLine( 200, 200, value / highest_row_value, value ) 
end 
addEventHandler( "onClientRender", root, lineChart ) 

Link to comment
  • MTA Team

I took the time and made a small script with render targets.

Preview: (http://i.imgur.com/XYxLk4g.png)

XYxLk4g.png

Code:

Pastebin: Link

  
-- Warning, render targets require you to write into the meta.xml a min. version 
--  or  
  
-- Get the screen size 
local screenWidth, screenHeight = guiGetScreenSize() 
  
-- Resolution independet solution for width & height of the chart box 
local box_width = (screenWidth * 0.75) 
local box_height = (screenHeight * 0.50) 
  
-- Number of rows 
local chart_rows = 10 
  
-- Colors in the chart 
local colors = { 
    background = tocolor(255, 255, 255, 255), 
    coordline = tocolor(0, 0, 0, 255), 
    titlecolor = tocolor(0, 0, 0, 255), 
    gridline = tocolor(0, 0, 0, 5), 
    valueline = tocolor(255, 0, 0, 255), 
    rowvalue = tocolor(0, 0, 0, 255), 
} 
  
-- Cache variables 
local lowest_value = false 
local highest_value = false 
local chart_title = false 
local chart_columns = false 
local chart_data = false 
local title_height = false 
local rendertarget = false 
  
-- Cache a table with raw number values 
function cacheChartData(title, data) 
    -- Reset cache 
    lowest_value = false 
    highest_value = false 
  
    -- Find highest and lowest values 
    for i = 1, #data do 
        if (not lowest_value or data[i] < lowest_value) then 
            lowest_value = data[i] 
        end 
        if (not highest_value or data[i] > highest_value) then 
            highest_value = data[i] 
        end 
    end 
  
    -- Apply the data 
    chart_data = data 
     
    -- Calculate the number of columns 
    chart_columns = #data - 1 
  
    -- Apply the chart title 
    chart_title = title 
  
    -- Calculate the chart title height 
    title_height = dxGetFontHeight(3, "default-bold") 
  
    -- Draw the chart into a rendertarget 
    cacheChartDrawing() 
end 
  
-- Render the chart into a render target 
function cacheChartDrawing(cleared) 
    -- Event call detection 
    if (type(cleared) == "boolean") then 
        -- Do nothing if the render target is still intact 
        if (not cleared) then 
            return 
        end 
  
        -- Change the value so we know we don't have to re-create the r. t. 
        cleared = true 
    end 
  
    -- Destroy the old version (if neccessary) 
    if (not cleared) then 
        if (isElement(rendertarget)) then 
            destroyElement(rendertarget) 
        end 
  
        -- Create a new rendertarget 
        rendertarget = dxCreateRenderTarget(box_width, box_height, true) 
    end 
  
    -- Abort if the render target is invalid 
    if (not rendertarget) then 
        return 
    -- Else switch to the render target 
    else 
        dxSetRenderTarget(rendertarget) 
    end 
  
    -- Draw the background 
    dxDrawRectangle(0, 0, box_width, box_height, colors.background) 
  
    -- Define a general padding to the content 
    local padding = 0.10 * box_height 
  
    -- Calculate the width of the highest number 
    local left_width = dxGetTextWidth(tostring(highest_value), 1, "default") 
  
    -- Calculate the height of the chart and the 0 coordinate position 
    local chart_height = (box_height - (padding * 2) - title_height) 
    local chart_y = (box_height - padding) 
  
    -- Calculate the width of the chart and the 0 coordinate position 
    local chart_width = (box_width - (padding * 2) - left_width) 
    local chart_x = (padding + left_width) 
  
    -- Draw the chart title 
    dxDrawText(chart_title, 0, (padding / 2), box_width, (padding / 2) + title_height, colors.titlecolor, 3, "default-bold", "center", "center", false, false, false, true) 
  
    -- Draw the x and y lines 
    dxDrawLine(chart_x, chart_y, chart_x + chart_width, chart_y, colors.coordline, 2) 
    dxDrawLine(chart_x, chart_y - chart_height, chart_x, chart_y, colors.coordline, 2) 
  
    -- Calculate the width and height for each cell 
    local column_width = (chart_width / chart_columns) 
    local column_height = (chart_height / chart_rows) 
  
    -- Draw the grid 
    for i = 0, chart_columns do 
        for j = 0, chart_rows do 
            -- Draw the column line 
            dxDrawLine(chart_x + (i * column_width), chart_y - chart_height, chart_x + (i * column_width), chart_y, colors.gridline) 
  
            -- Draw the row line 
            dxDrawLine(chart_x, chart_y - (j * column_height), chart_x + chart_width, chart_y - (j * column_height), colors.gridline) 
        end 
    end 
  
    -- Draw the highest value 
    dxDrawText(tostring(highest_value), padding, chart_y - chart_height, padding / 2 + left_width, chart_y - chart_height, colors.rowvalue, 1, "default", "center", "center", false, false, false, true) 
  
    -- Draw the values for the other rows 
    for i = 0, (chart_rows - 1) do 
        dxDrawText(("%.2f"):format((i / chart_rows) * highest_value), padding, chart_y - (column_height * i), padding / 2 + left_width, chart_y - (column_height * i), colors.rowvalue, 1, "default", "center", "center", false, false, false, true) 
    end 
  
    -- Cache for the last height 
    local last_height = false 
  
    -- Draw the value line 
    for i = 0, chart_columns do 
        -- Calculate the height 
        local height = (chart_data[i + 1] / highest_value) * chart_height 
  
        -- Draw a line if we have a last height 
        if (last_height) then 
            dxDrawLine(chart_x + ((i - 1) * column_width), chart_y - last_height, chart_x + (i * column_width), chart_y - height, colors.valueline, 2) 
        end 
  
        -- Save the height for the next value 
        last_height = height 
    end 
     
    -- Reset the render target 
    dxSetRenderTarget() 
end 
  
function renderChart() 
    -- Nothing cached 
    if (not rendertarget) then 
        return 
    end 
  
    -- Calculate the position (not efficient to do here, but fuck that) 
    local x = (screenWidth - box_width) / 2 
    local y = (screenHeight - box_height) / 2 
  
    -- Draw the render target 
    dxDrawImage(x, y, box_width, box_height, rendertarget) 
end 
  
addEventHandler("onClientResourceStart", resourceRoot, 
    function () 
        -- Example 
        cacheChartData("Fancy Chart Title", { 
            5, 10, 20, 6, 1, 19, 30, 15, 120, 59, 12, 22, 125, 12 
        }) 
  
        -- Events 
        addEventHandler("onClientRender", root, renderChart) 
        addEventHandler("onClientRestore", root, cacheChartDrawing) 
    end 
) 
  

Link to comment
  • MTA Team

Well, I already made a chart script in the past and I still could recall how to calculate the values + how to script in MTA.

Back then I thought how to calculate the height and other values (that's really basic percentage maths).

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...