/adei/trunk

To get this branch, use:
bzr branch http://darksoft.org/webbzr/adei/trunk

« back to all changes in this revision

Viewing changes to classes/views/calcview.php

  • Committer: Suren A. Chilingaryan
  • Date: 2020-02-06 06:10:37 UTC
  • Revision ID: csa@suren.me-20200206061037-eoniyzu03w69rkrj
Adapt calcview from ASEC setup and make it use new abstracted helpers

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
<?php
2
2
global $ADEI_ROOTDIR;
3
 
require_once($ADEI_ROOTDIR . "/classes/jpgraph.php");
 
3
require_once($ADEI_ROOTDIR . "/classes/views/basetimeseriesview.php");
4
4
 
5
5
abstract class AggregationMethods
6
6
{
16
16
    }
17
17
}
18
18
 
19
 
class CALCView extends VIEW
 
19
class CALCView extends BASETimeSeriesView
20
20
{
21
 
    var $raw_data;
22
 
    
23
 
    const small_window_threshold = 400;
24
21
    function __construct(REQUEST $req = NULL, $options)
25
22
    {
26
 
 
27
 
        $this->raw_data = $this->GetOption('raw_data', false);
28
23
        parent::__construct($req, $options);
29
24
    }
30
25
 
31
26
    function GetOptions()
32
27
    {
 
28
        global $GRAPH_MARGINS;
33
29
        $chan = $this->GetDataVariants(array("x", "y"));
34
30
 
 
31
        $req = $this->req->CreateDataRequest();
 
32
        
 
33
        $ymargin = $this->GetYAxisLabelsWidth($this->GetYAxisFormat());
 
34
        $xmargin = $this->GetTimeAxisLabelsWidth($this->GetTimeAxisFormat($this->ivl));
 
35
        
 
36
        $ylabel_margin = $req->GetProp("view_ylabelmargin", 0);
 
37
        $xlabel_margin = $req->GetProp("view_xlabelmargin", 0);
 
38
 
35
39
        return array(
36
40
            array("select" => array("label" => _("X"), "id" => "x", "options" => $chan[0])),
37
41
            array("xml" => "<br/>"),
38
42
            array("select" => array("label" => _("Y"), "id" => "y", "options" => $chan[1])),
39
43
            array("xml" => "<br/>"),
40
 
            array("select" => array("label" => _("Aggregation Method"), "id" => "channel_aggregation", "options" => AggregationMethods::GetSelectOptions())),
41
 
            array("xml" => "<br/>"),
42
 
            array("input" => array("label" => _("Math Function"), "id" => "math_func", "type" => "text", "size" => "8", "value" => "")),
43
 
            array("xml" => "<br/>"),
 
44
            array("select" => array("label" => _("Aggregation Method"), "id" => "channel_aggregation", "options" => RESAMPLER::GetSelectList())),
 
45
            array("xml" => "<br/>"),
 
46
            array("input" => array("label" => _("Function"), "id" => "math_func", "type" => "text", "size" => "20", "value" => "")),
 
47
            array("xml" => "<br/>"),
 
48
            array("input" => array("label" => _("X-axis Title"), "id" => "xlabel", "type" => "text", "size" => "8", "value" => "")),
 
49
            array("input" => array("label" => _(" Offset ($xmargin) correction"), "id" => "xlabelmargin", "type" => "text", "size" => "8", "value" => "$xlabel_margin")),
 
50
            array("xml" => "<br/>"),
 
51
            array("input" => array("label" => _("Y-axis Title"), "id" => "ylabel", "type" => "text", "size" => "8", "value" => "")),
 
52
            array("input" => array("label" => _(" Offset ($ymargin) correction"), "id" => "ylabelmargin", "type" => "text", "size" => "8", "value" => "$ylabel_margin")),
 
53
            array("xml" => "<br/>"),
 
54
 
44
55
        );
45
56
    }
46
57
 
49
60
        $req = $this->req->CreateDataRequest();
50
61
        $agg = $req->GetProp("view_channel_aggregation", false);
51
62
        $this->math_func = $req->GetProp("view_math_func", false);
52
 
 
53
 
        if (!$this->math_func) {
54
 
            return array("info" => "Math Function is empty!");
55
 
        }
56
 
 
57
63
        $x = $req->GetProp("view_x", false);
58
64
        $y = $req->GetProp("view_y", false);
59
65
 
60
66
        if (!$x) throw new ADEIException(translate("Parameters view_x are not set"));
61
 
 
62
67
        if (!$y) throw new ADEIException(translate("Parameters view_y are not set"));
 
68
        if (!$this->math_func) throw new ADEIException(translate("Arithmetic operation is not specified"));
63
69
 
64
70
        $func = dsMathCreateFunction('$x,$y', $this->math_func);
65
 
        $res = $this->GetData(array("x", "y"), NULL, ($this->raw_data?VIEW::GET_RAW_DATA:0));
 
71
        if (!$func) throw new ADEIException(translate("Can't parse function %s", $this->math_func));
66
72
 
67
 
        $total = 0;
68
 
        $missing = 0;
 
73
        $res_full = $this->GetData(array("x", "y"), NULL, VIEW::GET_RAW_DATA);
 
74
        $total = sizeof($res_full['data']);
 
75
        $res = $this->ResampleData($res_full, $agg);
 
76
        $missing = $res['info']['incomplete'];
 
77
        
69
78
        $data = array();
70
 
 
71
 
        switch ($agg) {
72
 
            case AggregationMethods::SkipMissing:
73
 
                foreach ($res['data'] as $t => $v) {
74
 
                    $cond = is_numeric($v[0]) && is_numeric($v[1]);
75
 
                    if ($cond) {
76
 
                        $point = $func($v[0], $v[1]);
77
 
                        $total++;
78
 
                        $data[$t] = $point;
79
 
                    } else {
80
 
                        $missing++;
81
 
                    }
82
 
                }
83
 
                break;
84
 
            case AggregationMethods::UseLast:
85
 
                $raw_data = $res['data'];
86
 
                $raw_data_keys = array_keys($raw_data);
87
 
                $raw_data_values = array_values($raw_data);
88
 
                for ($i = 0; $i < sizeof($raw_data_values); $i++) {
89
 
                    $key = $raw_data_keys[$i];
90
 
                    $v = &$raw_data_values[$i];
91
 
                    
92
 
                    if(!is_numeric($v[0]) || !is_numeric($v[1])) {
93
 
                        $missing++;
94
 
                    }
95
 
 
96
 
                    if (!is_numeric($v[0]) && $i > 0) {
97
 
                        $v[0] = $raw_data_values[$i - 1][0];
98
 
                    }
99
 
 
100
 
                    if (!is_numeric($v[1]) && $i > 0) {
101
 
                        $v[1] = $raw_data_values[$i - 1][1];
102
 
                    }
103
 
 
104
 
                    $point = $func($v[0], $v[1]);
105
 
                    $total++;
106
 
                    $data[$key] = $point;
107
 
                }
108
 
                break;
109
 
        }
110
 
 
111
 
        ksort($data);
112
 
        $el_parent_x = '';
113
 
        $el_x = '';
 
79
        foreach ($res['data'] as $t => $v) {
 
80
            $point = $func($v[0], $v[1]);
 
81
            $data[$t] = $point;
 
82
        }
 
83
        ksort($data);
 
84
 
 
85
        $el_parent_x = '';
 
86
        $el_x = '';
114
87
        $el_parent_y = '';
115
 
        $el_y = '';
 
88
        $el_y = '';
116
89
        $arr = $this->GetOptions();
117
90
        foreach ($arr[0]['select']['options'] as $x_key => $x_lv) {
118
 
            $el = $arr[0]['select']['options'][$x_key];
 
91
            $el = $arr[0]['select']['options'][$x_key];
119
92
            if ($el["disabled"] == 1) {
120
93
                $el_parent_x = $el['label'];
121
 
            } elseif ($el['value'] == $x) {
122
 
                $el_x = $el['label'];
123
 
                break;
124
 
            }
 
94
            } elseif ($el['value'] == $x) {
 
95
                $el_x = $el['label'];
 
96
                break;
 
97
            }
125
98
        }
