Excel Javascript API - Add chart with Category Axis values - javascript

I am adding\inserting a Line chart to Excel via the following JS call:
var newSheet = ctx.workbook.worksheets.add();
newSheet.activate();
// populate grid
// category (axis)
var cell = newSheet.getCell(0, 0)
...
// values (axis)
cell = newSheet.getCell(0, 1)
...
var range = newSheet.getUsedRange();
newSheet.charts.add("Line", range);
My "range" data looks like this:
2012 10
2013 20
2014 30
2015 40
2016 50
The issue I'm having is each column is treated as an individual series, and 2 lines are rendered in the chart. I only want one line and the Category Axis to contain the years. Does anyone know if this is possible?
Screenshot:

Chris,
The current JavaScript API for Excel that you use to create the chart doesn't give you much control of how Excel should construct the series and axis for the chart. When using the ChartCollection.add() method, you are depending on the "smarts" of the Excel Recommended Charts algorithm, and in this particular case the, answer it comes up with as the first answer is not what you expect.
We have an item in our API backlog to provide more fine-grained control for charts similar to what is available in other Excel APIs. At this time I can't say when this will be available in the API. I encourage you to follow our open specification process to get a heads up, and an opportunity to give feedback on our designs.
As a workaround for your particular case, I would suggest that you try using date values for the first column instead of numbers. You can format the column to show only the year part of the dates:
async function run() {
try {
await Excel.run(async (context) => {
var sheet = context.workbook.worksheets.getActiveWorksheet();
let data = [
["Year", "Measure"],
["2010-12-31", 10],
["2011-12-31", 20],
["2012-12-31", 30],
["2013-12-31", 40],
["2014-12-31", 50],
];
let format = [
["#"],
["yyyy"],
["yyyy"],
["yyyy"],
["yyyy"],
["yyyy"]
];
let categories = sheet.getRange("A1:A6");
categories.numberFormat = format;
var range = sheet.getRange("A1:B6");
range.values = data;
sheet.charts.add(Excel.ChartType.line, range, Excel.ChartSeriesBy.columns);
await context.sync();
});
}
catch (error) {
OfficeHelpers.Utilities.log(error);
}
}
This snippet is written in TypeScript using async/await, but easily be translated to JavaScript.
Jakob

Related

Run javascript in Bubble with loops to compare JSON API data

