Completed
Push — master ( 249923...ac15b4 )
by Jeroen De
135:11 queued 115:11
created

formats/timeseries/SRF_Timeseries.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * A query printer for timeseries using the flot plotting JavaScript library
5
 *
6
 * @see http://www.semantic-mediawiki.org/wiki/Help:Flot_timeseries_chart
7
 * @licence GNU GPL v2 or later
8
 *
9
 * @since 1.8
10
 *
11
 * @author mwjames
12
 */
13
class SRFTimeseries extends SMWResultPrinter {
14
15
	/**
16
	 * @see SMWResultPrinter::getName
17
	 * @return string
18
	 */
19
	public function getName() {
20
		return wfMessage( 'srf-printername-timeseries' )->text();
21
	}
22
23
	/**
24
	 * @see SMWResultPrinter::getResultText
25
	 *
26
	 * @param SMWQueryResult $result
27
	 * @param $outputMode
28
	 *
29
	 * @return string
30
	 */
31
	protected function getResultText( SMWQueryResult $result, $outputMode ) {
32
33
		// Data processing
34
		$data = $this->getAggregatedTimeSeries( $result, $outputMode );
35
36
		// Post-data processing check
37
		if ( $data === [] ) {
38
			return $result->addErrors( [ wfMessage( 'srf-warn-empy-chart' )->inContentLanguage()->text() ] );
39
		} else {
40
			$options['sask'] = SRFUtils::htmlQueryResultLink( $this->getLink( $result, SMW_OUTPUT_HTML ) );
41
			return $this->getFormatOutput( $data, $options );
42
		}
43
	}
44
45
	/**
46
	 * Returns an array with numerical data
47
	 *
48
	 * @since 1.8
49
	 *
50
	 * @param SMWQueryResult $result
51
	 * @param $outputMode
52
	 *
53
	 * @return array
54
	 */
55
	protected function getAggregatedTimeSeries( SMWQueryResult $result, $outputMode ) {
56
		$values = [];
57
		$aggregatedValues =  [];
58
59
		while ( /* array of SMWResultArray */ $row = $result->getNext() ) { // Objects (pages)
60
			$timeStamp = '';
61
			$value     = '';
0 ignored issues
show
$value is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
62
			$series = [];
63
64
			foreach ( $row as /* SMWResultArray */ $field ) {
65
				$value  = [];
0 ignored issues
show
$value is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
66
				$sum    = [];
67
				$rowSum = [];
0 ignored issues
show
$rowSum is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
68
69
				// Group by subject (page object)  or property
70
				if ( $this->params['group'] == 'subject' ){
71
					$group = $field->getResultSubject()->getTitle()->getText();
72
				} else {
73
					$group = $field->getPrintRequest()->getLabel();
74
				}
75
76
				while ( ( /* SMWDataValue */ $dataValue = $field->getNextDataValue() ) !== false ) { // Data values
77
78
					// Find the timestamp
79
					if ( $dataValue->getDataItem()->getDIType() == SMWDataItem::TYPE_TIME ){
80
						// We work with a timestamp, we have to use intval because DataItem
81
						// returns a string but we want a numeric representation of the timestamp
82
						$timeStamp = intval( $dataValue->getDataItem()->getMwTimestamp() );
83
					}
84
85
					// Find the values (numbers only)
86
					if ( $dataValue->getDataItem()->getDIType() == SMWDataItem::TYPE_NUMBER ){
87
						$sum[] = $dataValue->getNumber();
88
					}
89
				}
90
				// Aggegate individual values into a sum
91
				$rowSum = array_sum( $sum );
92
93
				// Check the sum and threshold/min
94
				if ( $timeStamp !== '' && $field->getPrintRequest()->getTypeID() !== '_dat' && $rowSum >= $this->params['min'] ) {
95
					$series[$group] =  [ $timeStamp , $rowSum ] ;
96
				}
97
			}
98
				$values[] = $series ;
99
		}
100
101
		// Re-assign values according to their group
102
		foreach ( $values as $key => $value ) {
103
			foreach ( $values[$key] as $row => $rowvalue ) {
104
					$aggregatedValues[$row][] = $rowvalue;
105
			}
106
		}
107
		return $aggregatedValues;
108
	}
109
110
	/**
111
	 * Prepare data for the output
112
	 *
113
	 * @since 1.8
114
	 *
115
	 * @param array $data
116
	 *
117
	 * @return string
118
	 */
119
	protected function getFormatOutput( array $data, $options ) {
120
121
		// Object count
122
		static $statNr = 0;
123
		$chartID = 'timeseries-' . ++$statNr;
124
125
		$this->isHTML = true;
126
127
		// Reorganize the raw data
128
		foreach ( $data as $key => $values ) {
129
			$dataObject[] =  [ 'label' => $key, 'data' => $values ];
130
		}
131
132
		// Series colour
133
		$seriescolors = $this->params['chartcolor'] !== '' ? array_filter( explode( "," , $this->params['chartcolor'] ) ) : [];
134
135
		// Prepare transfer array
136
		$chartData =  [
137
			'data' => $dataObject,
138
			'fcolumntypeid' => '_dat',
139
			'sask' => $options['sask'],
140
			'parameters' =>  [
141
				'width'        => $this->params['width'],
142
				'height'       => $this->params['height'],
143
				'charttitle'   => $this->params['charttitle'],
144
				'charttext'    => $this->params['charttext'],
145
				'infotext'     => $this->params['infotext'],
146
				'charttype'    => $this->params['charttype'],
147
				'gridview'     => $this->params['gridview'],
148
				'zoom'         => $this->params['zoompane'],
149
				'seriescolors' => $seriescolors
150
			]
151
		];
152
153
		// Array encoding and output
154
		$requireHeadItem =  [ $chartID => FormatJson::encode( $chartData ) ];
155
		SMWOutputs::requireHeadItem( $chartID, Skin::makeVariablesScript( $requireHeadItem ) );
156
157
		// RL module
158
		SMWOutputs::requireResource( 'ext.srf.timeseries.flot' );
159
160
		if ( $this->params['gridview'] === 'tabs' ) {
161
			SMWOutputs::requireResource( 'ext.srf.util.grid' );
162
		}
163
164
		// Chart/graph placeholder
165
		$chart = Html::rawElement( 'div', [
166
			'id' => $chartID,
167
			'class' => 'container',
168
			'style' => "display:none;"
169
			], null
170
		);
171
172
		// Processing/loading image
173
		$processing = SRFUtils::htmlProcessingElement( $this->isHTML );
174
175
		// Beautify class selector
176
		$class = $this->params['class'] ? ' ' . $this->params['class'] : ' flot-chart-common';
177
178
		// General output marker
179
		return Html::rawElement( 'div', [
180
			'class' => 'srf-timeseries' . $class
181
			], $processing . $chart
182
		);
183
	}
184
185
	/**
186
	 * @see SMWResultPrinter::getParamDefinitions
187
	 *
188
	 * @since 1.8
189
	 *
190
	 * @param $definitions array of IParamDefinition
191
	 *
192
	 * @return array of IParamDefinition|array
193
	 */
194
	public function getParamDefinitions( array $definitions ) {
195
		$params = parent::getParamDefinitions( $definitions );
196
197
		$params['charttype'] = [
198
			'message' => 'srf-paramdesc-layout',
199
			'default' => 'line',
200
			'values' => [ 'line', 'bar'],
201
		];
202
203
		$params['min'] = [
204
			'type' => 'integer',
205
			'message' => 'srf-paramdesc-minvalue',
206
			'default' => '',
207
		];
208
209
		$params['gridview'] = [
210
			'message' => 'srf-paramdesc-gridview',
211
			'default' => 'none',
212
			'values' => [ 'none' , 'tabs' ],
213
		];
214
215
		$params['group'] = [
216
			'message' => 'srf-paramdesc-group',
217
			'default' => 'subject',
218
			'values' => [ 'property' , 'subject' ],
219
		];
220
221
		$params['zoompane'] = [
222
			'message' => 'srf-paramdesc-zoompane',
223
			'default' => 'bottom',
224
			'values' => [ 'none' , 'bottom', 'top' ],
225
		];
226
227
		$params['height'] = [
228
			'type' => 'integer',
229
			'message' => 'srf_paramdesc_chartheight',
230
			'default' => 400,
231
			'lowerbound' => 1,
232
		];
233
234
		$params['width'] = [
235
			'message' => 'srf_paramdesc_chartwidth',
236
			'default' => '100%',
237
		];
238
239
		$params['charttitle'] = [
240
			'message' => 'srf_paramdesc_charttitle',
241
			'default' => '',
242
		];
243
244
		$params['charttext'] = [
245
			'message' => 'srf-paramdesc-charttext',
246
			'default' => '',
247
		];
248
249
		$params['infotext'] = [
250
			'message' => 'srf-paramdesc-infotext',
251
			'default' => '',
252
		];
253
254
		$params['chartcolor'] = [
255
			'message' => 'srf-paramdesc-chartcolor',
256
			'default' => '',
257
		];
258
259
		$params['class'] = [
260
			'message' => 'srf-paramdesc-class',
261
			'default' => '',
262
		];
263
264
		return $params;
265
	}
266
}
267