126
99
 
127
100
        foreach ($arr[2]['select']['options'] as $y_key => $y_lv) {
128
 
            $el = $arr[2]['select']['options'][$y_key];
129
 
            if ($el["disabled"] == 1){
 
101
            $el = $arr[2]['select']['options'][$y_key];
 
102
            if ($el["disabled"] == 1) {
130
103
                $el_parent_y = $el['label'];
131
104
            } elseif ($el['value'] == $y) {
132
 
                $el_y = $el["label"];
133
 
                break;
 
105
                $el_y = $el["label"];
 
106
                break;
134
107
            }
135
108
        }
136
109
 
137
 
        $info = array(
138
 
            array("title" => _("Data Points"), "value" => "$total (of $this->max_points)"),
139
 
            array("title" => _("Missing Values"), "value" => "$missing"),
140
 
            array("title" => _("Formula"), "value" => "$this->math_func"),
141
 
            array("title" => _("x"), "value" => "$el_parent_x - $el_x"),
142
 
            array("title" => _("y"), "value" => "$el_parent_y - $el_y"),
143
 
        );
 
110
        $info = array(
 
111
            array("title" => _("Data Records"), "value" => "$total (of $this->max_points)"),
 
112
            array("title" => _("Skipped Incomplete"), "value" => "$missing"),
 
113
            array("title" => _("Operation"), "value" => "$this->math_func"),
 
114
            array("title" => _("x"), "value" => "$el_parent_x - $el_x"),
 
115
            array("title" => _("y"), "value" => "$el_parent_y - $el_y"),
 
116
        );
144
117
 
145
118
        if (sizeof($data) == 0) {
146
119
            return array("info" => $info);
147
120
        }
148
121
 
149
 
        $from = date("D, d M Y H:i:s", key($data));
150
 
        end($data);
151
 
        $to = date("D, d M Y H:i:s", key($data));
152
 
        reset($data);
153
 
        $info = array_merge($info, array(
154
 
                array("title" => _("From"), "value" => "$from"),
155
 
                array("title" => _("To"), "value" => "$to"))
156
 
        );
 
122
        $from = date("D, d M Y H:i:s", key($data));
 
123
        end($data);
 
124
        $to = date("D, d M Y H:i:s", key($data));
 
125
        reset($data);
 
126
        $info = array_merge($info, array(
 
127
            array("title" => _("From"), "value" => "$from"),
 
128
            array("title" => _("To"), "value" => "$to")
 
129
        ));
157
130
 
158
131
        $view = $this->GetGraphView($data, $req);
159
 
        $view["info"] = $info;
 
132
        $view["info"] = $info;
160
133
        return $view;
161
134
    }