I'm building an app using Bubble and I have the Toolbox plugin which enables me to use the "Run javascript" step in a Workflow.
From the following NASA API url, I'm planning to read and analyze 20 years of data with values for every month (240 values):
https://power.larc.nasa.gov/api/temporal/monthly/point?parameters=ALLSKY_SFC_SW_DNI&community=RE&longitude=48.0000&latitude=27.0000&format=JSON&start=2001&end=2020
Below is what I am trying to accomplish (with missing pieces of code):
Read in the json data from the API and parse it into an Javascript object.
const response = await fetch(api_url);
const data = await response.json();
Loop through the objects values of interest. Inside the loop calculate the average values for each month. January, February, March, etc.
for(const entry of Object.entries(data.properties.parameters.ALLSKY_SFC_SW_DNI)){}
Store the above 12 average values to the Bubble database.
Loop through the 12 average values to find the two months with highest and lowest value.
Store the above High/low months values to the Bubble database. For example January as lowest average value.
I have successfully learned how to do some basic Javascript operations in Bubble. Reading single values from the API, display them on the page, and store them in the Bubble database. But, I do not know how to read the values in to an JS array, and make the necessary loops and comparisons.
I found this older question but it's about a txt file instead of json in my case.
Get an array of values using fetch api javascript
Appreciate any advice and directions. Thanks
We know the data exists # data.properties.parameter.ALLSKY_SFC_SW_DNI
The year and month are combined so the month must be extracted. Here is one simple way. (note I chose to remove the leading zero for a reason)
/* Given '202001' returns '1', given 202012' returns '12' */
function extractMonth(yearmonth){
let month = yearmonth.substring(yearmonth.length-2);
return month.startsWith('0')? month[month.length-1] : month;
}
If you store the data in a simple Array, the indexes can serve as the Month number. So index 1 will represent January. In order to do that the first element (index 0) will be set to null.
The reasons I took this approach is because the data structure is simple and it makes finding the lowest and highest values quite easy.
Now it is as easy as populating each Array element with the average value inside the loop. Each iteration of the loop updates the average for the month.
for(let [yearmonth, measurement] of Object.entries(data.properties.parameter.ALLSKY_SFC_SW_DNI)){
const month = extractMonth(yearmonth);
if(!tempsByMonth[month]) tempsByMonth[month] = 0;
tempsByMonth[month] = (tempsByMonth[month] + measurement)/2;
}
It looks like this:
const data = {"type":"Feature","geometry":{"type":"Point","coordinates":[48.0,27.0,191.14]},"properties":{"parameter":{"ALLSKY_SFC_SW_DNI":{"200101":5.65,"200102":4.88,"200103":5.28,"200104":5.05,"200105":4.84,"200106":5.21,"200107":5.44,"200108":6.07,"200109":5.72,"200110":5.3,"200111":4.52,"200112":3.03,"200113":5.08,"200201":4.09,"200202":4.89,"200203":4.49,"200204":4.19,"200205":5.17,"200206":6.12,"200207":6.15,"200208":5.64,"200209":5.92,"200210":5.5,"200211":4.57,"200212":3.26,"200213":5.0,"200301":4.55,"200302":3.9,"200303":4.09,"200304":4.29,"200305":4.39,"200306":6.1,"200307":5.29,"200308":6.14,"200309":6.3,"200310":5.28,"200311":3.93,"200312":3.39,"200313":4.81,"200401":3.51,"200402":4.45,"200403":5.37,"200404":4.01,"200405":5.39,"200406":6.4,"200407":6.42,"200408":6.11,"200409":6.21,"200410":5.86,"200411":3.66,"200412":3.89,"200413":5.11,"200501":4.05,"200502":4.03,"200503":4.52,"200504":4.49,"200505":5.14,"200506":5.33,"200507":5.06,"200508":5.85,"200509":6.08,"200510":5.45,"200511":3.89,"200512":4.06,"200513":4.83,"200601":3.65,"200602":3.43,"200603":4.85,"200604":4.0,"200605":4.57,"200606":6.08,"200607":5.01,"200608":5.5,"200609":6.32,"200610":4.81,"200611":4.08,"200612":3.99,"200613":4.7,"200701":4.27,"200702":4.56,"200703":4.39,"200704":3.51,"200705":4.75,"200706":5.4,"200707":5.18,"200708":5.77,"200709":5.88,"200710":5.43,"200711":4.7,"200712":3.76,"200713":4.8,"200801":3.26,"200802":4.12,"200803":4.64,"200804":3.77,"200805":4.03,"200806":4.52,"200807":4.84,"200808":5.3,"200809":4.71,"200810":4.76,"200811":3.97,"200812":5.08,"200813":4.42,"200901":4.08,"200902":3.23,"200903":3.68,"200904":3.66,"200905":4.57,"200906":4.9,"200907":4.23,"200908":4.73,"200909":5.03,"200910":4.57,"200911":4.15,"200912":3.89,"200913":4.23,"201001":4.73,"201002":3.99,"201003":4.51,"201004":3.52,"201005":4.36,"201006":5.12,"201007":4.8,"201008":5.17,"201009":5.28,"201010":5.14,"201011":5.39,"201012":4.65,"201013":4.73,"201101":3.56,"201102":3.47,"201103":4.1,"201104":2.83,"201105":4.52,"201106":4.37,"201107":4.63,"201108":5.31,"201109":5.53,"201110":4.8,"201111":3.71,"201112":4.81,"201113":4.31,"201201":4.19,"201202":3.51,"201203":3.36,"201204":3.34,"201205":3.68,"201206":4.9,"201207":5.33,"201208":5.18,"201209":5.7,"201210":4.84,"201211":4.43,"201212":3.52,"201213":4.33,"201301":3.44,"201302":4.4,"201303":4.03,"201304":3.79,"201305":4.96,"201306":4.94,"201307":4.97,"201308":5.45,"201309":5.39,"201310":5.11,"201311":4.14,"201312":4.38,"201313":4.58,"201401":3.86,"201402":4.49,"201403":4.28,"201404":4.19,"201405":4.78,"201406":5.71,"201407":5.4,"201408":5.37,"201409":5.82,"201410":4.61,"201411":4.21,"201412":4.66,"201413":4.78,"201501":4.24,"201502":3.73,"201503":4.01,"201504":3.79,"201505":4.18,"201506":5.02,"201507":4.7,"201508":5.67,"201509":4.94,"201510":4.17,"201511":3.77,"201512":3.45,"201513":4.31,"201601":4.19,"201602":5.15,"201603":3.77,"201604":4.8,"201605":5.0,"201606":5.73,"201607":4.92,"201608":5.69,"201609":5.49,"201610":5.5,"201611":4.16,"201612":3.46,"201613":4.82,"201701":3.8,"201702":4.54,"201703":3.76,"201704":4.32,"201705":4.89,"201706":7.03,"201707":6.06,"201708":6.37,"201709":6.41,"201710":5.69,"201711":4.48,"201712":4.72,"201713":5.17,"201801":4.6,"201802":4.12,"201803":5.46,"201804":3.69,"201805":5.18,"201806":5.6,"201807":5.71,"201808":5.88,"201809":6.16,"201810":4.48,"201811":3.29,"201812":3.9,"201813":4.85,"201901":2.72,"201902":4.73,"201903":4.92,"201904":4.62,"201905":5.73,"201906":7.4,"201907":5.76,"201908":6.02,"201909":6.66,"201910":5.02,"201911":4.33,"201912":4.65,"201913":5.21,"202001":4.6,"202002":4.85,"202003":5.12,"202004":4.48,"202005":6.14,"202006":6.77,"202007":6.52,"202008":6.37,"202009":6.58,"202010":6.86,"202011":4.21,"202012":3.89,"202013":5.54}}},"header":{"title":"NASA/POWER CERES/MERRA2 Native Resolution Monthly and Annual","api":{"version":"v2.2.12","name":"POWER Monthly and Annual API"},"fill_value":-999.0,"start":"20010101","end":"20201231"},"messages":[],"parameters":{"ALLSKY_SFC_SW_DNI":{"units":"kW-hr/m^2/day","longname":"All Sky Surface Shortwave Downward Direct Normal Irradiance"}},"times":{"data":0.745,"process":0.02}};
const tempsByMonth = [null];
for(let [yearmonth, measurement] of Object.entries(data.properties.parameter.ALLSKY_SFC_SW_DNI)){
const month = extractMonth(yearmonth);
if(!tempsByMonth[month]) tempsByMonth[month] = 0;
tempsByMonth[month] = (tempsByMonth[month] + measurement)/2;
}
function extractMonth(yearmonth){
let month = yearmonth.substring(yearmonth.length-2);
return month.startsWith('0')? month[month.length-1] : month;
}
console.log(tempsByMonth);
Finally, to find the lowest and highest average, you'll use Math.max and Math.min. Note that for the lowest average the null value was filtered out of the list:
console.log('Month with greatest value: ', tempsByMonth.indexOf(Math.max(...tempsByMonth)));
console.log('Month with lowest value: ', tempsByMonth.indexOf(Math.min(...tempsByMonth.filter(v=>v!==null))));
And here is the final result in action:
const data = {"type":"Feature","geometry":{"type":"Point","coordinates":[48.0,27.0,191.14]},"properties":{"parameter":{"ALLSKY_SFC_SW_DNI":{"200101":5.65,"200102":4.88,"200103":5.28,"200104":5.05,"200105":4.84,"200106":5.21,"200107":5.44,"200108":6.07,"200109":5.72,"200110":5.3,"200111":4.52,"200112":3.03,"200113":5.08,"200201":4.09,"200202":4.89,"200203":4.49,"200204":4.19,"200205":5.17,"200206":6.12,"200207":6.15,"200208":5.64,"200209":5.92,"200210":5.5,"200211":4.57,"200212":3.26,"200213":5.0,"200301":4.55,"200302":3.9,"200303":4.09,"200304":4.29,"200305":4.39,"200306":6.1,"200307":5.29,"200308":6.14,"200309":6.3,"200310":5.28,"200311":3.93,"200312":3.39,"200313":4.81,"200401":3.51,"200402":4.45,"200403":5.37,"200404":4.01,"200405":5.39,"200406":6.4,"200407":6.42,"200408":6.11,"200409":6.21,"200410":5.86,"200411":3.66,"200412":3.89,"200413":5.11,"200501":4.05,"200502":4.03,"200503":4.52,"200504":4.49,"200505":5.14,"200506":5.33,"200507":5.06,"200508":5.85,"200509":6.08,"200510":5.45,"200511":3.89,"200512":4.06,"200513":4.83,"200601":3.65,"200602":3.43,"200603":4.85,"200604":4.0,"200605":4.57,"200606":6.08,"200607":5.01,"200608":5.5,"200609":6.32,"200610":4.81,"200611":4.08,"200612":3.99,"200613":4.7,"200701":4.27,"200702":4.56,"200703":4.39,"200704":3.51,"200705":4.75,"200706":5.4,"200707":5.18,"200708":5.77,"200709":5.88,"200710":5.43,"200711":4.7,"200712":3.76,"200713":4.8,"200801":3.26,"200802":4.12,"200803":4.64,"200804":3.77,"200805":4.03,"200806":4.52,"200807":4.84,"200808":5.3,"200809":4.71,"200810":4.76,"200811":3.97,"200812":5.08,"200813":4.42,"200901":4.08,"200902":3.23,"200903":3.68,"200904":3.66,"200905":4.57,"200906":4.9,"200907":4.23,"200908":4.73,"200909":5.03,"200910":4.57,"200911":4.15,"200912":3.89,"200913":4.23,"201001":4.73,"201002":3.99,"201003":4.51,"201004":3.52,"201005":4.36,"201006":5.12,"201007":4.8,"201008":5.17,"201009":5.28,"201010":5.14,"201011":5.39,"201012":4.65,"201013":4.73,"201101":3.56,"201102":3.47,"201103":4.1,"201104":2.83,"201105":4.52,"201106":4.37,"201107":4.63,"201108":5.31,"201109":5.53,"201110":4.8,"201111":3.71,"201112":4.81,"201113":4.31,"201201":4.19,"201202":3.51,"201203":3.36,"201204":3.34,"201205":3.68,"201206":4.9,"201207":5.33,"201208":5.18,"201209":5.7,"201210":4.84,"201211":4.43,"201212":3.52,"201213":4.33,"201301":3.44,"201302":4.4,"201303":4.03,"201304":3.79,"201305":4.96,"201306":4.94,"201307":4.97,"201308":5.45,"201309":5.39,"201310":5.11,"201311":4.14,"201312":4.38,"201313":4.58,"201401":3.86,"201402":4.49,"201403":4.28,"201404":4.19,"201405":4.78,"201406":5.71,"201407":5.4,"201408":5.37,"201409":5.82,"201410":4.61,"201411":4.21,"201412":4.66,"201413":4.78,"201501":4.24,"201502":3.73,"201503":4.01,"201504":3.79,"201505":4.18,"201506":5.02,"201507":4.7,"201508":5.67,"201509":4.94,"201510":4.17,"201511":3.77,"201512":3.45,"201513":4.31,"201601":4.19,"201602":5.15,"201603":3.77,"201604":4.8,"201605":5.0,"201606":5.73,"201607":4.92,"201608":5.69,"201609":5.49,"201610":5.5,"201611":4.16,"201612":3.46,"201613":4.82,"201701":3.8,"201702":4.54,"201703":3.76,"201704":4.32,"201705":4.89,"201706":7.03,"201707":6.06,"201708":6.37,"201709":6.41,"201710":5.69,"201711":4.48,"201712":4.72,"201713":5.17,"201801":4.6,"201802":4.12,"201803":5.46,"201804":3.69,"201805":5.18,"201806":5.6,"201807":5.71,"201808":5.88,"201809":6.16,"201810":4.48,"201811":3.29,"201812":3.9,"201813":4.85,"201901":2.72,"201902":4.73,"201903":4.92,"201904":4.62,"201905":5.73,"201906":7.4,"201907":5.76,"201908":6.02,"201909":6.66,"201910":5.02,"201911":4.33,"201912":4.65,"201913":5.21,"202001":4.6,"202002":4.85,"202003":5.12,"202004":4.48,"202005":6.14,"202006":6.77,"202007":6.52,"202008":6.37,"202009":6.58,"202010":6.86,"202011":4.21,"202012":3.89,"202013":5.54}}},"header":{"title":"NASA/POWER CERES/MERRA2 Native Resolution Monthly and Annual","api":{"version":"v2.2.12","name":"POWER Monthly and Annual API"},"fill_value":-999.0,"start":"20010101","end":"20201231"},"messages":[],"parameters":{"ALLSKY_SFC_SW_DNI":{"units":"kW-hr/m^2/day","longname":"All Sky Surface Shortwave Downward Direct Normal Irradiance"}},"times":{"data":0.745,"process":0.02}};
const tempsByMonth = [null];
for(let [yearmonth, measurement] of Object.entries(data.properties.parameter.ALLSKY_SFC_SW_DNI)){
const month = extractMonth(yearmonth);
if(!tempsByMonth[month]) tempsByMonth[month] = 0;
tempsByMonth[month] = (tempsByMonth[month] + measurement)/2;
}
function extractMonth(yearmonth){
let month = yearmonth.substring(yearmonth.length-2);
return month.startsWith('0')? month[month.length-1] : month;
}
console.log(tempsByMonth);
console.log('Month with greatest value: ', tempsByMonth.indexOf(Math.max(...tempsByMonth)));
console.log('Month with lowest value: ', tempsByMonth.indexOf(Math.min(...tempsByMonth.filter(v=>v!==null))));
Given what you showed me, I just fixed a couple lines and you say that you understand the bubble database end of whatever you're doing so here's how to get your data from the api, but as for the months.. something strange, apparently there are 13 data points per year ;-;
Nonetheless, I'd just have a list of 13 averages instead of 12 due to the data I'm getting
let api_url="https://power.larc.nasa.gov/api/temporal/monthly/point?parameters=ALLSKY_SFC_SW_DNI&community=RE&longitude=48.0000&latitude=27.0000&format=JSON&start=2001&end=2020"
var list={} //will store data points on each month "number"
let response = await fetch(api_url)
let parseData = await response.json()
let interest=parseData.properties.parameter.ALLSKY_SFC_SW_DNI
for(const entry of Object.entries(interest)){
let [key,value]=entry //value is value xD
key=key.substring(4,6) //key becomes month "number"
list[key]=list[key]||{average:0,count:0}
list[key].count++; list[key].average+=value
}
Object.entries(list).forEach(([_,month])=>{
month.average/=month.count
})
console.log(list[12]) //sample of a month data
console.log(list) //full thing
Here's what it looks like

