Commit 3090732a authored by Administrator's avatar Administrator

[FEATURE] CHART CORPUS OK, need to adapt first and last date of graphs.

parent c819f020
...@@ -33,7 +33,7 @@ urlpatterns = patterns('', ...@@ -33,7 +33,7 @@ urlpatterns = patterns('',
url(r'^exploration$', exploration), url(r'^exploration$', exploration),
url(r'^data.csv$', send_csv), url(r'^chart/corpus/(\d+)/data.csv$', send_csv),
url(r'^graph.json$', send_graph), url(r'^graph.json$', send_graph),
) )
......
...@@ -268,90 +268,44 @@ def corpus(request, project_id, corpus_id): ...@@ -268,90 +268,44 @@ def corpus(request, project_id, corpus_id):
project = Node.objects.get(id=project_id) project = Node.objects.get(id=project_id)
corpus = Node.objects.get(id=corpus_id) corpus = Node.objects.get(id=corpus_id)
#print(Document.objects.filter(corpus=c_id, user=request.user.pk).query) #documents = corpus.children.all()
documents = corpus.children.all() #number = corpus.children.count()
number = corpus.children.count()
# try:
# sources = defaultdict(int)
# for document in documents.all():
# sources[document.metadata['journal']] += 1
#
# sources_donut = []
#
# for source in sources.keys():
# source_count = dict()
# source_count['count'] = source['count']
# try:
# source_count['part'] = round(source_count['count'] * 100 / number)
# except:
# source_count['part'] = None
# source_count['source'] = source['source']
# sources_donut.append(source_count)
# except:
# sources_donut = []
try: try:
sources = defaultdict(int) chart = dict()
for document in documents.all(): chart['first'] = parse(corpus.children.first().metadata['publication_date']).strftime("%Y, %m, %d")
sources[document.metadata['journal']] += 1 chart['last'] = parse(corpus.children.last().metadata['publication_date']).strftime("%Y, %m, %d")
print(chart)
sources_donut = [] except Exception as error:
print(error)
for source in sources.keys():
source_count = dict()
source_count['count'] = source['count']
try:
source_count['part'] = round(source_count['count'] * 100 / number)
except:
source_count['part'] = None
source_count['source'] = source['source']
sources_donut.append(source_count)
except:
sources_donut = []
try:
histo = [
{'to_char': 2000, 'count': 13},
{'to_char': 2001, 'count': 20},
{'to_char': 2002, 'count': 5},
{'to_char': 2003, 'count': 130},
{'to_char': 2004, 'count': 300},
]
first = parse(documents.first().metadata['publication_date'])
last = parse(documents.last().metadata['publication_date'])
duree = first - last
if duree.days > 365:
date_format = 'YYYY'
date_form = 'years'
for document in documents:
pass
elif duree.days > 60:
date_format = 'YYYY-MM'
date_form = 'months'
else:
date_format = 'YYYY-MM-DD'
date_form = 'days'
try:
dates = dict()
except:
pass
# for e in date_range('1990-01', '1992-02', format=date_form):
# print(e)
# if date_format = 'YYYY':
# while True:
# if d -histo.append(d)
# for d in dates:
# histo.append(d)
except:
histo = [
{'to_char': 2000, 'count': 13},
{'to_char': 2001, 'count': 20},
{'to_char': 2002, 'count': 5},
{'to_char': 2003, 'count': 130},
{'to_char': 2004, 'count': 300},
]
#histo = None
html = t.render(Context({\ html = t.render(Context({\
'user': user,\ 'user': user,\
'date': date,\ 'date': date,\
'project': project,\ 'project': project,\
'corpus' : corpus,\ 'corpus' : corpus,\
'documents': documents,\ # 'documents': documents,\
'number' : number,\ # 'number' : number,\
'dates' : histo,\ 'dates' : chart,\
})) }))
return HttpResponse(html) return HttpResponse(html)
...@@ -416,7 +370,7 @@ def explorer_chart(request): ...@@ -416,7 +370,7 @@ def explorer_chart(request):
import csv import csv
from django.db import connection from django.db import connection
def send_csv(request): def send_csv(request, corpus_id):
''' '''
Create the HttpResponse object with the appropriate CSV header. Create the HttpResponse object with the appropriate CSV header.
''' '''
...@@ -424,8 +378,6 @@ def send_csv(request): ...@@ -424,8 +378,6 @@ def send_csv(request):
response['Content-Disposition'] = 'attachment; filename="data.csv"' response['Content-Disposition'] = 'attachment; filename="data.csv"'
writer = csv.writer(response) writer = csv.writer(response)
#writer = csv.writer(response, delimiter=',', quotechar=' ', quoting=csv.QUOTE_NONE)
cursor = connection.cursor() cursor = connection.cursor()
cursor.execute(""" cursor.execute("""
...@@ -442,7 +394,7 @@ def send_csv(request): ...@@ -442,7 +394,7 @@ def send_csv(request):
day, month, year day, month, year
ORDER BY ORDER BY
year, month, day ASC year, month, day ASC
""", [45044]) """, [corpus_id])
writer.writerow(['date','volume']) writer.writerow(['date','volume'])
...@@ -451,6 +403,7 @@ def send_csv(request): ...@@ -451,6 +403,7 @@ def send_csv(request):
if row is None: if row is None:
break break
writer.writerow([ row[0] + '/' + row[1] + '/' + row[2] , str(row[3]) ]) writer.writerow([ row[0] + '/' + row[1] + '/' + row[2] , str(row[3]) ])
#dates['last']['day'] = documents.last().metadata['publication_day'])
cursor.close() cursor.close()
......
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
<div class="row"> <div class="row">
<div id="monthly-move-chart"> <div id="monthly-move-chart">
<strong>Title</strong> (Blue Line: Avg Index, Green Line: Index Fluctuation) <strong>Title</strong> (Blue Line: Publications by months, Green Line: Zoomable publications)
<a class="reset" href="javascript:volumeChart.filterAll();dc.redrawAll();" <a class="reset" href="javascript:volumeChart.filterAll();dc.redrawAll();"
style="display: none;">reset</a> style="display: none;">reset</a>
<div class="clearfix"></div> <div class="clearfix"></div>
...@@ -65,7 +65,7 @@ ...@@ -65,7 +65,7 @@
</div> </div>
</div> </div>
<a class="btn btn-primary btn-lg" role="button" href="/data.csv">Save</a></p> <a class="btn btn-primary btn-lg" role="button" href="/chart/corpus/{{ corpus.id }}/data.csv">Save</a></p>
<div class="container"> <div class="container">
...@@ -117,8 +117,366 @@ ...@@ -117,8 +117,366 @@
<script src="{% static "js/charts/jquery-latest.js" %}"></script> <script src="{% static "js/charts/jquery-latest.js" %}"></script>
<script src="{% static "js/charts/bootstrap.min.js" %}"></script> <script src="{% static "js/charts/bootstrap.min.js" %}"></script>
<script src="{% static "js/d3/DC.js"%}"></script>
<script>
// var gainOrLossChart = dc.pieChart("#gain-loss-chart");
// var fluctuationChart = dc.barChart("#fluctuation-chart");
// var quarterChart = dc.pieChart("#quarter-chart");
// var dayOfWeekChart = dc.rowChart("#day-of-week-chart");
var moveChart = dc.compositeChart("#monthly-move-chart");
var volumeChart = dc.barChart("#monthly-volume-chart");
// var yearlyBubbleChart = dc.bubbleChart("#yearly-bubble-chart");
// set dc.js version in title
d3.selectAll("#version").text(dc.version);
// load data from a csv file
//
//
//
//
d3.csv("/chart/corpus/{{ corpus.id }}/data.csv", function (data) {
// since its a csv file we need to format the data a bit
var dateFormat = d3.time.format("%Y/%m/%d");
var numberFormat = d3.format(".2f");
data.forEach(function (e) {
e.dd = dateFormat.parse(e.date);
e.month = d3.time.month(e.dd); // pre-calculate month for better performance
});
// feed it through crossfilter
var ndx = crossfilter(data);
var all = ndx.groupAll();
/*
var yearlyDimension = ndx.dimension(function (d) {
return d3.time.year(d.dd);
});
var yearlyPerformanceGroup = yearlyDimension.group().reduce(
//add
function (p, v) {
++p.count;
p.absGain += +v.close - +v.open;
p.fluctuation += Math.abs(+v.close - +v.open);
p.sumIndex += (+v.open + +v.close) / 2;
p.avgIndex = p.sumIndex / p.count;
p.percentageGain = (p.absGain / p.avgIndex) * 100;
p.fluctuationPercentage = (p.fluctuation / p.avgIndex) * 100;
return p;
},
//remove
function (p, v) {
--p.count;
p.absGain -= +v.close - +v.open;
p.fluctuation -= Math.abs(+v.close - +v.open);
p.sumIndex -= (+v.open + +v.close) / 2;
p.avgIndex = p.sumIndex / p.count;
p.percentageGain = (p.absGain / p.avgIndex) * 100;
p.fluctuationPercentage = (p.fluctuation / p.avgIndex) * 100;
return p;
},
//init
function () {
return {count: 0, absGain: 0, fluctuation: 0, fluctuationPercentage: 0, sumIndex: 0, avgIndex: 0, percentageGain: 0};
}
);
var dateDimension = ndx.dimension(function (d) {
return d.dd;
});
*/
//volumeChart:(1)
//moveChart:(1)
// monthly index avg fluctuation in percentage
var moveMonths = ndx.dimension(function (d) {
return d.month;
});
//moveChart:(3)
var monthlyMoveGroup = moveMonths.group().reduceSum(function (d) {
return d.volume;
//return Math.abs(+d.close - +d.open);
});
//volumeChart:(2)
var volumeByMonthGroup = moveMonths.group().reduceSum(function (d) {
return d.volume / 500000;
});
//moveChart:(2)
var indexAvgByMonthGroup = moveMonths.group().reduce(
function (p, v) {
++p.days;
p.total += (+v.open + +v.close) / 2;
p.avg = Math.round(p.total / p.days);
return p;
},
function (p, v) {
--p.days;
p.total -= (+v.open + +v.close) / 2;
p.avg = p.days == 0 ? 0 : Math.round(p.total / p.days);
return p;
},
function () {
return {days: 0, total: 0, avg: 0};
}
);
/*
var gainOrLoss = ndx.dimension(function (d) {
return +d.open > +d.close ? "Loss" : "Gain";
});
var gainOrLossGroup = gainOrLoss.group();
var fluctuation = ndx.dimension(function (d) {
return Math.round((d.close - d.open) / d.open * 100);
});
var fluctuationGroup = fluctuation.group();
var quarter = ndx.dimension(function (d) {
var month = d.dd.getMonth();
if (month <= 3)
return "Q1";
else if (month > 3 && month <= 5)
return "Q2";
else if (month > 5 && month <= 7)
return "Q3";
else
return "Q4";
});
var quarterGroup = quarter.group().reduceSum(function (d) {
return d.volume;
});
var dayOfWeek = ndx.dimension(function (d) {
var day = d.dd.getDay();
switch (day) {
case 0:
return "0.Sun";
case 1:
return "1.Mon";
case 2:
return "2.Tue";
case 3:
return "3.Wed";
case 4:
return "4.Thu";
case 5:
return "5.Fri";
case 6:
return "6.Sat";
}
});
var dayOfWeekGroup = dayOfWeek.group();
*/
/*
yearlyBubbleChart.width(990)
.height(250)
.margins({top: 10, right: 50, bottom: 30, left: 40})
.dimension(yearlyDimension)
.group(yearlyPerformanceGroup)
.transitionDuration(1500)
.colors(["#a60000", "#ff0000", "#ff4040", "#ff7373", "#67e667", "#39e639", "#00cc00"])
.colorDomain([-12000, 12000])
.colorAccessor(function (d) {
return d.value.absGain;
})
.keyAccessor(function (p) {
return p.value.absGain;
})
.valueAccessor(function (p) {
return p.value.percentageGain;
})
.radiusValueAccessor(function (p) {
return p.value.fluctuationPercentage;
})
.maxBubbleRelativeSize(0.3)
.x(d3.scale.linear().domain([-2500, 2500]))
.y(d3.scale.linear().domain([-100, 100]))
.r(d3.scale.linear().domain([0, 4000]))
.elasticY(true)
.yAxisPadding(100)
.elasticX(true)
.xAxisPadding(500)
.renderHorizontalGridLines(true)
.renderVerticalGridLines(true)
.renderLabel(true)
.renderTitle(true)
.label(function (p) {
return p.key.getFullYear();
})
.title(function (p) {
return p.key.getFullYear()
+ "\n"
+ "Index Gain: " + numberFormat(p.value.absGain) + "\n"
+ "Index Gain in Percentage: " + numberFormat(p.value.percentageGain) + "%\n"
+ "Fluctuation / Index Ratio: " + numberFormat(p.value.fluctuationPercentage) + "%";
})
.yAxis().tickFormat(function (v) {
return v + "%";
});
*/
/*
gainOrLossChart.width(180)
.height(180)
.radius(80)
.dimension(gainOrLoss)
.group(gainOrLossGroup)
.label(function (d) {
return d.data.key + "(" + Math.floor(d.data.value / all.value() * 100) + "%)";
});
*/
/*
quarterChart.width(180)
.height(180)
.radius(80)
.innerRadius(30)
.dimension(quarter)
.group(quarterGroup);
*/
/*
dayOfWeekChart.width(180)
.height(180)
.margins({top: 20, left: 10, right: 10, bottom: 20})
.group(dayOfWeekGroup)
.dimension(dayOfWeek)
.colors(['#3182bd', '#6baed6', '#9ecae1', '#c6dbef', '#dadaeb'])
.label(function (d){
return d.key.split(".")[1];
})
.xAxis().ticks(4);
*/
/*
fluctuationChart.width(420)
.height(180)
.margins({top: 10, right: 50, bottom: 30, left: 40})
.dimension(fluctuation)
.group(fluctuationGroup)
.elasticY(true)
.centerBar(true)
.gap(1)
.round(dc.round.floor)
.x(d3.scale.linear().domain([-25, 25]))
.renderHorizontalGridLines(true)
.xAxis()
.tickFormat(function (v) {
return v + "%";
});
*/
moveChart.width(800)
.height(150)
.transitionDuration(1000)
.margins({top: 10, right: 50, bottom: 25, left: 40})
.dimension(moveMonths)
.group(indexAvgByMonthGroup)
.valueAccessor(function (d) {
return d.value.avg;
})
.x(d3.time.scale().domain([new Date(1950,01,01), new Date(2014,12,31)]))
.round(d3.time.month.round)
.xUnits(d3.time.months)
.elasticY(true)
.renderHorizontalGridLines(true)
.brushOn(false)
.compose([
dc.lineChart(moveChart).group(indexAvgByMonthGroup)
.valueAccessor(function (d) {
return d.value.avg;
})
.renderArea(true)
.stack(monthlyMoveGroup, function (d) {
return d.value;
})
.title(function (d) {
var value = d.value.avg ? d.value.avg : d.value;
if (isNaN(value)) value = 0;
return dateFormat(d.key) + "\n" + numberFormat(value);
})
])
.xAxis();
volumeChart.width(800)
.height(100)
.margins({top: 0, right: 50, bottom: 20, left: 40})
.dimension(moveMonths)
.group(volumeByMonthGroup)
.centerBar(true)
.gap(0)
.x(d3.time.scale().domain([new Date(1950, 01, 01), new Date(2015, 01, 01)]))
.round(d3.time.month.round)
.xUnits(d3.time.months)
.renderlet(function (chart) {
chart.select("g.y").style("display", "none");
moveChart.filter(chart.filter());
})
.on("filtered", function (chart) {
dc.events.trigger(function () {
moveChart.focus(chart.filter());
});
});
/*
dc.dataCount(".dc-data-count")
.dimension(ndx)
.group(all);
*/
/*
dc.dataTable(".dc-data-table")
.dimension(dateDimension)
.group(function (d) {
var format = d3.format("02d");
return d.dd.getFullYear() + "/" + format((d.dd.getMonth() + 1));
})
.size(10)
.columns([
function (d) {
return d.date;
},
function (d) {
return d.open;
},
function (d) {
return d.close;
},
function (d) {
return numberFormat(d.close - d.open);
},
function (d) {
return d.volume;
}
])
.sortBy(function (d) {
return d.dd;
})
.order(d3.ascending)
.renderlet(function (table) {
table.selectAll(".dc-table-group").classed("info", true);
});
*/
dc.renderAll();
}
);
</script>
{% endblock %} {% endblock %}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment