#coding=utf-8
import re
from datetime import date
from pymongo import MongoClient
client = MongoClient('localhost', 27017)
ganji = client['ganji_market']
goods = ganji['sampledata']
def gen_data_by_district(start,end,district,limit):
'''指定城區(qū),獲取某時(shí)間段內(nèi)二手物品數(shù)量'''
pipeline = [
{'$match': {'pub_date':{'$gte':start,'$lte':end},'area': {'$all': [district]}}},
{'$limit' : limit},
{'$group':
{'_id': {'district': {'$slice': ['$area', 1]}, 'cate': {'$slice': ['$cates', 2, 1]}},
'count': {'$sum': 1}}},
{'$sort': {'count':-1}},
{'$project' : {'cate' : '$_id.cate','count' : 1,'_id' : 0}}
]
for data in goods.aggregate(pipeline):
fmt_data = {
'name' : data['cate'][0],
'data' : [data['count']],
'type' : 'column'
}
yield fmt_data
district = '海淀'
start = '2015.01.01'
end = '2015.12.30'
datas = gen_data_by_district(start,end,district,20000)
series = [item for item in datas]
options = {
'chart' : {'zoomType':'xy'},
'title' : {'text': district + '區(qū)二手物品發(fā)帖量'},
'subtitle': {'text': start + '至' + end},
'xAxis' : {'title': {'text': '二手物品類目'}},
'yAxis' : {'title': {'text': '發(fā)帖量'}}
}
charts.plot(series,options=options,show='inline')
<style>body{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;color:#555;font-family:sans-serif}
small{font-weight:400;display:block;font-size:14px}
code{background-color:#d3d3d3;border-radius:3px;font-family:monospace;padding:0 .5em}
.icon.-facebook:before,.icon.-linkedin:before,.icon.-pinterest:before,.icon.-twitter:before{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:Post-Creator-Icons;font-style:normal;font-variant:normal;font-weight:400;line-height:1;speak:none;text-transform:none}
@font-face{font-family:Post-Creator-Icons;src:url(fonts/Post-Creator-Icons.eot);src:url(fonts/Post-Creator-Icons.eot?#iefix) format('embedded-opentype'),url(fonts/Post-Creator-Icons.woff) format('woff'),url(fonts/Post-Creator-Icons.ttf) format('truetype'),url(fonts/Post-Creator-Icons.svg#Post-Creator-Icons) format('svg');font-weight:400;font-style:normal}
.icon.-facebook:before{content:"\e001"}
.icon.-linkedin:before{content:"\e002"}
.icon.-pinterest:before{content:"\e003"}
.icon.-twitter:before{content:"\e004"}
.social-icons h4{display:inline-block;margin:20px 10px 0 0}
.social-icons .icon{display:inline-block;margin:0 5px}
body.modal-open{overflow:hidden}
.jsoneditor table,.jsoneditor td,.jsoneditor td.tree,.jsoneditor tr{border:none;margin:0}</style>
<link rel="stylesheet" />
<link rel="stylesheet" />
<div class="container-fluid">
<div class="row">
<div class="col-sm-10">
<input type="text" id="variable-selector">
</div>
<div class="col-sm-2">
<button class="btn btn-default pull-right" type="submit" id="settings-button">Settings</button>
</div>
</div>
<div class="row">
<div class="collapse col-xs-12" id="settings-collapse">
<div class="panel panel-default" style="margin-top: 20px">
<div class="panel-heading"><h3 class="panel-title">Adjust chart settings</h3></div>
<div class="panel-body">
<div class="row">
<div id="jsoneditor" class="col-md-12" style="height: 350px"></div>
</div>
<div class="row" style="margin-top: 10px">
<div class="col-sm-4">
<button type="button" class="btn btn-primary" id="save-settings">
Apply changes
</button>
</div>
<div class="col-sm-8 text-right ">
<form class="form-inline">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" id="options-input"
placeholder="settings" style="text-align: right">
<div class="input-group-addon"><strong>.json</strong></div>
</div>
</div>
<button type="submit" class="btn btn-primary" id="options-button">Save</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div id="chart-container" style="min-width: 310px;"></div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.18/require.min.js"></script>
<script>(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
//findIndex polyfill
if (!Array.prototype.findIndex) {
Array.prototype.findIndex = function(predicate) {
if (this == null) {
throw new TypeError('Array.prototype.findIndex called on null or undefined');
}
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
var list = Object(this);
var length = list.length >>> 0;
var thisArg = arguments[1];
var value;
for (var i = 0; i < length; i++) {
value = list[i];
if (predicate.call(thisArg, value, i, list)) {
return i;
}
}
return -1;
};
}
if (!Array.prototype.filter) {
Array.prototype.filter = function(fun/, thisArg/) {
'use strict';
if (this === void 0 || this === null) {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun !== 'function') {
throw new TypeError();
}
var res = [];
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++) {
if (i in t) {
var val = t[i];
// NOTE: Technically this should Object.defineProperty at
// the next index, as push can be affected by
// properties on Object.prototype and Array.prototype.
// But that method's new, and collisions should be
// rare, so use the more-compatible alternative.
if (fun.call(thisArg, val, i, t)) {
res.push(val);
}
}
}
return res;
};
}
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
Array.prototype.equals = function (array) {
// if the other array is a false value, return
if (!array)
return false;
// compare lengths - can save a lot of time
if (this.length != array.length)
return false;
for (var i = 0, l = this.length; i < l; i++) {
// Check if we have nested arrays
if (this[i] instanceof Array && array[i] instanceof Array) {
// recurse into the nested arrays
if (!this[i].equals(array[i]))
return false;
}
else if (this[i] != array[i]) {
// Warning - two different object instances will never be equal: {x:20} != {x:20}
return false;
}
}
return true;
};
},{}]},{},[1]);
</script>
<script>(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
requirejs.config({
"paths": {
"highstock": "https://cdnjs.cloudflare.com/ajax/libs/highstock/2.1.5/highstock",
"export": "https://cdnjs.cloudflare.com/ajax/libs/highstock/2.1.5/modules/exporting",
"more": "https://cdnjs.cloudflare.com/ajax/libs/highstock/2.1.7/highcharts-more",
"jsoneditor": "https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/4.2.0/jsoneditor.min",
"selectize": "https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.1/js/standalone/selectize.min",
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min"
},
"shim": {
"export": ["highstock"],
"more": ["highstock"]
}
});
//Define jquery here to use the pre-loaded version
define('jquery', [], function() {
return jQuery;
});
},{}]},{},[1]);
</script>
<script>(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
//Count the number of charts on the page
if (window.counter == undefined) {
window.counter = 0;
} else {
window.counter++;
}
requirejs([
'jquery',
'selectize',
'jsoneditor',
'highstock',
'export',
'more'
], function ($, selectize, JSONEditor) {
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
var id = guid();
plot(id);
function plot(id) {
var series = [
{data: [1, 2, 4, 9], name: "temperature 1", display: true, color: '#2b908f'},
{data: [9, 4, 2, 1], name: "temperature 2", display: true},
{data: [0, 3, 5, 6], name: "temperature 3", display: false}
];
var series = [{"display": true, "type": "column", "data": [557], "name": "\u5317\u4eac\u4e8c\u624b\u670d\u88c5/\u978b\u5e3d/\u7bb1\u5305"}, {"display": true, "type": "column", "data": [468], "name": "\u5317\u4eac\u4e8c\u624b\u5bb6\u7535"}, {"display": true, "type": "column", "data": [389], "name": "\u5317\u4eac\u4e8c\u624b\u6bcd\u5a74/\u513f\u7ae5\u7528\u54c1"}, {"display": true, "type": "column", "data": [325], "name": "\u5317\u4eac\u4e8c\u624b\u6587\u4f53/\u6237\u5916/\u4e50\u5668"}, {"display": true, "type": "column", "data": [285], "name": "\u5317\u4eac\u4e8c\u624b\u529e\u516c\u7528\u54c1/\u8bbe\u5907"}, {"display": true, "type": "column", "data": [225], "name": "\u5317\u4eac\u4e8c\u624b\u56fe\u4e66/\u97f3\u50cf/\u8f6f\u4ef6"}, {"display": true, "type": "column", "data": [204], "name": "\u5317\u4eac\u4e8c\u624b\u53f0\u5f0f\u673a/\u914d\u4ef6"}, {"display": true, "type": "column", "data": [198], "name": "\u5317\u4eac\u4e8c\u624b\u7b14\u8bb0\u672c"}, {"display": true, "type": "column", "data": [181], "name": "\u5317\u4eac\u4e8c\u624b\u6570\u7801\u4ea7\u54c1"}, {"display": true, "type": "column", "data": [118], "name": "\u5317\u4eac\u4e8c\u624b\u5e73\u677f\u7535\u8111"}, {"display": true, "type": "column", "data": [82], "name": "\u5317\u4eac\u4e8c\u624b\u624b\u673a"}, {"display": true, "type": "column", "data": [48], "name": "\u5317\u4eac\u5176\u4ed6\u4e8c\u624b\u7269\u54c1"}]
var options = {};
var options = {"scale": 2, "xAxis": {"title": {"text": "\u4e8c\u624b\u7269\u54c1\u7c7b\u76ee"}}, "height": 400, "chart": {"zoomType": "xy", "type": "line"}, "width": "auto", "type": "line", "title": {"text": "\u6d77\u6dc0\u533a\u4e8c\u624b\u7269\u54c1\u53d1\u5e16\u91cf"}, "subtitle": {"text": "2015.01.01\u81f32015.12.30"}, "yAxis": {"title": {"text": "\u53d1\u5e16\u91cf"}}}
var useHighStock = false;
var useHighStock = false
var save = 'app/chart.svg';
var save = false
var url = 'http://127.0.0.1:65079';
var url = "http://127.0.0.1:61383/"
var settingsFile = 'settings';
var settingsFile = "settings"
var scale = options.scale;
//Create different containers for the charts
var chartContainer = document.getElementById("chart-container");
chartContainer.id = "chart-container" + id;
chartContainer.style.height = options.height.toString() + 'px';
if (options.width != 'auto') {
chartContainer.style.width = options.width.toString() + 'px';
}
var selector = $("#variable-selector");
selector.attr('id', "variable-selector" + id);
var settings = $("#settings-collapse");
settings.attr('id', "settings-collapse" + id);
var button = $("#settings-button");
button.attr('id', "settings-button" + id);
var saveButton = $("#save-settings");
saveButton.attr('id', "save-settings" + id);
var optionsInput = $("#options-input");
optionsInput.attr('id', "options-input" + id);
optionsInput.val(settingsFile);
var optionsButton = $("#options-button");
optionsButton.attr('id', "options-button" + id);
// create the editor
var editorContainer = document.getElementById("jsoneditor");
editorContainer.id = "jsoneditor" + id;
var editor = new JSONEditor(editorContainer);
button.on('click', showSettings);
saveButton.on('click', applyOptions);
optionsButton.on('click', saveOptions);
function applyOptions() {
var newOptions = editor.get();
setOptions(newOptions);
settings.collapse('hide');
}
function saveOptions(event) {
event.preventDefault();
applyOptions();
var options = chart.options;
delete options.exporting;
var name = optionsInput.val() ? optionsInput.val() + '.json' : 'settings.json';
options['settingsFile'] = name;
$.ajax({
type: "POST",
url: url,
data: JSON.stringify({
options: options,
name: name
})
});
}
function showSettings() {
settings.collapse('toggle');
}
//Choose a chart type
var ChartType = useHighStock ? Highcharts.StockChart : Highcharts.Chart;
//Default highchart colors
var colors = ['#7cb5ec', '#434348', '#90ed7d', '#f7a35c', '#8085e9',
'#f15c80', '#e4d354', '#2b908f', '#f45b5b', '#91e8e1'];
series.map(function (serie, index) {
if (!serie.color) {
serie['color'] = colors[index % 10];
}
return serie;
});
//Get all the keys
var keys = [];
var initialKeys = [];
$.each(series, function (index, serie) {
keys.push({
display: serie.display,
value: serie.name,
text: serie.name
});
if (serie.display) {
initialKeys.push(serie.name)
}
});
selector.selectize({
plugins: ['remove_button', 'restore_on_backspace'],
delimiter: ',',
options: keys,
items: initialKeys,
onItemAdd: function (key) {
console.log('series added');
addSeries(key);
newChart(chart.options, renderedSeries);
},
onItemRemove: function (key) {
console.log('series removed');
deleteSeries(key);
newChart(chart.options, renderedSeries);
}
});
//Set initial chart options
var chartOptions;
if (typeof options.chart === "undefined") {
chartOptions = {renderTo: chartContainer.id};
} else {
chartOptions = $.extend(options["chart"], {renderTo: chartContainer.id});
}
//Initial rendered series
var renderedSeries = [];
options = $.extend(options, {chart: chartOptions}, {series: renderedSeries});
var chart = new ChartType(options);
$.each(initialKeys, function (index, key) {
addSeries(key);
});
newChart(chart.options, renderedSeries);
editor.set(chart.options);
if (save) {
saveSVG(url, save)
}
function setOptions(options) {
//Prevent export from breaking
delete options.exporting;
options['exporting'] = {scale: options.scale};
chartContainer.style.height = options.height.toString() + 'px';
if (options.width != 'auto') {
chartContainer.style.width = options.width.toString() + 'px';
}
newChart(options, renderedSeries);
}
function findSeries(series, key) {
return series.findIndex(function (obj) {
return obj.name == key;
})
}
function newChart(options, series) {
//Disable animation
var newOptions = $.extend(options, {series: series});
newOptions.plotOptions['series'] = {animation: false};
//Get zoom
var xExtremes = chart.xAxis[0].getExtremes();
//Re-plot the chart
chart.destroy();
chart = new ChartType(newOptions);
//Reset the zoom
chart.xAxis[0].setExtremes(xExtremes.min, xExtremes.max, false, false);
//Re-draw chart
chart.redraw();
}
function addSeries(key) {
var index = findSeries(series, key);
var newSeries = series[index];
renderedSeries.push(newSeries)
}
function deleteSeries(key) {
var index = findSeries(renderedSeries, key);
renderedSeries.splice(index, 1)
}
function saveSVG(url, name) {
$.ajax({
type: "POST",
url: url,
data: JSON.stringify({
svg: chart.getSVG(),
name: name
})
});
}
console.log('loaded!', Date());
}
});
},{}]},{},[1]);
</script>
def gen_data_by_look(start,end,cate,limit):
'''指定類目杠览,獲取某時(shí)間段內(nèi)所有城區(qū)二手物品平均數(shù)'''
# pipeline = [
# {'$match': {'pub_date':{'$gte':start,'$lte':end},'cates': {'$all': [cate]}, 'look' : {'$nin' : ['-']}}},
# {'$limit' : limit},
# {'$group':{'_id': '$look','avg': {'$avg': '$price'}}},
# {'$sort': {'_id':1}},
# ]
pipeline = [
{'$match' : {'pub_date':{'$gte':start,'$lte':end},'cates' : {'$all' : [cate]},'look' : {'$nin' : ['-']}}},
{'$project' : {'price' : 1,'look' : 1, '_id' : 0}},
{'$limit': limit},
{'$group' : {'_id' : '$look','avg' : {'$avg' : '$price'}}},
{'$sort': {'_id':1}},
]
categories = []
data = []
for item in goods.aggregate(pipeline):
categories.append(item['_id'])
data.append(round(item['avg'],2))
return(categories,data)
cate = '北京二手手機(jī)'
start = '2015.01.01'
end = '2015.12.30'
datas = gen_data_by_look(start, end, cate, 20000)
series = {
'name' : cate,
'data' : datas[1]
}
print(datas[1])
print(datas[0])
options = {
'chart' : {'zoomType':'xy'},
'title' : {'text': cate + '平均價(jià)格走勢'},
'subtitle': {'text': start + '至' + end},
'xAxis' : {'title': {'text': '二手物品類目'},
'categories' :datas[0]},
'yAxis' : {'title': {'text': '發(fā)帖量'}}
}
charts.plot(series,options=options,show='inline')
[175.0, 497.86, 2802.46, 1657.75, 975.26, 2294.28, 450.0]
['7成新及以下', '8成新', '95成新', '99成新', '9成新', '全新', '報(bào)廢機(jī)/尸體']
<style>body{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;color:#555;font-family:sans-serif}
small{font-weight:400;display:block;font-size:14px}
code{background-color:#d3d3d3;border-radius:3px;font-family:monospace;padding:0 .5em}
.icon.-facebook:before,.icon.-linkedin:before,.icon.-pinterest:before,.icon.-twitter:before{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:Post-Creator-Icons;font-style:normal;font-variant:normal;font-weight:400;line-height:1;speak:none;text-transform:none}
@font-face{font-family:Post-Creator-Icons;src:url(fonts/Post-Creator-Icons.eot);src:url(fonts/Post-Creator-Icons.eot?#iefix) format('embedded-opentype'),url(fonts/Post-Creator-Icons.woff) format('woff'),url(fonts/Post-Creator-Icons.ttf) format('truetype'),url(fonts/Post-Creator-Icons.svg#Post-Creator-Icons) format('svg');font-weight:400;font-style:normal}
.icon.-facebook:before{content:"\e001"}
.icon.-linkedin:before{content:"\e002"}
.icon.-pinterest:before{content:"\e003"}
.icon.-twitter:before{content:"\e004"}
.social-icons h4{display:inline-block;margin:20px 10px 0 0}
.social-icons .icon{display:inline-block;margin:0 5px}
body.modal-open{overflow:hidden}
.jsoneditor table,.jsoneditor td,.jsoneditor td.tree,.jsoneditor tr{border:none;margin:0}</style>
<link rel="stylesheet" />
<link rel="stylesheet" />
<div class="container-fluid">
<div class="row">
<div class="col-sm-10">
<input type="text" id="variable-selector">
</div>
<div class="col-sm-2">
<button class="btn btn-default pull-right" type="submit" id="settings-button">Settings</button>
</div>
</div>
<div class="row">
<div class="collapse col-xs-12" id="settings-collapse">
<div class="panel panel-default" style="margin-top: 20px">
<div class="panel-heading"><h3 class="panel-title">Adjust chart settings</h3></div>
<div class="panel-body">
<div class="row">
<div id="jsoneditor" class="col-md-12" style="height: 350px"></div>
</div>
<div class="row" style="margin-top: 10px">
<div class="col-sm-4">
<button type="button" class="btn btn-primary" id="save-settings">
Apply changes
</button>
</div>
<div class="col-sm-8 text-right ">
<form class="form-inline">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" id="options-input"
placeholder="settings" style="text-align: right">
<div class="input-group-addon"><strong>.json</strong></div>
</div>
</div>
<button type="submit" class="btn btn-primary" id="options-button">Save</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div id="chart-container" style="min-width: 310px;"></div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.18/require.min.js"></script>
<script>(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
//findIndex polyfill
if (!Array.prototype.findIndex) {
Array.prototype.findIndex = function(predicate) {
if (this == null) {
throw new TypeError('Array.prototype.findIndex called on null or undefined');
}
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
var list = Object(this);
var length = list.length >>> 0;
var thisArg = arguments[1];
var value;
for (var i = 0; i < length; i++) {
value = list[i];
if (predicate.call(thisArg, value, i, list)) {
return i;
}
}
return -1;
};
}
if (!Array.prototype.filter) {
Array.prototype.filter = function(fun/, thisArg/) {
'use strict';
if (this === void 0 || this === null) {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun !== 'function') {
throw new TypeError();
}
var res = [];
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++) {
if (i in t) {
var val = t[i];
// NOTE: Technically this should Object.defineProperty at
// the next index, as push can be affected by
// properties on Object.prototype and Array.prototype.
// But that method's new, and collisions should be
// rare, so use the more-compatible alternative.
if (fun.call(thisArg, val, i, t)) {
res.push(val);
}
}
}
return res;
};
}
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
Array.prototype.equals = function (array) {
// if the other array is a false value, return
if (!array)
return false;
// compare lengths - can save a lot of time
if (this.length != array.length)
return false;
for (var i = 0, l = this.length; i < l; i++) {
// Check if we have nested arrays
if (this[i] instanceof Array && array[i] instanceof Array) {
// recurse into the nested arrays
if (!this[i].equals(array[i]))
return false;
}
else if (this[i] != array[i]) {
// Warning - two different object instances will never be equal: {x:20} != {x:20}
return false;
}
}
return true;
};
},{}]},{},[1]);
</script>
<script>(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
requirejs.config({
"paths": {
"highstock": "https://cdnjs.cloudflare.com/ajax/libs/highstock/2.1.5/highstock",
"export": "https://cdnjs.cloudflare.com/ajax/libs/highstock/2.1.5/modules/exporting",
"more": "https://cdnjs.cloudflare.com/ajax/libs/highstock/2.1.7/highcharts-more",
"jsoneditor": "https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/4.2.0/jsoneditor.min",
"selectize": "https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.1/js/standalone/selectize.min",
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min"
},
"shim": {
"export": ["highstock"],
"more": ["highstock"]
}
});
//Define jquery here to use the pre-loaded version
define('jquery', [], function() {
return jQuery;
});
},{}]},{},[1]);
</script>
<script>(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
//Count the number of charts on the page
if (window.counter == undefined) {
window.counter = 0;
} else {
window.counter++;
}
requirejs([
'jquery',
'selectize',
'jsoneditor',
'highstock',
'export',
'more'
], function ($, selectize, JSONEditor) {
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
var id = guid();
plot(id);
function plot(id) {
var series = [
{data: [1, 2, 4, 9], name: "temperature 1", display: true, color: '#2b908f'},
{data: [9, 4, 2, 1], name: "temperature 2", display: true},
{data: [0, 3, 5, 6], name: "temperature 3", display: false}
];
var series = [{"display": true, "data": [175.0, 497.86, 2802.46, 1657.75, 975.26, 2294.28, 450.0], "name": "\u5317\u4eac\u4e8c\u624b\u624b\u673a"}]
var options = {};
var options = {"scale": 2, "xAxis": {"categories": ["7\u6210\u65b0\u53ca\u4ee5\u4e0b", "8\u6210\u65b0", "95\u6210\u65b0", "99\u6210\u65b0", "9\u6210\u65b0", "\u5168\u65b0", "\u62a5\u5e9f\u673a/\u5c38\u4f53"], "title": {"text": "\u4e8c\u624b\u7269\u54c1\u7c7b\u76ee"}}, "height": 400, "chart": {"zoomType": "xy", "type": "line"}, "width": "auto", "type": "line", "title": {"text": "\u5317\u4eac\u4e8c\u624b\u624b\u673a\u5e73\u5747\u4ef7\u683c\u8d70\u52bf"}, "subtitle": {"text": "2015.01.01\u81f32015.12.30"}, "yAxis": {"title": {"text": "\u53d1\u5e16\u91cf"}}}
var useHighStock = false;
var useHighStock = false
var save = 'app/chart.svg';
var save = false
var url = 'http://127.0.0.1:65079';
var url = "http://127.0.0.1:61383/"
var settingsFile = 'settings';
var settingsFile = "settings"
var scale = options.scale;
//Create different containers for the charts
var chartContainer = document.getElementById("chart-container");
chartContainer.id = "chart-container" + id;
chartContainer.style.height = options.height.toString() + 'px';
if (options.width != 'auto') {
chartContainer.style.width = options.width.toString() + 'px';
}
var selector = $("#variable-selector");
selector.attr('id', "variable-selector" + id);
var settings = $("#settings-collapse");
settings.attr('id', "settings-collapse" + id);
var button = $("#settings-button");
button.attr('id', "settings-button" + id);
var saveButton = $("#save-settings");
saveButton.attr('id', "save-settings" + id);
var optionsInput = $("#options-input");
optionsInput.attr('id', "options-input" + id);
optionsInput.val(settingsFile);
var optionsButton = $("#options-button");
optionsButton.attr('id', "options-button" + id);
// create the editor
var editorContainer = document.getElementById("jsoneditor");
editorContainer.id = "jsoneditor" + id;
var editor = new JSONEditor(editorContainer);
button.on('click', showSettings);
saveButton.on('click', applyOptions);
optionsButton.on('click', saveOptions);
function applyOptions() {
var newOptions = editor.get();
setOptions(newOptions);
settings.collapse('hide');
}
function saveOptions(event) {
event.preventDefault();
applyOptions();
var options = chart.options;
delete options.exporting;
var name = optionsInput.val() ? optionsInput.val() + '.json' : 'settings.json';
options['settingsFile'] = name;
$.ajax({
type: "POST",
url: url,
data: JSON.stringify({
options: options,
name: name
})
});
}
function showSettings() {
settings.collapse('toggle');
}
//Choose a chart type
var ChartType = useHighStock ? Highcharts.StockChart : Highcharts.Chart;
//Default highchart colors
var colors = ['#7cb5ec', '#434348', '#90ed7d', '#f7a35c', '#8085e9',
'#f15c80', '#e4d354', '#2b908f', '#f45b5b', '#91e8e1'];
series.map(function (serie, index) {
if (!serie.color) {
serie['color'] = colors[index % 10];
}
return serie;
});
//Get all the keys
var keys = [];
var initialKeys = [];
$.each(series, function (index, serie) {
keys.push({
display: serie.display,
value: serie.name,
text: serie.name
});
if (serie.display) {
initialKeys.push(serie.name)
}
});
selector.selectize({
plugins: ['remove_button', 'restore_on_backspace'],
delimiter: ',',
options: keys,
items: initialKeys,
onItemAdd: function (key) {
console.log('series added');
addSeries(key);
newChart(chart.options, renderedSeries);
},
onItemRemove: function (key) {
console.log('series removed');
deleteSeries(key);
newChart(chart.options, renderedSeries);
}
});
//Set initial chart options
var chartOptions;
if (typeof options.chart === "undefined") {
chartOptions = {renderTo: chartContainer.id};
} else {
chartOptions = $.extend(options["chart"], {renderTo: chartContainer.id});
}
//Initial rendered series
var renderedSeries = [];
options = $.extend(options, {chart: chartOptions}, {series: renderedSeries});
var chart = new ChartType(options);
$.each(initialKeys, function (index, key) {
addSeries(key);
});
newChart(chart.options, renderedSeries);
editor.set(chart.options);
if (save) {
saveSVG(url, save)
}
function setOptions(options) {
//Prevent export from breaking
delete options.exporting;
options['exporting'] = {scale: options.scale};
chartContainer.style.height = options.height.toString() + 'px';
if (options.width != 'auto') {
chartContainer.style.width = options.width.toString() + 'px';
}
newChart(options, renderedSeries);
}
function findSeries(series, key) {
return series.findIndex(function (obj) {
return obj.name == key;
})
}
function newChart(options, series) {
//Disable animation
var newOptions = $.extend(options, {series: series});
newOptions.plotOptions['series'] = {animation: false};
//Get zoom
var xExtremes = chart.xAxis[0].getExtremes();
//Re-plot the chart
chart.destroy();
chart = new ChartType(newOptions);
//Reset the zoom
chart.xAxis[0].setExtremes(xExtremes.min, xExtremes.max, false, false);
//Re-draw chart
chart.redraw();
}
function addSeries(key) {
var index = findSeries(series, key);
var newSeries = series[index];
renderedSeries.push(newSeries)
}
function deleteSeries(key) {
var index = findSeries(renderedSeries, key);
renderedSeries.splice(index, 1)
}
function saveSVG(url, name) {
$.ajax({
type: "POST",
url: url,
data: JSON.stringify({
svg: chart.getSVG(),
name: name
})
});
}
console.log('loaded!', Date());
}
});
},{}]},{},[1]);
</script>