Find and replace based on criteria with Google Apps Scripts Code

I have two Google Sheets housed in the same Spreadsheet object, for reference I'll refer to them as Data and Change-Log.
Data Sheet
ID Country Attribute Value
1 USA X 100
2 RUS X 77
3 MEX Y 32
4 GER Z 111
...
Change-Log Sheet
Country Attribute Value
USA X 84
GER Z 97
Updated Data Sheet
ID Country Attribute Value
1 USA X 84
2 RUS X 77
3 MEX Y 32
4 GER Z 97
...
Currently I am pulling into the Data sheet via an API, which is cleared and updated monthly.
Ideally I would like to write some sort of helper function that can query the Data sheet for entries shared between the two sheets and overwrite values in the Data sheet with the corresponding value from the Change-Log.
In the example above, I would want to query where the Country and Indicator variables are the same, then compare the Value variable and give preference to the Change-Log.Value entry by overwriting this value into the Data sheet where appropriate.
We have a very little information on how your sheets look and what are you trying to do.
You can do something like this:
function test() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const dataSheet = ss.getSheetByName("Data");
const dataRange = dataSheet.getRange(2, 1, dataSheet.getLastRow() - 1, 4);
const dataValues = dataRange.getValues(); // Get at once, faster execution
const changeLogSheet = ss.getSheetByName("Change-Log");
const replacements = changeLogSheet.getRange(2, 1, changeLogSheet.getLastRow() - 1, 3).getValues(); // Faster
const newValues = [];
dataValues.forEach(row => {
const replacementValue = getReplacementValue_(row[1], row[2], replacements);
newValues.push([row[0], row[1], row[2], (replacementValue ? replacementValue : row[3])]);
});
dataRange.setValues(newValues); // Faster
}
function getReplacementValue_(country, attribute, replacements) {
const matchingRows = replacements.filter(row => row[0] == country && row[1] == attribute);
return matchingRows.length > 0 ? matchingRows[0][2] : null;
}
I'm not sure if you want to overwrite all the data each time, or start at some row.
Note 1: Stack Overflow community will be able to help you more if your question is in the form of "here is my goal and code so far, these are the errors and problems". If you ask "how to do something" we won't be able to help you that much.
Note 2: If some answer helps you, upvote/accept it. If not, edit your question to provide more information. In this case it would be good if you can make a copy of your sheet (if data is sensitive then replace with mock data) and share it with anyone on the internet and post a link in your question. Something like "Data" sheet, "Change Log" sheet and "Desired Data" sheet.

