MediaWiki:Common.js/GECharts.js

$('.GEdatachart').attr('id', function(c) { return "GEdatachart"+c}); $('.GEdataprices').attr('id', function(c) { return "GEdataprices"+c});

//general functions

function getUrlParam(param) { param = document.location.search.substring(1).match(new RegExp(param+'=([^&#=]*)')); return param?param[1]:''; }

function cloneObj(a,b) { if (typeof(a)!='object') return ''; if (typeof(b)!='object') b = {}; for (var key in a) { b[key] = a[key]; }	return b; }

function avg(arr,amt) { amt = amt?amt:arr.length; var avgs = [], list = []; for (var i=0;i=amt) { avgs.push([arr[i][0], isIndexChart?sum(list)/list.length:Math.round(sum(list)/list.length)]); }	}	return avgs; }

function sum(arr) { var tot = 0; for (var i=0;i=1e10) { n = Math.round(n/1e8)/10; n += 'B'; } else if (n>=1e7) { n = Math.round(n/1e5)/10; n += 'M'; } else if (n>=1e4) { n = Math.round(n/100)/10; n += 'K'; }	n = neg+n; return addCommas(n); }

$('body').append('\nClose popup'+ ' '+ ' Average:  days Add more item(s):  Note: If you add more items, the averages will not be shown. Submit Reset all fields  '+ ' ');

