Что нового

[Элементы GUI] Построение гистограммы

Крепыш

Новичок
Сообщения
105
Репутация
2
Версия AutoIt: 3.3.8.1

Описание: Помогите построить гистограмму по заданным значениям, типа такой:
graph.png


Примечания:
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Ну так давай больше данных. Что за гистограмма? Макс. и мин. значения? Да и вообще, что куда и для чего?
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
В Excel за две минуты такую гистограмму нарисовать!
Зачем тут AutoIt ?
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
C2H5OH
Мало ли какая задача, да и екселя может не быть на компе.
Вот UDF на эту тему:
http://www.autoitscript.com/forum/topic/79412-graph-udf-updated-141009/#entry572525
http://www.autoitscript.com/forum/topic/104399-graphgdiplus-udf-create-gdi-line-graphs/#entry738474
 

AZJIO

Меценат
Меценат
Сообщения
2,892
Репутация
1,196
Крепыш
Вот например 3D Bar Graph от taietel. А ещё:

Код:
GUICtrlCreateGraphic
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
Данные считываются из текстового файла вида:

Код:
-0.01
-0.02
-0.01
-0.02
0.01
-0.01
-0.02
0.01
-0.01
-0.01
-0.02
0.01
0.01
0.01
-0.03
0.01
0.01
0.09
-0.03
0.02
0.03
0.05
0.05
0.06
0.05
0.07
0.05
0.06
0.06
0.07

Соответственно, отрицательные значения откладываются слева от нулевой оси (красные), положительные - справа (зелёные)
Минимальных и максимальных значений нет: они могут быть любыми, может не быть положительных или отрицательных вообще. Соответственно, нужно определить максимум и минимум после чтения данных и смасштабировать оси для оптимального отображения.

Добавлено: Скриншет сделан как раз из экселя. Но нужно сделать так: текстовый файл с данными обновляется раз в сек. другим приложением. AutoIt его считывает с такой же периодичностью и перерисовывает гистограмму.

Добавлено: Сейчас посмотрю примеры...
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Что значит "обновляется" ? Дописывается? Переписывается?
Какое количество данных используется для построение гистограммы? Фиксированное?
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
Крепыш
Другое приложение - Quik?
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
C2H5OH
Переписывается. Количество значений фиксированное, но зараннее не известное.
Но это не так важно. Мне бы сейчас начертить статическую гистограмму. Для простоты можно допустить, что данные уже считаны из файла. Любые, какие вам удобно, в любом количестве.
Вот тут вот UDF и пример с гистограммой: http://www.autoitscript.com/forum/topic/79412-graph-udf-updated-141009/, но, к сожалению нет кода этого примера.

WSWR
Да, QUIK.
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
Крепыш
Вот на основе Graph UDF.au3
подставляются случайные числа.
Сразу добавлю - функционала этой UDF не достаточно, чтобы сделать "отрицательные" бары, пришлось наложить еще одну пустую диаграмму

Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Array.au3>
#include <StaticConstants.au3>
#include <Graph UDF.au3>


Global $aData[1]

$GUI_Main = GUICreate("Graph GUI", 600, 600)

$hGraph = _Graph_Create(40, 120, 520, 170)
_Graph_SetRange_X($hGraph, 1, 11, 10,3)

_Graph_SetRange_Y($hGraph, 0, 50, 10,1)

$hGraph1 = _Graph_Create(40, 290, 520, 170)
_Graph_SetRange_X($hGraph1, 1, 11, 10,1)

_Graph_SetRange_Y($hGraph1, -50, 0, 10,1)

GUISetState(@SW_SHOW)

AdlibRegister("_Data_AddPoint", 500)
AdlibRegister("_Graph_Redraw", 500)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case -3 
            Exit
		EndSwitch 			
WEnd


Func _Data_AddPoint()
ReDim $aData[UBound($aData) + 1]
$aData[UBound($aData) - 1] = Random(-30,30) ; в массив кидаются случайные числа
EndFunc

Func _Graph_Redraw()
    GUISetState(@SW_LOCK)
    _Graph_Clear($hGraph)

    _Graph_SetGrid_Y($hGraph, 10)
	_Graph_SetGrid_Y($hGraph1, 10)

    $UpperXLimit = UBound($aData) - 1
    $LowerXLimit = $UpperXLimit - 11
    If $LowerXLimit < 1 Then $LowerXLimit = 1

    If $UpperXLimit > 9 Then _Graph_SetRange_X($hGraph, $LowerXLimit, $UpperXLimit, 20,3)

    For $i = $LowerXLimit To $UpperXLimit
		Select 			
		Case $aData[$i]<0
		$color = 0xFF0000
		Case $aData[$i]>0
		$color = 0x00FF00
		EndSelect
    If $i = $LowerXLimit Then _Graph_Plot_Start($hGraph, $i, $aData[$i]) 
	_Graph_Plot_Bar_X($hGraph,$i,0.3, $aData[$i],0XFFFFFF,$color)

    Next
    _Graph_Refresh($hGraph)
    GUISetState(@SW_UNLOCK)