C3js - Failed to parse x 'time' to Date object

I am constantly facing a failed to parse time to date object issue. I want to generate a graph which on the left (Y-axis) shows a probability. Say the probability is 0, 0.2, 0.4 etc.. to 1. On the graph, I would like to plot the probability of something at a specific time. The below code is what I am using.
arr1 is the array containing the probabilities.
arr5 is the array containing the timestamp for each of the probability in arr1. The time format is in "12:03:55".
The issue now is if I were to hard code the timestamps into the chart columns, the chart would display perfectly fine. However I am getting the time from a user uploaded .csv file, hence I am concatenating an array which has the timestamps. And this gives me the error of Failed to parse x '12:03:55' to Date object.
I did console.log(dataTime), so I know my concat has been performed correctly in the intended format. This is what the console.log returns.
["times", "12:03:55", "12:03:56", "12:03:56", "12:03:56", "12:03:57", "12:03:57", "12:03:58", "12:03:58", "12:03:59", "12:03:59", "12:04:00"]
This is what the console.log for dataMood returns.
["Mood", 0.3677342, 0.34968433, 0.32662648, 0.3163717, 0.78009516, 0.97079295, 0.97183245, 0.9724318, 0.9689829, 0.7293974, 0.12735543]
Below is the code I am using.
var labelMood = 'Mood';
var dataMood = [labelMood].concat(arr1);
var times = 'times';
var dataTime = [times].concat(arr5);
var chart = c3.generate({
bindto: '#line',
data: {
x: 'times',
xFormat: '%H:%M:%S',
columns: [
dataTime, dataMood
]
},
axis: {
x: {
type: 'timeseries',
tick: {
format: '%H:%M:%S'
}
}
}
});
I really can't see why this isn't working since the format of the concatenated object is the same as how I would've hard coded the times into columns. I'm at my wits end after having Googled for hours. Hopefully someone has came across this issued before and has solved it successfully.

