I running a script to take rows and columns from a worksheet and use it to make charts. The problem that I am running into is that since the rows in the MSEXCEL sheet are changing, I want to add the last row in the add_series argument so that it will always take the limit of the chart data from row 2 till the last row.
This is the code that I am using currently (that I want to change):
chart1 = workbook.add_chart({'type': 'column'})
chart1.add_series({
'values': "='Sheet1'!$B$2:$B$126",
'categories': "='Sheet1'!$A$2:$A$126",
'data_labels': {'value': False, 'categories': False, 'series': False}
})
I have modified the above code to the following, but now the charts are not getting any data whatsoever.
chart1 = workbook.add_chart({'type': 'column'})
chart1.add_series({
'values': "='Sheet1'!$B$2:($B$ + str(last_row_number + 1)",
'categories': "='Sheet1'!$A$2:($A$ + str(last_row_number + 1)",
'data_labels': {'value': False, 'categories': True, 'series': False}
last_row_number in this case is a variable [<type 'int'>] calculated by enumerating through the worksheet column.
Thanks in advance.
Almost every interface in XlsxWriter supports (row, col) notation as well as A1 range notation.
In the case of add_series() you can use lists like [sheetname, first_row, first_col, last_row, last_col]:
chart.add_series({
'categories': ['Sheet1', 1, 0, 125, 0],
'values': ['Sheet1', 1, 1, 125, 1],
# ...
})
# Or:
last_row = 125
chart.add_series({
'categories': ['Sheet1', 1, 0, last_row, 0],
'values': ['Sheet1', 1, 1, last_row, 1],
# ...
})
See the docs for add_series().
Related
I am retrieving data from multiple tables in Django.
my current response is :
{
"status": 0,
"message": "Client details retrived successfully...!!!",
"results": [
{
"id": 11,
"client_id": "CL15657917080578748000",
"client_name": "Pruthvi Katkar",
"client_pan_no": "RGBB004A11",
"client_adhar_no": "12312312313",
"legal_entity_name": "ABC",
"credit_period": "6 months",
"client_tin_no": 4564565,
"client_email_id": "abc#gmail.com",
"head_office_name": "ABC",
"office_name": "asd234",
"office_email_id": "zxc#gmail.com",
"office_contact": "022-27547119",
"gst_number": "CGST786876876",
"office_country": "India",
"office_state": "gujrat",
"office_district": "vadodara",
"office_taluka": "kachh",
"office_city": "vadodara",
"office_street": "New rode 21",
"office_pincode": 2344445,
"contact_person_name": "prasad",
"contact_person_designation": "DM",
"contact_person_number": "456754655",
"contact_person_email": "asd#gmail.com",
"contact_person_mobile": "5675545654",
"created_at": "2019-08-14T14:08:28.057Z",
"created_by": "Prathamseh",
"updated_at": "2019-08-14T14:08:28.057Z",
"updated_by": "prasad",
"is_deleted": false
},
{
"id": 11,
"user_id": "CL15657917080578748000",
"bank_details_id": "BL15657917080778611000",
"bank_name": "Pruthvi",
"branch": "vashi",
"ifsc_code": "BOI786988",
"account_number": 56756765765765,
"account_name": "Pruthvi",
"is_deleted": false
},
{
"id": 10,
"document_details_id": "DL15657917080808598000",
"user_id": "CL15657917080578748000",
"document_type": "Pruthvi ID",
"document": "www.sendgrid.com/pan",
"is_deleted": false
}
]
}
Expected Response :
I am getting the queryset form db in models.py and i am sending it to the views.py and i am iterating over the dict but not getting the expected response.
views.py
#csrf_exempt
def get_client_details(request):
try:
# Initialising lists for storing results
result = []
temp_array = []
# Getting data from request body
client_master_dict = json.loads(request.body)
# Response from get client data
records = ClientDetails.get_client_data(client_master_dict)
# Create response object
# Iterating over the records object for getting data
for i in range(len(records)):
# Converting the querysets objects to json array format
record_result_list = list(records[i].values())
# If multiple records are present
if(len(record_result_list) > 1):
for j in range(len(record_result_list)):
user_info = record_result_list[j]
temp_array.append(user_info)
result.append(temp_array)
temp_array=[]
# For single record
else:
result.append(record_result_list[0])
# Success
returnObject = {
"status" : messages.SUCCESS,
"message" : messages.CLIENT_RETRIVE_SUCCESS,
"results" : result
}
return JsonResponse(returnObject,safe=False)
I think the issue might be in my inner for loop, can anyone help me out with this, is there any way to iterate over the nested JSON object.
Models.py
#classmethod
def get_client_data(cls, client_master_dict):
try:
response_list = []
client_id = client_master_dict['client_id']
client_details = cls.objects.filter(client_id = client_id,is_deleted = False)
bank_details = BankDetails.objects.filter(user_id = client_id,is_deleted = False)
document_details = DocumentDetails.objects.filter(user_id = client_id,is_deleted = False)
response_list.append(client_details)
response_list.append(bank_details)
response_list.append(document_details)
return response_list
except(Exception) as error:
print("Error in get_client_data",error)
return False
Here i'm fetching data from 3 tables and adding it into list.
After printing the data on console i am getting :
[{'id': 11, 'client_id': 'CL15657917080578748000', 'client_name': 'Pruthvi Katkar', 'client_pan_no': 'RGBB004A11', 'client_adhar_no': '12312312313', 'legal_entity_name': 'ABC', 'credit_period': '6 months', 'client_tin_no': 4564565, 'client_email_id': 'abc#gmail.com', 'head_office_name': 'ABC', 'office_name': 'asd234', 'office_email_id': 'zxc#gmail.com', 'office_contact': '022-27547119', 'gst_number': 'CGST786876876', 'office_country': 'India', 'office_state': 'gujrat', 'office_district': 'vadodara', 'office_taluka': 'kachh', 'office_city': 'vadodara', 'office_street': 'New rode 21', 'office_pincode': 2344445, 'contact_person_name': 'prasad', 'contact_person_designation': 'DM', 'contact_person_number': '456754655', 'contact_person_email': 'asd#gmail.com', 'contact_person_mobile': '5675545654', 'created_at': datetime.datetime(2019, 8, 14, 14, 8, 28, 57874, tzinfo=<UTC>), 'created_by': 'Prathamseh', 'updated_at': datetime.datetime(2019, 8, 14, 14, 8, 28, 57874, tzinfo=<UTC>), 'updated_by': 'prasad', 'is_deleted': False}]
[{'id': 11, 'user_id': 'CL15657917080578748000', 'bank_details_id': 'BL15657917080778611000', 'bank_name': 'Pruthvi', 'branch': 'vashi', 'ifsc_code': 'BOI786988', 'account_number': 56756765765765, 'account_name': 'Pruthvi', 'is_deleted': False}]
[{'id': 10, 'document_details_id': 'DL15657917080808598000', 'user_id': 'CL15657917080578748000', 'document_type': 'Pruthvi ID', 'document': 'www.sendgrid.com/pan', 'is_deleted': False}]
Did you check the output of record_result_list? You can outright tell their if it's recovering the data in the format you requested. Try the printing to screen method to debug.
As far as I cam see, the expected output and the hierarchy of results for bank details are not matching. I don't know how you are handling the hierarchy. Are you directly taking it from JSON as the hierarchy? Or are you just taking the data and creating hierarchy in the expected output?
I have created Highcharts graph by this code:
def chart_data(request):
dataset = DispatchPlan.objects.annotate(month=TruncMonth('scheduled_date')).values('month').annotate(
c=Sum('weight')).values('month', 'c')
chart = {
'chart': {'type': 'column'},
'title': {'text': 'Weight Dispatched by Months'},
'series': [{
'name': 'Months',
'data': [{'name': row['month'], 'y': row["c"]} for row in dataset]
}]
}
return JsonResponse(chart)
How can I add the X axis labels such that it shows month name instead of 0 and 1 ?
This is the one row of dataset from which the graph is plotted
{'month': datetime.datetime(2019, 6, 1, 0, 0, tzinfo=<DstTzInfo 'Asia/Kolkata' IST+5:30:00 STD>), 'c': 17600}
Try to use strftime (documentation) like that :
{'month': datetime.datetime(2019, 6, 1, 0, 0, tzinfo=<DstTzInfo 'Asia/Kolkata' IST+5:30:00 STD>).strftime("%B"), 'c': 17600}
I'm trying to add an interactive shape (circle) to a set of subplots (for simplicity, below I use only one empty plot to create a simple reproducible example).
Intended behaviour of the code below is to be able to switch between two different circles using a drop down menu.
import plotly.plotly as py
import plotly.graph_objs as go
from plotly import tools
# Create empty plot to put shapes into
scatter = go.Scatter()
fig = tools.make_subplots(cols=1)
fig.append_trace(scatter, 1, 1)
# Create two different shapes to select from
fig['layout']['shapes'].append(
{
'type': 'circle',
'xref': 'x', 'yref': 'y',
'x0': 0, 'y0': 0, 'x1': 1, 'y1': 1,
'visible':True
})
fig['layout']['shapes'].append(
{
'type': 'circle',
'xref': 'x', 'yref': 'y',
'x0': 0, 'y0': 0, 'x1': 0.5, 'y1': 0.5,
'visible':False
})
# This doesn't work
fig['layout']['updatemenus'] =
[{
x:-0.05, y:0.8,
buttons=[
{args:['layout.shapes.visible', [True, False]], label:'1', method:'restyle'},
{args:['layout.shapes.visible', [False, True]], label:'2', method:'restyle'}
]
}]
py.plot(fig, filename='shape_select')
I assume my mistake is that I refer to visible parameter in a wrong way, and layout.shapes.visible should be replaced with something else.
So, how do I properly refer to shape parameters in this case?
Either I am too stupid to find the obvious solution, but this seems like a like a bug or unspecified behavior to me.
The last 8 drop down items reliably work. The first 8 have some unspecified behavior depending on the order they are clicked and might interfere one with another..
The suggested solution uses argument unpacking to create the dictionaries for the shapes on the fly and setting visible for each shape.
import plotly
shape1 = {
'type': 'circle',
'xref': 'x', 'yref': 'y',
'x0': 0, 'y0': 0, 'x1': 1, 'y1': 1,
'line': {'color': 'rgb(0, 0, 255)'}
}
shape2 = {
'type': 'circle',
'xref': 'x', 'yref': 'y',
'x0': 0, 'y0': 0, 'x1': 0.5, 'y1': 0.5,
'line': {'color': 'rgb(255, 0, 255)'}
}
trace0 = plotly.graph_objs.Scatter(
x= [0.2, 0.2, 0.3, 0.4, 0.2],
y= [0.2, 0.5, 0.8, 0.3, 0.2]
)
data = plotly.graph_objs.Data([trace0])
layout = plotly.graph_objs.Layout(shapes=[shape1, shape2])
fig = plotly.graph_objs.Figure(data=data, layout=layout)
fig['layout']['shapes'].append(dict(visible=True, **shape1))
fig['layout']['shapes'].append(dict(visible=True, **shape2))
fig['layout']['updatemenus'] = [dict(
x=-0.05, y=0.8,
buttons=[
dict(args=['shapes.visible', [False, True]], label='Hide big - does not work', method='relayout'),
dict(args=['shapes.visible', [True, False]], label='Hide small - does not work', method='relayout'),
dict(args=['shapes[0].visible', False], label='Hide big - might work', method='relayout'),
dict(args=['shapes[1].visible', False], label='Hide small - might work', method='relayout'),
dict(args=['shapes[0].visible', True], label='Show big', method='relayout'),
dict(args=['shapes[1].visible', True], label='Show small', method='relayout'),
dict(args=['shapes', [dict(visible=True, **shape1), dict(visible=True, **shape2)]], label='Show all', method='relayout'),
dict(args=['shapes', [dict(visible=False, **shape1), dict(visible=False, **shape2)]], label='Hide all', method='relayout'),
dict(args=['shapes', [dict(visible=True, **shape1), dict(visible=False, **shape2)]], label='Show big, hide small', method='relayout'),
dict(args=['shapes', [dict(visible=False, **shape1), dict(visible=True, **shape2)]], label='Hide big, show small', method='relayout')
]
)]
plotly.offline.plot(fig, filename='shape_select.html')
This a bit more compact solution works as well:
fig['layout']['updatemenus'] = [dict(
x=-0.05, y=0.8,
dict(args=[{'shapes[0].visible': True, 'shapes[1].visible': False}], label='First circle', method='relayout'),
dict(args=[{'shapes[0].visible': False, 'shapes[1].visible': True}], label='First circle', method='relayout'),
]
)]
Im trying to filter column 'time' in visualization data table using getFilteredRows(filters) method.I provided column value with minimum and maximum values as,
var timesheet_dataTable = new google.visualization.DataTable(data, 0.6);
var time_filter = timesheet_dataTable.getFilteredRows([{column: 3, minValue: '2:28 PM', maxValue: '3:01 PM'}]);
and then created data view with setRows method to display the data but the table displayed without filtering the data.I checked with other column values and received proper output.So whether 'timeofday' data type is supported in this type of filters?
Is there any other method to filter column based on time?
Update:
This is the code for formatting and passing value to the visualization table.Value of variable startTime will be like '14:28:12'.
val datetimeStart: String = "Date(0,0,0,"
val datetimeEnd: String = ")"
val simpleDateTimeFormat = new SimpleDateFormat("HH,mm,ss")
Json.obj("v" -> JsString(datetimeStart + (simpleDateTimeFormat.format(tsl.startTime)).toString() + datetimeEnd))
before displaying in visualization table i have used formatter as:
var formatter_short1 = new google.visualization.DateFormat({pattern:'h:mm aa'});
formatter_short1.format(timesheet_dataTable,3);
The "timeofday" data type is supported by the filter method, you just need to use it correctly:
// filter column 3 from 2:28PM to 3:01PM
var time_filter = timesheet_dataTable.getFilteredRows([{
column: 3,
minValue: [14, 28, 0, 0],
maxValue: [15, 1, 0, 0]
}]);
var view = new google.visualization.DataView(timesheet_dataTable);
view.setRows(time_filter);
Make sure you are using the view you create to draw your chart, instead of the DataTable:
chart.draw(view, options);
[edit - example for filtering "datetime" type column]
// filter column 3 from 2:28PM to 3:01PM
var time_filter = timesheet_dataTable.getFilteredRows([{
column: 3,
minValue: new Date(0, 0, 0, 14, 28, 0, 0),
maxValue: new Date(0, 0, 0, 15, 1, 0, 0)
}]);
var view = new google.visualization.DataView(timesheet_dataTable);
view.setRows(time_filter);
I've got the template to render manually, but not the dates with a filter. Is there a way of doing this without formatting the dates before I put them in the context?
Here is the code:
t= This is to notify you that you are booked on the course {{title}} that starts on {{start_date|date:"F j, Y"}} at {{start|time}} and is being held at {{venue}}.
c = {'startdate': datetime.datetime(2010, 12, 1, 9, 0), 'enddate': datetime.datetime(2010, 12, 1, 12, 0), 'has_cpd': False, 'title': 'Course 1', 'closes': None, 'creator': 1L, 'venue': 'Venue for Course 1', 'summary': 'Course 1 Summary', 'tags': '', 'attachment': <FieldFile: None>, 'organiser': 3L, 'id': 1L, 'opens': datetime.datetime(2010, 11, 30, 20, 1, 50, 951490), 'venue_map': None}
t.render(c)
This gives the output:
This is to notify you that you are booked on the course Course 1 that starts on at and is being held at Venue for Course 1.
Why don't the dates show up?
Looks like a simple typo between start_date vs. startdate.
In [18]: t= Template("""This is to notify you that you are booked on the course {{title}} that starts on {{startdate|date:"F j, Y"}} at {{start|time}} and is being held at {{venue}}.""")
In [19]: t.render(c)Out[19]: u'This is to notify you that you are booked on the course Course 1 that starts on December 1, 2010 at and is being held at Venue for Course 1.'