EndFunc


И если из квика пишется в файл, потом скрипт читает из файла - неэффективно... Это скрипт на QPILE? У него есть таблица с меняющимися значениями?
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
Ну, вот как-то так у меня получилось:

Код:
#include <Array.au3>
#include <Graph UDF.au3>

Opt("GUIOnEventMode", 1)

Local $sData = "-0.12,-0.22,-0.13,0.05,-0.04,-0.03,0.00,-0.02,-0.03,0.04,-0.03,-0.04,-0.00,-0.05,-0.00,-0.01,0.00,0.01,-0.01,0.00,-0.03,0.00,-0.00,-0.03,0.00,-0.00,-0.00,-0.01,0.01,-0.00"

Local $aData = StringSplit($sData, ",", 2)
Local $iNumberItems = UBound($aData)
Local $nLowerLimit = Floor((_ArrayMin($aData, 1)-0.01)*10)/10
Local $nUpperLimit = Ceiling((_ArrayMax($aData, 1)+0.01)*10)/10

Local $GUI_Main = GUICreate("Graph GUI", 600, 400)
GUISetOnEvent(-3,"_Exit")

Global $hGraph = _Graph_Create(12, 0, 576, 376)
_Graph_SetRange_X($hGraph, $nLowerLimit, $nUpperLimit, ($nUpperLimit-$nLowerLimit)*10, 1, 2)
_Graph_SetRange_Y($hGraph, 0, $iNumberItems, 0)

_Graph_SetGrid_X($hGraph, 0.05)

For $i = 0 To $iNumberItems-1
  Select          
    Case $aData[$i] < 0
      $sColor = 0xFF0000
    Case $aData[$i] > 0
      $sColor = 0x00FF00
  EndSelect
  _Graph_Plot_Bar_Y($hGraph, $iNumberItems-$i-1, 0.85, $aData[$i], $sColor, $sColor)
Next

_Graph_Plot_Start($hGraph, 0, 0)
_Graph_Plot_Line($hGraph, 0, $iNumberItems)

GUISetState(@SW_SHOW)

While 1
    Sleep(100)
WEnd


Func _Exit()
    _Graph_Delete($hGraph)
    GUIDelete()
    Exit
EndFunc


Чтобы отрисовывались отрицательные зачения немного изменил функцию _Graph_Plot_Bar_Y из Graph UDF.au3:

Код:
Func _Graph_Plot_Bar_Y(ByRef $aGraphArray,$iStart,$iWidth,$nYValue,$hColor = 0x000000,$hBkGrdColor = $GUI_GR_NOBKCOLOR)
;----- Draw Bar for BarChart Application -----
	_Graph_Set_Color($aGraphArray,$hColor,$hBkGrdColor)
	GUICtrlSetGraphic($aGraphArray[1],$GUI_GR_RECT, _
		_Graph_Reference_Pixel("x",0,$aGraphArray[6],$aGraphArray[7],$aGraphArray[4]), _ ;x
		_Graph_Reference_Pixel("y",$iStart + $iWidth,$aGraphArray[8],$aGraphArray[9],$aGraphArray[5]), _ ;y
		_Graph_Reference_Pixel("x",$nYValue,0,$aGraphArray[7]-$aGraphArray[6],$aGraphArray[4]) + 1, _ ;width
		_Graph_Reference_Pixel("y",$iStart,$aGraphArray[8],$aGraphArray[9],$aGraphArray[5]) - _ ;height
		_Graph_Reference_Pixel("y",$iStart + $iWidth,$aGraphArray[8],$aGraphArray[9],$aGraphArray[5]) + 1)
	;- redraw axis in case coloured -
	_Graph_Set_Color($aGraphArray,$aGraphArray[14],$GUI_GR_NOBKCOLOR)
	GUICtrlSetGraphic($aGraphArray[1],$GUI_GR_RECT,0,0,$aGraphArray[4]+1,$aGraphArray[5]+1)
	;- set colour back to default -
	_Graph_Set_Color($aGraphArray,0x000000,$GUI_GR_NOBKCOLOR)
EndFunc


WSWR, по поводу QUIK ответил в личку
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
Сделал динамически обновляемую гистограмму:

Код:
;#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Array.au3>
#include <StaticConstants.au3>
#include <Graph UDF.au3>

Opt('TrayIconDebug', 1)
Opt("GUIOnEventMode", 1)