Extract GPS data from EXIF data in JavaScript

I would like to extract the GPS Exif tag from pictures using NodeJS. I got data in this format:
{
"gps": {
"GPSTimeStamp": [2147483647, 76, 41],
"GPSLongitude": [76, 41, 56.622],
"GPSLatitude": [30, 43, 8.754],
"GPSAltitude": 0,
"GPSDateStamp": "14615748802"
}
}
Is there any way to convert it into latitude and longitude?
When I am checking Exif data in Android it shows me proper latitude and longitude, but in NodeJS I am getting data in this format.
Oh, i just come to know the concept og digree,minute,seconds and direction.
i got three values in array as digree , minute and seconds
To parse your input use the following.
function ParseDMS(input) {
var parts = input.split(/[^\d\w]+/);
var lat = ConvertDMSToDD(parts[0], parts[1], parts[2], parts[3]);
var lng = ConvertDMSToDD(parts[4], parts[5], parts[6], parts[7]);
}
The following will convert your DMS to DD
function ConvertDMSToDD(degrees, minutes, seconds, direction) {
var dd = degrees + minutes/60 + seconds/(60*60);
if (direction == "S" || direction == "W") {
dd = dd * -1;
} // Don't do anything for N or E
return dd;
}
So your input would produce the following:
36°57'9" N = 36.9525000
110°4'21" W = -110.0725000
I know this may be already solved but I'd like to offer alternative solution, for the people stumbling upon this question.
It seems like you are using some Node.js library that gives you these raw lat/long data and it's up to you to convert them. There is a new library exifr that does this for you automatically. It's maintained, actively developed library with focus on performance and works in both nodejs and browser.
async function getExif() {
let output = await exifr.parse(imgBuffer)
console.log('gps', output.latitude, output.longitude)
}
You can also try out the library's playground and experiment with images and their output, or check out the repository and docs.