for (var c=0;c<$('div.GEdatachart').length;c++) {

var itemsParam = unescape(getUrlParam('items')).split(','); var isSmall = $('#GEdatachart'+c).is('.smallChart'); var isIndexChart = !!($('#GEdataprices'+c).attr('data-item')||'').match(/index/i);

//chart-related general functions

if ($('#GEdataprices'+c).length) { var item,chartid; function addItem(i) { item = $('#extraItem').val; chartid = i	if (item&&item.length) { if ($('#addedItems [data-item="'+item+'"]').length||window['chart'+i].series[0].name==item) { alert('That item is already in the graph.') $('#extraItem').val(''); return false; }		$('#extraItem').prop('disabled',true); var req = $.get('/wiki/Exchange:'+item+'/Data?action=render', function(data) {			var prices = data.replace(/(.|\n)*]*>\n?|<\/p>(.|\n)*/g, ).split(/,\s/);			var data = [];			var thisprice;			for (var i=0;i<prices.length;i++) {				if (prices[i].replace(/\s/g,).length) {					thisprice = prices[i].split(':');					data.push([ parseInt(thisprice[0])*1000, parseInt(thisprice[1]) ]);				}			}			if (window['chart'+chartid].series[2]&&window['chart'+chartid].series[2].name == 'Volume') {				reloadChart('chart'+chartid,{ series: window['chart'+chartid].options.series[0], yAxis: { title: { text: 'Price history', offset: 60, style: { color: 'black', fontSize: '12px', },						},						labels: { align: 'right', x: -8, y: 4, },						allowDecimals: false, minTickInterval: 1, //1 coin showLastLabel: 1, lineWidth: 1, lineColor: '#E0E0E0', }				});			}			if (window['chart'+chartid].series[1]&&window['chart'+chartid].series[1].name.match(/average/i)) {				window['chart'+chartid].series[1].remove(true);			}			window['chart'+chartid].addSeries({name: item, data: data, id: item, lineWidth: 2});			$('#itemstats').hide;			setChartExtremes(chartid);			$('#extraItem').prop('disabled',false).val();			if (!$('#addedItems').html.replace(/\s+/,).length) {				$('#addedItems').html('Remove items from graph: '+item+'');			} else {				$('#addedItems').append(', '+item+'</a>');			}		}); req.statusCode({			404: function {				alert("That item doesn't exist on our Grand Exchange database.")				$('#extraItem').prop('disabled',false).val('');			}		}); } else { if ($('#addedItems').html.match(/^\s*$/)) { loadChart }	} }

function reloadChart(c,change) { if (!window[c].options) {return false;} for (var i in change) { window[c].options[i] = change[i]; }	window[c] = new Highcharts.StockChart(window[c].options); }

function removeGraphItem(item,c) { for (var i=0;i<window['chart'+c].series.length;i++) { if (window['chart'+c].series[i].name.match(item)) { var id = i;		} }	window['chart'+c].series[id].remove(true); setChartExtremes(c) $('#addedItems [data-item="'+item+'"]').remove $('#addedItems').html($('#addedItems').html.replace(/,, /g,', ').replace(/, $/,'').replace(': , ',': ')); if (!$('#addedItems [data-item]').length) { $('#addedItems').empty; loadChart; $('#itemstats').show; } }

function popupChart(i) { if (!$('#GEchartpopup').length) return false; if ($('#overlay').length) { $('#overlay').toggle; } else { $('#GEchartpopup').before(' '); }	document.getElementById('overlay').onclick = popupChart $('#GEchartpopup').toggle; if (typeof(i)=='number' && $('#GEpopupchart').attr('data-chartid') != i) { addPopupPriceInfo(i) $('#GEpopupchart').attr('data-chartid',i); var options = {} cloneObj(window['chart'+i].options,options); console.log(options.series.length,window['chart'+i].options.series.length); options.chart.renderTo = 'GEpopupchart'; options.legend.enabled = true; options.title.text = 'Grand Exchange Market Watch'; options.subtitle.text = ''+options.series[0].name+'</a>'; options.rangeSelector.inputBoxStyle.display = 'block'; options.plotOptions.series.enableMouseTracking = true; options.tooltip.enabled = true; options.navigator.enabled = true; options.credits.enabled = false; options.series = [{}]; cloneObj(window['chart'+i].options.series[0],options.series[0]); options.series.push({				name: '30-day average',				data: avg(options.series[0].data,30),				lineWidth: 2,				dashStyle: 'shortdash',			}); window.chartpopup = new Highcharts.StockChart(options); setChartExtremes('popup'); chartpopup.redraw; } }

function setChartExtremes(i) { extremes = window['chart'+i].yAxis[0].getExtremes; window['chart'+i].yAxis[0].setExtremes(extremes.dataMin * 0.95, extremes.dataMax * 1.05); if (window['chart'+i].yAxis[2]) { extremes = window['chart'+i].yAxis[1].getExtremes; window['chart'+i].yAxis[1].setExtremes(0, extremes.dataMax * 0.35); } }

function addPopupPriceInfo(c) { var prices = $('#GEdataprices'+c).html.split(/,\s/); var data = []; var curprice; for (var i=0;i<prices.length;i++) { if (prices[i].replace(/\s/g,'').length) { curprice = prices[i].split(':'); data.push(parseInt(curprice[1])); }	}	var datal = data.length var curprice = data[datal-1] var priceDiffs = [ curprice - data[datal-2], curprice - data[datal-8], curprice - data[datal-31], curprice - data[datal-91], curprice - data[datal-181] ];	var percentDiffs = [ Math.round(priceDiffs[0] / data[datal-2]*1000)/10, Math.round(priceDiffs[1] / data[datal-8]*1000)/10, Math.round(priceDiffs[2] / data[datal-31]*1000)/10, Math.round(priceDiffs[3] / data[datal-91]*1000)/10, Math.round(priceDiffs[4] / data[datal-181]*1000)/10 ];	var dayDiffs = [1,7,30,90,180]; function rg(n) { return n>0?'green':(n==0?'blue':'red'); }	var itemStats = ' '; $('#itemStats').html(itemStats); }

function getData(c,isSmall) { var itemName = $('#GEdataprices'+c).attr('data-item'); itemName = itemName || wgPageName.replace(/_/g,' ').split('/')[0].replace('Exchange:',''); var prices = $('#GEdataprices'+c).html.split(/,\s/); window.data = []; var thisprice; var volumes = []; for (var i=0;i<prices.length;i++) { if (prices[i].replace(/\s/g,'').length) { thisprice = prices[i].split(':'); data.push([ parseInt(thisprice[0])*1000, parseFloat(thisprice[1]) ]); if (thisprice[2]&&!isSmall) { volumes.push([ parseInt(thisprice[0])*1000, parseFloat(thisprice[2])*1000*1000 ]); }		}	}

var dataList = [{ name: itemName, data: data, lineWidth: isSmall?2:3 }]	if (!isSmall) { var inputAvg = parseInt($('input#average').val); if (inputAvg) { dataList.push({				name: inputAvg+'-day average',				data: avg(data,inputAvg),				lineWidth: 2,				dashStyle: 'shortdash',			}); } else { dataList.push({				name: '30-day average',				data: avg(data,30),				lineWidth: 2,				dashStyle: 'shortdash',			}); }		if (volumes.length) { dataList.push({				name: 'Volume',				data: volumes,				type : 'area',				color: '#cc8400',                      				fillColor: {					linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },					stops: 0, ',				},				yAxis: 1,			}); }	}	var yAxis = {}; if (volumes.length&&!isSmall) { yAxis = [{ title: { text: 'Price history', offset: 60, style: { color: 'black', fontSize: '12px', },			},			labels: { align: 'right', x: -8, y: 4, },			allowDecimals: false, minTickInterval: 1, //1 coin showLastLabel: 1, lineWidth: 1, lineColor: '#E0E0E0', height: 225, }, {			title: { text: 'Trade volume', offset: 60, style: { color: 'black', fontSize: '12px', },			},			labels: { align: 'right', x: -8, y: 4, },			showEmpty: 0, showLastLabel: 1, offset: 0, lineWidth: 1, lineColor: '#E0E0E0', height: 75, top: 325, min: 0 }];	} else if (isSmall) { yAxis = { labels: { align: 'right', x: -8, y: 4, },			allowDecimals: false, minTickInterval: 1, //1 coin showLastLabel: 1, lineWidth: 1, lineColor: '#E0E0E0', }	} else { yAxis = { title: { text: isIndexChart?'Index':'Price history', offset: 60, style: { color: 'black', fontSize: '12px', },			},			labels: { align: 'right', x: -8, y: 4, },			allowDecimals: false, minTickInterval: 1, //1 coin showLastLabel: 1, lineWidth: 1, lineColor: '#E0E0E0', }       	}	return [dataList,yAxis]; }

//setting up the form and chart elements

var formhtml = '<form action="javascript:addItem" id="chartProperties" style="font-family:\'Lucida Grande\',\'Lucida Sans Unicode\',Verdana,Arial,Helvetica,sans-serif;font-size:12px"> Average: <input type="number" min="1" id="average" style="font-family:\'Lucida Grande\',\'Lucida Sans Unicode\',Verdana,Arial,Helvetica,sans-serif;font-size:12px"> days '+(isIndexChart?:' Add more item(s): <input type="text" id="extraItem" style="font-family:\'Lucida Grande\',\'Lucida Sans Unicode\',Verdana,Arial,Helvetica,sans-serif;font-size:12px"> Note: If you add more items, the averages will not be shown.')+' <button style="font-family:\'Lucida Grande\',\'Lucida Sans Unicode\',Verdana,Arial,Helvetica,sans-serif;font-size:12px">Submit <input type="reset" style="font-family:\'Lucida Grande\',\'Lucida Sans Unicode\',Verdana,Arial,Helvetica,sans-serif;font-size:12px" value="Reset'+(isIndexChart?:' all fields')+'"/> <div id="addedItems" style="font-family:\'Lucida Grande\',\'Lucida Sans Unicode\',Verdana,Arial,Helvetica,sans-serif;font-size:12px"> ';

if (!isSmall) { $('#GEdatachart'+c).before(formhtml); }

$('[id^="item"]').keyup(function {	if ($(this).val.length) $(this).next.removeAttr('disabled');	else if (!$(this).val.length) $(this).nextAll('input[id^="item"]').attr('disabled','disabled'); }); $('[id^="item"]:not(:disabled)').next.removeAttr('disabled');

//the chart function

var data = [];

function loadChart { var itemName = $('#GEdataprices'+c).attr('data-item'); itemName = itemName || wgPageName.replace(/_/g,' ').split('/')[0].replace('Exchange:',''); var dataList = getData(c,isSmall,yAxis); var yAxis = dataList[1]; dataList = dataList[0];

//adding in the chart properties

Highcharts.setOptions({	lang: {               rangeSelectorZoom: isSmall?'':'Zoom',                numericSymbols: ['k', 'M', 'B', 'T', 'Qd', 'Qt'],	} }); //generating the chart window['chart'+c] = new Highcharts.StockChart({	chart: {		renderTo: 'GEdatachart'+c,		backgroundColor: 'white',		plotBackgroundColor: 'white',		events: {			redraw: function {				window.thisid = this.renderTo.id.replace('GEdatachart','');				setTimeout(function {console.trace;setChartExtremes(thisid);},0);			}		},	},	legend: {		enabled: !isSmall,		backgroundColor: 'white',		align: 'right',		layout: 'vertical',		verticalAlign: 'top',		y: 75	},       title: {		text: isSmall?null:'Grand Exchange Market Watch',		style: {                	color: 'black',                	fontSize: '18px',                },	},	subtitle: {		text: isSmall?null:''+itemName+'</a>',		y: 35,		style: {                	color: '#666',                	fontSize: '15px',                },                	},	rangeSelector: { selected: 2, //3-month zoom inputBoxStyle: { display: isSmall?'none':'block' },               inputStyle: { fontFamily: '\'Lucida Grande\', \'Lucida Sans Unicode\', Verdana, Arial, Helvetica, sans-serif', fontSize: '11px' },               inputDateFormat: "%e-%b-%Y", buttons: [{ type: 'month', count: 1, text: '1m' }, {	               type: 'month', count: 2, text: '2m' }, {	               type: 'month', count: 3, text: '3m' }, {	               type: 'month', count: 6, text: '6m' }, {	               type: 'year', count: 1, text: '1y' }, {	               type: 'all', text: 'All' }]	},	plotOptions: { series: { enableMouseTracking: !isSmall, dataGrouping: { dateTimeLabelFormats: { day: ['%A, %e %B %Y', '%A, %e %B', '-%A, %e %B %Y'], week: ['Week from %A, %e %B %Y', '%A, %e %B', '-%A, %e %B %Y'], month: ['%B %Y', '%B', '-%B %Y'], year: ['%Y', '%Y', '-%Y'] }                       }                }        },        tooltip: { enabled: !isSmall, yDecimals: isIndexChart?2:0, valueDecimals: 0, headerFormat: ' {point.key} ', xDateFormat: "%A, %e %B %Y", },       navigator: { xAxis: { dateTimeLabelFormats: { day: "%e-%b", week: "%e-%b", month: "%b-%Y", year: "%Y", },                       minTickInterval: 24 * 3600 * 1000, //1 day },		maskFill: 'none', enabled: !isSmall },	credits: { enabled: isSmall, href: 'javascript:console.log("'+c+'");popupChart('+c+');', text: 'Enlarge chart', position: { y: -3 },		style: { color: '#666', fontSize: '11px' }	},       xAxis: [{ lineColor: '#666', tickColor: '#666', dateTimeLabelFormats: { day: "%e-%b", week: "%e-%b", month: "%b-%Y", year: "%Y", },               minTickInterval: 24 * 3600 * 1000, //1 day /*events: { //adjusting the Y-axis extremes (at different zoom levels) afterSetExtremes: function { extremes = this.chart.yAxis[0].getExtremes; this.chart.yAxis[0].setExtremes(extremes.dataMin * 0.95, extremes.dataMax * 1.05); if (volumes.length&&(!isSmall||cLoaded)) { extremes = this.chart.yAxis[1].getExtremes; this.chart.yAxis[1].setExtremes(0, extremes.dataMax * 0.35); }                   }                },*/        }],	yAxis: yAxis, series: dataList, colors: window.GEMWChartColors||['#4572A7','#AA4643','#89A54E','#80699B','#3D96AE','#DB843D','#92A8CD','#A47D7C','#B5CA92'] });

//adjusting the Y-axis extremes (initial load) setChartExtremes(c)

}

//loading the chart and additional price info when the page is ready

addOnloadHook(loadChart);

}

}//exit c