1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/RichAndyZ-VisualData

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
app.js 21 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Andy Отправлено 18.09.2019 05:52 b9c6f71
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
(function (echarts) {
var dataResults = [];
var chartIndex = 0;
var axisOptions = "";
if (!echarts) {
echarts = window.echarts;
}
function updateChartsOptions(chartsContainerElement) {
axisOptions = "";
$.each(dataResults[0], function (name) {
if (name) {
axisOptions += '<option val="' + name + '">' + name + '</option>';
}
});
if (!chartsContainerElement) {
chartsContainerElement = $("#chartsPanel");
}
//update all elements on page
$(".my-x-axis", chartsContainerElement).empty();
$(".my-y-series tbody", chartsContainerElement).empty();
$(".my-x-axis", chartsContainerElement).append(axisOptions);
$('.my-filter-expression', chartsContainerElement).val("");
$(".my-group-expression", chartsContainerElement).val("");
addNewSerieRowInTbody($(".my-y-series tbody", chartsContainerElement));
$(".my-selected-y-serie", chartsContainerElement).append(axisOptions);
}
function onFileDataLoaded(data, columns) {
dataResults = data;
$("#dataGridContainer")
.append("<table id='dataGrid' class='table table-striped table-bordered' width='100%'></table>");
$('#dataGrid').DataTable({
data: data,
columns: columns,
scrollX: true,
destroy: true
});
updateChartsOptions();
}
function onParseFileComplete(results) {
$("#loadingLabel").text("Succeed to load file");
$("#loadingLabel").hide(3000);
if (results && results.errors) {
if (results.errors) {
var errorCount = results.errors.length;
var firstError = results.errors[0];
console.error("Got " + errorCount + " errors to parse data file. " + firstError, + results.errors);
}
if (results.data && results.data.length > 0) {
var rowCount = results.data.length;
console.log("Got " + rowCount + " records from data file.");
}
}
//console.log("parse file succeed Results:", results);
if (results && results.data && results.data.length > 0) {
dataResults = results.data;
var columns = [];
if ($('#header').prop('checked')) {
$.each(results.data[0], function (name) {
columns.push({ data: name, title: name });
});
} else {
$.each(results.data[0], function (index) {
columns.push({ title: "col-" + index });
});
}
onFileDataLoaded(results.data, columns);
}
}
function onParseFileError(err, file) {
$("#loadingLabel").text("Failed to load file");
$("#loadingLabel").hide(3000);
console.error("Got error to read file '" + file + "'", err, file);
}
function handleFileSelect(evt) {
var dataTable = $('#dataGrid').DataTable();
if (dataTable) {
dataTable.destroy();
}
$('#dataGridContainer').empty();
var files = evt.target.files;
//console.log(files);
if (files.length > 0) {
if (files[0].name.indexOf(".json") > 0) {
var fileReader = new FileReader();
fileReader.onerror = function (e) {
onParseFileError(e.target.error, files[0].name);
};
fileReader.onload = function (e) {
$("#loadingLabel").text("Succeed to load file");
$("#loadingLabel").hide(3000);
//console.log("loaded json file", e);
var dataResult = JSON.parse(e.target.result);
if (dataResult && dataResult.length > 0) {
var columns = [];
$.each(dataResult[0], function (name) {
columns.push({ data: name, title: name });
});
onFileDataLoaded(dataResult, columns);
}
};
if (files[0].name.startsWith("http") > 0) {
fileReader.readAsDataURL(files[0]);
} else {
fileReader.readAsText(files[0], $('#encoding').val());
}
} else {
$('#dataFile').parse({
config:
{
delimiter: $('#delimiter').val(),
header: $('#header').prop('checked'),
dynamicTyping: $('#dynamicTyping').prop('checked'),
skipEmptyLines: true,
preview: 0,
step: null,
encoding: $('#encoding').val(),
worker: false, //should be false, or it has problem in IE
comments: '',
complete: onParseFileComplete,
error: onParseFileError,
download: false
}
});
}
$("#loadingLabel").text("Loading file...");
$("#loadingLabel").show();
}
}
//send notification in modal dialog
function notifyMessage(title, message) {
$("#myModal .modal-title").text(title);
$("#myModal .modal-body").text(message);
$("#myModal").modal('show');
}
function groupBy(array, key, groupExpression) {
var groupFunction = null;
if (groupExpression && groupExpression !== '' && groupExpression.trim() !== '') {
groupFunction = new Function('dataItem', 'return ' + groupExpression);
}
return array.reduce(function (objectsByKeyValue, dataItem) {
var value;
if (groupFunction) {
value = groupFunction(dataItem);
} else if (key && key !== '') {
value = dataItem[key];
} else {
throw new Error("should either specify groupExpression or key.");
}
objectsByKeyValue[value] = (objectsByKeyValue[value] || []).concat(dataItem);
return objectsByKeyValue;
}, {});
}
function getAggregateValue(array, key, aggregateOption) {
if (!array || array.length <= 0) {
return null;
}
if (!aggregateOption || aggregateOption === "") {
return array[0][key];
} else if (aggregateOption === "Sum") {
return array.reduce(function (total, currentObj) {
return total += parseFloat(currentObj[key]);
}, 0);
} else if (aggregateOption === "Count") {
var countObj =
array.reduce(function (countObj, currentObj) {
if (!countObj.hasOwnProperty(currentObj[key])) {
countObj[currentObj[key]] = true;
countObj.count += 1;
}
return countObj;
}, { count: 0 });
return countObj.count;
} else if (aggregateOption === "Avg") {
return array.reduce(function (total, currentObj) {
return total += parseFloat(currentObj[key]);
}, 0) / array.length;
} else if (aggregateOption === "Max") {
return array.reduce(function (max, currentObj) {
return max < currentObj[key] ? currentObj[key] : max;
}, array[0][key]);
} else if (aggregateOption === "Min") {
return array.reduce(function (min, currentObj) {
return min > currentObj[key] ? currentObj[key] : min;
}, array[0][key]);
} else if (aggregateOption === "First") {
return array[0][key];
} else if (aggregateOption === "Last") {
return array[array.length - 1][key];
} else {
throw new Error("Unsupport aggregate option " + aggregateOption);
}
}
function generateSerieName(serieOption) {
if (serieOption.aggregateOption && serieOption.aggregateOption !== "") {
return serieOption.aggregateOption + "(" + serieOption.field + ")";
}
return serieOption.field;
}
function generateChart(event) {
//console.log("generate clicked", event);
if (!event.target) {
console.error("No target in event.", event);
return;
}
//only genereate chart for current panel
var chartContainer = $(event.target).parents(".my-chart-container");
var chartType = chartContainer.find(".my-chart-type").val();
var xAxis = chartContainer.find(".my-x-axis").val();
var xAxisType = chartContainer.find(".my-x-axis-type").val();
var filterExpression = chartContainer.find(".my-filter-expression").val().trim();
var groupExpression = chartContainer.find(".my-group-expression").val().trim();
var selectedYSeriesOptionElements = $(".my-selected-y-serie", chartContainer);
var ySeriesOptions = [];
for (var i = 0; i < selectedYSeriesOptionElements.length; ++i) {
if (!$(selectedYSeriesOptionElements[i]).val() || $(selectedYSeriesOptionElements[i]).val() === "") {
continue;
}
var options = {
field: $(selectedYSeriesOptionElements[i]).val(),
yAxisPostion: $(selectedYSeriesOptionElements[i]).attr("data-y-axis-position"),
aggregateOption: $(selectedYSeriesOptionElements[i]).attr("data-y-axis-aggregate-type")
};
//check whether there is duplicate serie
var isDuplicateSerie = false;
for(var j = 0; j < ySeriesOptions.length; ++j){
if (ySeriesOptions[j].field === options.field
&& ySeriesOptions[j].aggregateOption === options.aggregateOption) {
isDuplicateSerie = true;
}
}
if (!isDuplicateSerie) {
ySeriesOptions.push(options);
}
}
// console.log("selected type: ", chartType);
// console.log("selected x axis: ", xAxis, xAxisType);
// console.log("selected y series: ", ySeries);
// console.log("filterExpression: ", filterExpression);
// console.log("groupExpression: ", groupExpression);
// console.log("aggregate options: ", aggregateOptionsObj);
if (!xAxis) {
notifyMessage("Warning", "Please select an xAxis!");
return;
}
if (!ySeriesOptions || ySeriesOptions.length < 1) {
notifyMessage("Warning", "Please select at least one series!");
return;
}
var seriesData = [];
var dimensions = [];
dimensions.push(xAxis);
$.each(ySeriesOptions, function (_, ySerie) {
dimensions.push(generateSerieName(ySerie));
});
//apply filter expression
var filteredDataResults = [];
if (filterExpression && filterExpression !== '' && filterExpression.trim() !== '') {
var filterFunction = new Function('dataItem', 'return ' + filterExpression);
$.each(dataResults, function (_, dataItem) {
if (!filterFunction(dataItem)) {
return;
}
filteredDataResults.push(dataItem);
});
} else {
filteredDataResults = dataResults;
}
//apply group expression
var groupedDataObj = groupBy(filteredDataResults, xAxis, groupExpression);
$.each(groupedDataObj, function (key, valueArray) {
var dataArray = [];
dataArray.push(key);
$.each(ySeriesOptions, function (_, ySerie) {
dataArray.push(getAggregateValue(valueArray, ySerie.field, ySerie.aggregateOption));
});
seriesData.push(dataArray);
});
//sort data by xAxis
seriesData =
seriesData.sort(function(a, b) {
if (a[0] < b[0]) {
return -1;
} else if (a[0] === b[0]) {
return 0;
} else {
return 1;
}
});
//console.log("final chart data: ", xAxisData, seriesData);
var chartOptions = {
title: {
text: $(".my-chart-title", chartContainer).val(),
left: 'center',
top: 10
},
tooltip: {
trigger: 'axis',
axisPointer: {
show: true,
type: 'cross',
lineStyle: {
type: 'dashed',
width: 1
}
}
},
toolbox: {
show: true,
feature: {
mark: { show: true },
dataView: { show: true, readOnly: false },
restore: { show: true },
saveAsImage: { show: true },
magicType: {
show: true,
title: {
line: '折线图切换',
bar: '柱形图切换',
scatter: '散点切换',
pie: '饼图切换'
},
type: ['line', 'bar', 'scatter', 'pie']
}
}
},
dataZoom: [
{
type: 'slider',
show: chartType !== 'pie' ? true : false
},
{
type: 'inside',
disabled: chartType !== 'pie' ? false : true
}
],
legend: {
show: chartType === 'pie' && seriesData.length > 8 ? false : true,
top: 30
},
dataset: {
source: seriesData,
sourceHeader: false,
dimensions: dimensions
},
xAxis: [
{
type: xAxisType,
//splitNumber: 10,
show: chartType !== 'pie' ? true : false
}
],
yAxis: [
],
series: []
};
//handle yAxis, we may have one or two y axis
var leftAxisIndex = -1, rightAxisIndex = -1, axisIndex = -1;
$.each(ySeriesOptions, function (_, serieOption) {
if (!serieOption.yAxisPostion || serieOption.yAxisPostion === 'left') {
if (leftAxisIndex < 0) {
leftAxisIndex = ++axisIndex;
serieOption.yAxisIndex = leftAxisIndex;
chartOptions.yAxis.push({
type: 'value',
show: chartType !== 'pie' ? true : false,
position: 'left'
});
chartOptions.dataZoom.push({
type: 'slider',
show: chartType !== 'pie' ? true : false,
yAxisIndex: leftAxisIndex,
filterMode: 'empty',
showDataShadow: false,
left: '4%'
});
}
serieOption.yAxisIndex = leftAxisIndex;
} else {
if (rightAxisIndex < 0) {
rightAxisIndex = ++axisIndex;
chartOptions.yAxis.push({
type: 'value',
show: chartType !== 'pie' ? true : false,
position: 'right'
});
chartOptions.dataZoom.push({
type: 'slider',
show: chartType !== 'pie' ? true : false,
yAxisIndex: rightAxisIndex,
filterMode: 'empty',
showDataShadow: false,
left: '95%'
});
}
serieOption.yAxisIndex = rightAxisIndex;
}
});
if (chartType === 'pie') {
var pieOptions = {
tooltip: {
trigger: 'item',
formatter: "{a} <br/>{b} : {c} ({d}%)"
},
label: {
normal: {
textStyle: {
color: 'rgba(255, 255, 255, 0.3)'
}
}
},
labelLine: {
normal: {
lineStyle: {
color: 'rgba(255, 255, 255, 0.3)'
},
smooth: 0.2,
length: 10,
length2: 20
}
}
};
chartOptions = $.extend({}, chartOptions, pieOptions);
}
$.each(ySeriesOptions, function (_, ySerie) {
var serieName = generateSerieName(ySerie);
var series = {
name: serieName,
type: chartType,
yAxisIndex: ySerie.yAxisIndex
};
if (chartType !== 'pie') {
series.encode = {
x: xAxis,
y:serieName,
itemName: xAxis
};
}
else {
series.encode = {
tooltip: serieName,
value: serieName,
itemName: xAxis
};
}
chartOptions.series.push(series);
});
var chartElement = chartContainer.find(".my-chart")[0];
var chart = echarts.getInstanceByDom(chartElement);
if (!chart) {
chart = echarts.init(chartElement);
} else {
chart.clear();
}
chart.setOption(chartOptions);
}
function removeCurrentChart(event) {
//console.log("remove chart clicked", event);
if (!event.target) {
console.error("No target in event.", event);
return;
}
//only genereate chart for current panel
var chartContainer = $(event.target).parents(".my-chart-container");
chartContainer.remove();
}
function addNewChart() {
var chartTemplate = $("#chart-template").html();
chartTemplate = chartTemplate.replace(/\$\{chartNum\}/gm, ++chartIndex);
$("#chartsPanel").append(chartTemplate);
updateChartsOptions($("#chart" + chartIndex));
}
function updateDataTagToSelectedYSerie(event, sourceElementSelector, dataAttribute) {
if (!event.target) {
console.error("No target in event.", event);
return;
}
var rowContainer = $(event.target).parents("tr");
var sourceElement = $(sourceElementSelector, rowContainer);
var ySelectedYSerie = $(".my-selected-y-serie", rowContainer);
ySelectedYSerie.attr(dataAttribute, sourceElement.val());
}
function yAxisPositionChanged(event) {
updateDataTagToSelectedYSerie(event, ".my-y-axis-position", "data-y-axis-position");
}
function yAxisAggreateTypeChanged(event) {
updateDataTagToSelectedYSerie(event, ".my-y-axis-aggregate-type", "data-y-axis-aggregate-type");
}
function removeCurrentSerieRow(event){
if (!event.target) {
console.error("No target in event.", event);
return;
}
event.preventDefault();
var currentRow = $(event.target).parents("tr");
currentRow.remove();
}
function addNewSerieRow(event) {
if (!event.target) {
console.error("No target in event.", event);
return;
}
event.preventDefault();
var seriesTable = $("tbody", $(event.target).parents(".my-y-series"));
addNewSerieRowInTbody(seriesTable);
$("tr:last-child .my-selected-y-serie", seriesTable).append(axisOptions);
}
function addNewSerieRowInTbody(tbody) {
var rowTemplate = $("#serie-row-template").html();
tbody.append(rowTemplate);
}
$(document).ready(function () {
addNewChart();
$('#dataFile').on('change', handleFileSelect);
$("#addChartBtn").on("click", addNewChart);
//$("#chartsPanel").on('input propertychange', ".my-group-expression", groupExpressionChanged);
$("#chartsPanel").on('click', ".my-generate-btn", generateChart);
$("#chartsPanel").on('click', ".my-remove-chart-btn", removeCurrentChart);
$("#chartsPanel").on('change', ".my-y-axis-position", yAxisPositionChanged);
$("#chartsPanel").on('change', ".my-y-axis-aggregate-type", yAxisAggreateTypeChanged);
$("#chartsPanel").on('click', ".remove-y-serie-button", removeCurrentSerieRow);
$("#chartsPanel").on('click', ".add-y-serie-button", addNewSerieRow);
window.addEventListener("resize", function () {
//resize all charts
var chartElements = document.getElementsByClassName("my-chart");
$.each(chartElements, function (_, element) {
var chart = echarts.getInstanceByDom(element);
if (chart) {
chart.resize();
}
});
});
});
})();

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/RichAndyZ-VisualData.git
git@api.gitlife.ru:oschina-mirror/RichAndyZ-VisualData.git
oschina-mirror
RichAndyZ-VisualData
RichAndyZ-VisualData
master