162
135
 
163
 
    private function GetTicks($width, $length, $min_tick) {
164
 
        $n_ticks = $width / 40;
165
 
        if (!$n_ticks) $n_ticks = 1;
166
 
        $tick_step = $length / $n_ticks;
167
 
        return $min_tick * ceil($tick_step / $min_tick);
168
 
    }
169
 
 
170
136
    private function GetGraphView($data, $req)
171
137
    {
 
138
        global $GRAPH_MARGINS;
172
139
        global $TMP_PATH;
173
 
        global $GRAPH_SUBSECOND_THRESHOLD;
174
 
        $tmp_file = ADEI::GetTmpFile();
175
 
        
176
 
        $x = $req->GetProp("view_x", false);
177
 
        $y = $req->GetProp("view_y", false);
178
 
 
179
 
        if ($this->object) {
180
 
            $width = $req->GetProp($this->object . "_width", $this->min_width + 20) - 20;
181
 
            if ($width < $this->min_width) $width = $this->min_width;
182
 
            $height = $width - 40;
183
 
        } else {
184
 
            $width = $req->GetProp("page_width", $this->min_width + 5) - 5;
185
 
            $height = $req->GetProp("page_height", $this->min_height);
186
 
            if ($width < $this->min_width) $width = $this->min_width;
187
 
            if ($height < $this->min_height) $height = $this->min_height;
188
 
        }
189
 
        $length = $this->ivl->GetWindowSize();
190
 
 
191
 
        $graph = new Graph($width, $height);
192
 
        if ($length < $GRAPH_SUBSECOND_THRESHOLD)
193
 
            $graph->SetScale('linlin');
194
 
        else
195
 
            $graph->SetScale('datlin');
196
 
        $graph->xaxis->SetPos('min');
197
 
        $graph->xaxis->SetLabelAngle(90);
198
 
        $graph->xaxis->title->SetFont(FF_ARIAL, FS_BOLD);
199
 
        $graph->yaxis->title->SetFont(FF_ARIAL, FS_BOLD);
200
 
        $graph->xaxis->SetTextLabelInterval(1);
 
140
        global $GRAPH_SUBSECOND_THRESHOLD;
201
141
 
202
142
        $ydata = array_values($data);
203
143
        $xdata = array_keys($data);
204
144
 
205
 
        $graph->img->SetMargin(60, 10, 15, 60);
206
 
        $graph->title->Set("$this->math_func");
207
 
 
208
 
        if ($length > 315360000) { // 10 years
209
 
            $graph->xaxis->scale->SetDateFormat('Y');
210
 
            $graph->xaxis->scale->ticks->Set($this->GetTicks($width, $length, 315360000), 315360000);
211
 
        } elseif ($length > 31104000) { // 1 year
212
 
            $graph->xaxis->scale->SetDateFormat('M, Y');
213
 
            $graph->xaxis->scale->ticks->Set($this->GetTicks($width, $length, 3104000), 3104000);
214
 
        } elseif ($length > 1036800) { // 12 days
215
 
            $graph->xaxis->scale->SetDateFormat('M d');
216
 
            $graph->xaxis->scale->ticks->Set($this->GetTicks($width, $length, 3600 * 24), 3600 * 24);
217
 
        } elseif ($length > 86400) { // 1 day
218
 
            $graph->xaxis->scale->SetDateFormat('M d, H:i');
219
 
            $graph->img->SetMargin(60, 10, 15, 100);
220
 
            $graph->xaxis->scale->ticks->Set($this->GetTicks($width, $length, 3600 * 4), 3600 * 4);
221
 
        } elseif ($length > 14400) { // 4 hours
222
 
            $graph->xaxis->scale->SetDateFormat('H:i');
223
 
            $graph->xaxis->scale->ticks->Set($this->GetTicks($width, $length, 1800), 1800);
224
 
        } elseif ($length > $GRAPH_SUBSECOND_THRESHOLD) {
225
 
            $graph->xaxis->scale->SetDateFormat('H:i:s');
226
 
            $graph->xaxis->scale->ticks->Set($this->GetTicks($width, $length, $GRAPH_SUBSECOND_THRESHOLD), $GRAPH_SUBSECOND_THRESHOLD);
227
 
        } else {
228
 
            $from = $xdata[0];
229
 
            foreach ($xdata as &$x) $x = dsMathPreciseSubstract($x, $from);
230
 
        }
 
145
        $tmp_file = ADEI::GetTmpFile();
 
146
        $x = $req->GetProp("view_x", false);
 
147
        $y = $req->GetProp("view_y", false);
 
148
 
 
149
        $graph = new Graph($this->width, $this->height);
 
150
        $time_axis_format = $this->ConfigureTimeAxis($graph, $this->ivl, $this->width);
 
151
        $y_axis_format = $this->ConfigureYAxis($graph, $graph->yaxis, array(min($ydata), max($ydata)), $this->height);
 
152
 
 
153
//        $ydata = array_merge(array(''), $ydata, array(''));
 
154
//        $xdata = array_merge(array($this->ivl->GetWindowStart()), $xdata, array($this->ivl->GetWindowEnd()));
 
155
 
 
156
        if ($time_axis_format['time_format'] === false) {
 
157
            $from = $xdata[0];
 
158
            foreach ($xdata as &$x) $x = dsMathPreciseSubstract($x, $from);
 
159
        }
 
160
 
 
161
        $xlabel = $req->GetProp("view_xlabel", false);
 
162
        $xlabel_margin = $time_axis_format['labels_width'] + $req->GetProp("view_xlabelmargin", 0);
 
163
        if ($xlabel) $xlabel_margin = $this->ConfigureXAxisTitle($graph, $xlabel, $xlabel_margin);
 
164
 
 
165
        $ylabel = $req->GetProp("view_ylabel", false);
 
166
        $ylabel_margin = $y_axis_format['labels_width'] + $req->GetProp("view_ylabelmargin", 0);
 
167
        if ($ylabel) $ylabel_margin = $this->ConfigureYAxisTitle($graph, $graph->yaxis, $ylabel, $ylabel_margin);
 
168
 
 
169
        //$graph->title->Set("$this->math_func");
 
170
        $graph->img->SetMargin($ylabel_margin, 10, 20, $xlabel_margin + 10);
231
171
 
232
172
        $lineplot = new LinePlot($ydata, $xdata);
233
173
        $graph->Add($lineplot);
237
177
            "img" => array("id" => $tmp_file)
238
178
        );
239
179
    }
 
180
 
240
181
};