dc.js dimension group ordering

I am trying to render a dc.js barChart where my y-axis is percentage 0-100% and my x-axis are numbers, however I want to order the x-axis by date.
My data looks like this:
date,trend,percent
01/01/2014 13:00,238,53.6
01/01/2014 13:15,239,64.2
01/01/2014 13:30,219,43.1
01/01/2014 13:45,219.2,43.1
01/01/2014 14:00,237.4,50.6
...
I am adding the data to crossfilter
data.forEach(function (d) { d.date = parseDate(d.date); });
var ndx = crossfilter(data);
var trendDimension = ndx.dimension(function (d) { return d.trend; });
var trendGroup = trendDimension.group().reduce(
function (p, v) {
p.time = v.date.getTime();
p.trend = +v.trend;
p.percent = +v.percent;
return p;
},
...
).order(function (p) { return p.time; }); // ??? order by time rather than trend
When I graph the dimension and group, my x-axis is sorted by trend as my x domain looks like:
var minTrend = trendDimension.bottom(1)[0].trend;
var maxTrend = trendDimension.top(1)[0].trend;
...
chart.x(d3.scale.linear().domain([minTrend, maxTrend]);
...
chart.render();
Everything plots, however the bars a sorted in order of trend and I would like them sorted in order of date/time.
Is this possible?
EDIT
I also tried:
chart.ordering(function (d) { return d.value.time; });
but that does not seem to have an effect on the ordering...
Do you want to graph percent versus trend or percent versus time?
Right now your dimension is on trend, so it will not be possible to order it by date. Crossfilter will create a bin for each trend value (which may have many dates), and the way you have written your reduce function, it will simply replace the date entry for the bin, with the last date it sees.
If you want to order by date and then use trend to affect some other aesthetic (color for example), you should use a date dimension, group by some quantization of the date, not do anything with the date in your reduce, and use date scale/xUnits.

Categories