Completed
Push — master ( f2b2dd...49fb6f )
by Jeroen De
75:28 queued 55:28
created

formats/dygraphs/SRF_Dygraphs.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 that uses the dygraphs 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 SRFDygraphs extends SMWResultPrinter {
14
15
	/**
16
	 * @see SMWResultPrinter::getName
17
	 * @return string
18
	 */
19
	public function getName() {
20
		return wfMessage( 'srf-printername-dygraphs' )->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
		// Output mode is fixed
34
		$outputMode = SMW_OUTPUT_HTML;
35
36
		// Data processing
37
		$data = $this->getResultData( $result, $outputMode );
38
39
		// Post-data processing check
40
		if ( $data === [] ) {
41
			return $result->addErrors( [ wfMessage( 'srf-warn-empy-chart' )->inContentLanguage()->text() ] );
42
		} else {
43
			$options['sask'] = SRFUtils::htmlQueryResultLink( $this->getLink( $result, SMW_OUTPUT_HTML ) );
44
			return $this->getFormatOutput( $data, $options );
45
		}
46
	}
47
48
	/**
49
	 * Returns an array with numerical data
50
	 *
51
	 * @since 1.8
52
	 *
53
	 * @param SMWQueryResult $result
54
	 * @param $outputMode
55
	 *
56
	 * @return array
57
	 */
58
	protected function getResultData( SMWQueryResult $result, $outputMode ) {
59
		$aggregatedValues = [];
60
		
61
		while ( $rows = $result->getNext() ) { // Objects (pages)
62
			$annotation = [];
63
			$dataSource = false;
64
65
			/**
66
			 * @var SMWResultArray $field
67
			 * @var SMWDataValue $dataValue
68
			 */
69
			foreach ( $rows as $field ) {
70
71
				// Use the subject marker to identify a possible data file
72
				$subject = $field->getResultSubject(); 
73
				if ( $this->params['datasource'] === 'file' && $subject->getTitle()->getNamespace() === NS_FILE && !$dataSource ){
74
					$aggregatedValues['subject'] = SMWWikiPageValue::makePageFromTitle( $subject->getTitle() )->getLongHTMLText( $this->getLinker( $field->getResultSubject() ) );
0 ignored issues
show
Deprecated Code introduced by
The method SMWWikiPageValue::makePageFromTitle() has been deprecated with message: This method will vanish before SMW 1.7. If you really need this, simply copy its code.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
75
					$aggregatedValues['url'] = wfFindFile( $subject->getTitle() )->getUrl();
76
					$dataSource = true;
77
				}
78
79
				// Proceed only where a label is known otherwise items are of no use
80
				// for being a potential object identifier
81
				if ( $field->getPrintRequest()->getLabel() !== '' ){
82
					$propertyLabel = $field->getPrintRequest()->getLabel();
83
				}else{
84
					continue;
85
				}
86
87
				while ( ( $dataValue = $field->getNextDataValue() ) !== false ) { // Data values
88
89
					// Jump the column (indicated by continue) because we don't want the data source being part of the annotation array
90
					if ( $dataValue->getDataItem()->getDIType() == SMWDataItem::TYPE_WIKIPAGE && $this->params['datasource'] === 'raw' && !$dataSource ){
91
						// Support data source = raw which pulls the url from a wikipage in raw format
92
						$aggregatedValues['subject'] = SMWWikiPageValue::makePageFromTitle( $dataValue->getTitle() )->getLongHTMLText( $this->getLinker( $field->getResultSubject() ) );
0 ignored issues
show
Deprecated Code introduced by
The method SMWWikiPageValue::makePageFromTitle() has been deprecated with message: This method will vanish before SMW 1.7. If you really need this, simply copy its code.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
93
						$aggregatedValues['url'] = $dataValue->getTitle()->getLocalURL( 'action=raw' );
94
						$dataSource = true;
95
						continue;
96
					} elseif ( $dataValue->getDataItem()->getDIType() == SMWDataItem::TYPE_WIKIPAGE && $this->params['datasource'] === 'file' && $dataValue->getTitle()->getNamespace() === NS_FILE && !$dataSource ) {
97
						// Support data source = file which pulls the url from a uploaded file
98
						$aggregatedValues['subject'] = SMWWikiPageValue::makePageFromTitle( $dataValue->getTitle() )->getLongHTMLText( $this->getLinker( $field->getResultSubject() ) );
0 ignored issues
show
Deprecated Code introduced by
The method SMWWikiPageValue::makePageFromTitle() has been deprecated with message: This method will vanish before SMW 1.7. If you really need this, simply copy its code.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
99
						$aggregatedValues['url'] = wfFindFile( $dataValue->getTitle() )->getUrl();
100
						$dataSource = true;
101
						continue;
102
					} elseif ( $dataValue->getDataItem()->getDIType() == SMWDataItem::TYPE_URI && $this->params['datasource'] === 'url'  && !$dataSource ){
103
						// Support data source = url, pointing to an url data source
104
						$aggregatedValues['link'] = $dataValue->getShortHTMLText( $this->getLinker( false ) );
105
						$aggregatedValues['url'] = $dataValue->getURL();
106
						$dataSource = true;
107
						continue;
108
					}
109
110
					// The annotation should adhere outlined conventions as the label identifies the array object key
111
					// series -> Required The name of the series to which the annotated point belongs
112
					// x -> Required The x value of the point
113
					// shortText -> Text that will appear as annotation flag
114
					// text -> A longer description of the annotation
115
					// @see  http://dygraphs.com/annotations.html
116
					if ( in_array( $propertyLabel, [ 'series', 'x', 'shortText', 'text' ] ) ){
117
						if ( $dataValue->getDataItem()->getDIType() == SMWDataItem::TYPE_NUMBER ){
118
							// Set unit if available
119
							$dataValue->setOutputFormat( $this->params['unit'] );
120
							// Check if unit is available
121
							$annotation[$propertyLabel] = $dataValue->getUnit() !== '' ? $dataValue->getShortWikiText() : $dataValue->getNumber() ;
122
						} else {
123
							$annotation[$propertyLabel] = $dataValue->getWikiValue();
124
						}
125
					}
126
				}
127
			}
128
			// Sum-up collected row items in a single array
129
			if ( $annotation !== [] ){
130
				$aggregatedValues['annotation'][] =  $annotation;
131
			}
132
		}
133
		return $aggregatedValues;
134
	}
135
136
	/**
137
	 * Prepare data for the output
138
	 *
139
	 * @since 1.8
140
	 *
141
	 * @param array $data
142
	 *
143
	 * @return string
144
	 */
145
	protected function getFormatOutput( $data, $options ) {
146
147
		// Object count
148
		static $statNr = 0;
149
		$chartID = 'srf-dygraphs-' . ++$statNr;
150
151
		$this->isHTML = true;
152
153
		// Reorganize the raw data
154
		if ( $this->params['datasource'] === 'page' ){
155
			foreach ( $data as $key => $values ) {
156
				$dataObject[] =  [ 'label' => $key, 'data' => $values ];
157
			}
158
		}else{
159
				$dataObject['source'] = $data;
160
		}
161
162
		// Prepare transfer array
163
		$chartData =  [
164
			'data' => $dataObject,
165
			'sask' => $options['sask'],
166
			'parameters' =>  [
167
				'width'        => $this->params['width'],
168
				'height'       => $this->params['height'],
169
				'xlabel'       => $this->params['xlabel'],
170
				'ylabel'       => $this->params['ylabel'],
171
				'charttitle'   => $this->params['charttitle'],
172
				'charttext'    => $this->params['charttext'],
173
				'infotext'     => $this->params['infotext'],
174
				'datasource'   => $this->params['datasource'],
175
				'rollerperiod' => $this->params['mavg'],
176
				'gridview'    => $this->params['gridview'],
177
				'errorbar'     => $this->params['errorbar'],
178
			]
179
		];
180
181
		// Array encoding and output
182
		$requireHeadItem =  [ $chartID => FormatJson::encode( $chartData ) ];
183
		SMWOutputs::requireHeadItem( $chartID, Skin::makeVariablesScript( $requireHeadItem ) );
184
185
		SMWOutputs::requireResource( 'ext.srf.dygraphs' );
186
187
		if ( $this->params['gridview'] === 'tabs' ) {
188
			SMWOutputs::requireResource( 'ext.srf.util.grid' );
189
		}
190
191
		// Chart/graph placeholder
192
		$chart = Html::rawElement(
193
			'div',
194
			['id' => $chartID, 'class' => 'container', 'style' => "display:none;" ],
195
			null
196
		);
197
198
		// Processing/loading image
199
		$processing = SRFUtils::htmlProcessingElement( $this->isHTML );
200
201
		// Beautify class selector
202
		$class = $this->params['class'] ? ' ' . $this->params['class'] : ' dygraphs-common';
203
204
		// General output marker
205
		return Html::rawElement(
206
			'div',
207
			[ 'class' => 'srf-dygraphs' . $class	],
208
			$processing . $chart
209
		);
210
	}
211
212
	/**
213
	 * @see SMWResultPrinter::getParamDefinitions
214
	 *
215
	 * @since 1.8
216
	 *
217
	 * @param $definitions array of IParamDefinition
218
	 *
219
	 * @return array of IParamDefinition|array
220
	 */
221
	public function getParamDefinitions( array $definitions ) {
222
		$params = parent::getParamDefinitions( $definitions );
223
224
		$params['datasource'] = [
225
			'message' => 'srf-paramdesc-datasource',
226
			'default' => 'file',
227
			'values' => [ 'file', 'raw', 'url' ],
228
		];
229
230
		$params['errorbar'] = [
231
			'message' => 'srf-paramdesc-errorbar',
232
			'default' => '',
233
			'values' => [ 'fraction', 'sigma', 'range' ],
234
		];
235
236
		$params['min'] = [
237
			'type' => 'integer',
238
			'message' => 'srf-paramdesc-minvalue',
239
			'default' => '',
240
		];
241
242
		$params['mavg'] = [
243
			'type' => 'integer',
244
			'message' => 'srf-paramdesc-movingaverage',
245
			'default' => 14,
246
			'lowerbound' => 0,
247
		];
248
249
		$params['gridview'] = [
250
			'message' => 'srf-paramdesc-gridview',
251
			'default' => 'none',
252
			'values' => [ 'none' , 'tabs' ],
253
		];
254
255
		$params['infotext'] = [
256
			'message' => 'srf-paramdesc-infotext',
257
			'default' => '',
258
		];
259
260
		$params['unit'] = [
261
			'message' => 'srf-paramdesc-unit',
262
			'default' => '',
263
		];
264
265
		$params['height'] = [
266
			'type' => 'integer',
267
			'message' => 'srf_paramdesc_chartheight',
268
			'default' => 400,
269
			'lowerbound' => 1,
270
		];
271
272
		$params['width'] = [
273
			'message' => 'srf_paramdesc_chartwidth',
274
			'default' => '100%',
275
		];
276
277
		$params['charttitle'] = [
278
			'message' => 'srf_paramdesc_charttitle',
279
			'default' => '',
280
		];
281
282
		$params['charttext'] = [
283
			'message' => 'srf-paramdesc-charttext',
284
			'default' => '',
285
		];
286
287
		$params['infotext'] = [
288
			'message' => 'srf-paramdesc-infotext',
289
			'default' => '',
290
		];
291
292
		$params['ylabel'] = [
293
			'message' => 'srf-paramdesc-yaxislabel',
294
			'default' => '',
295
		];
296
297
		$params['xlabel'] = [
298
			'message' => 'srf-paramdesc-xaxislabel',
299
			'default' => '',
300
		];
301
302
		$params['class'] = [
303
			'message' => 'srf-paramdesc-class',
304
			'default' => '',
305
		];
306
307
		return $params;
308
	}
309
}