Local $iWidth = 400
Local $iHeight = 400
Global $hGUI = GUICreate("Гистограмма", $iWidth, $iHeight, -1, -1, -1, $WS_EX_COMPOSITED)
GUISetOnEvent(-3,"_Exit")

Global $aData[31]
Global $hGraph = _Graph_Create(12, 0, $iWidth-22, $iHeight-24)
Global $iNumberItems0 = 0
Global $nUpperLimit0 = 0
Global $nLowerLimit0 = 0

GUISetState(@SW_SHOW)


While 1
  _Graph_Redraw()
  Sleep(1000)
WEnd


Func _Exit()
;  _Graph_Delete($hGraph)
;  GUIDelete()
  Exit
EndFunc

Func _Graph_Redraw()
  For $i = 0 To 30
    $aData[$i] = $aData[$i] + Random(-0.01, 0.01)
  Next
  Local $iNumberItems = UBound($aData)-1
  Local $nUpperLimit = Ceiling((_ArrayMax($aData, 1, 1)+0.001)*10)/10
  If $nUpperLimit < 0 Then
    $nUpperLimit = 0.1
  EndIf
  Local $nLowerLimit = Floor((_ArrayMin($aData, 1, 1)-0.001)*10)/10
  If $nLowerLimit > 0 Then
    $nLowerLimit = -0.1
  EndIf

  GUISetState(@SW_LOCK)
  _Graph_Clear($hGraph)
  If $iNumberItems <> $iNumberItems0 Then
    _Graph_SetRange_Y($hGraph, 0, $iNumberItems, 0)
  EndIf
  If $nLowerLimit <> $nLowerLimit0 Or $nUpperLimit <> $nUpperLimit0 Then
    _Graph_SetRange_X($hGraph, $nLowerLimit, $nUpperLimit, ($nUpperLimit-$nLowerLimit)*20, 1, 2)
  EndIf

  For $i = 1 To $iNumberItems
    Select
      Case $aData[$i] < 0
        $sColor = 0xFF0000
      Case $aData[$i] > 0
        $sColor = 0x00FF00
      Case Else
        $sColor = 0XFFFFFF
    EndSelect
    _Graph_Plot_Bar_Y_($hGraph, $iNumberItems-$i, 0.85, $aData[$i], $sColor, $sColor)
  Next

  _Graph_SetGrid_X($hGraph, 0.05)

  _Graph_Plot_Start($hGraph, 0, 0)
  _Graph_Plot_Line($hGraph, 0, $iNumberItems)

  _Graph_Refresh($hGraph)
  GUISetState(@SW_UNLOCK)

  $iNumberItems0 = $iNumberItems
  $nLowerLimit0 = $nLowerLimit
  $nUpperLimit0 = $nUpperLimit
EndFunc

Func _Graph_Plot_Bar_Y_(ByRef $aGraphArray,$iStart,$iWidth,$nYValue,$hColor = 0x000000,$hBkGrdColor = $GUI_GR_NOBKCOLOR)
;----- Draw Bar for BarChart Application -----
	_Graph_Set_Color($aGraphArray,$hColor,$hBkGrdColor)
	GUICtrlSetGraphic($aGraphArray[1],$GUI_GR_RECT, _
		_Graph_Reference_Pixel("x",0,$aGraphArray[6],$aGraphArray[7],$aGraphArray[4]), _ ;x
		_Graph_Reference_Pixel("y",$iStart + $iWidth,$aGraphArray[8],$aGraphArray[9],$aGraphArray[5]), _ ;y
		_Graph_Reference_Pixel("x",$nYValue,0,$aGraphArray[7]-$aGraphArray[6],$aGraphArray[4]) + 1, _ ;width
		_Graph_Reference_Pixel("y",$iStart,$aGraphArray[8],$aGraphArray[9],$aGraphArray[5]) - _ ;height
		_Graph_Reference_Pixel("y",$iStart + $iWidth,$aGraphArray[8],$aGraphArray[9],$aGraphArray[5]) + 1)
	;- redraw axis in case coloured -
	_Graph_Set_Color($aGraphArray,$aGraphArray[14],$GUI_GR_NOBKCOLOR)
	GUICtrlSetGraphic($aGraphArray[1],$GUI_GR_RECT,0,0,$aGraphArray[4]+1,$aGraphArray[5]+1)
	;- set colour back to default -
	_Graph_Set_Color($aGraphArray,0x000000,$GUI_GR_NOBKCOLOR)
EndFunc


Нужно ли при выходе из программы удалять окно GUI и все его элементы или достаточно просто Exit?

В некоторых приложениях, например, Total Commander, наблюдается мерцание, если Total Commander расположен поверх гистограммы. Как избавиться от этого мерцания?
 
Верх