Custom alignment in richText cells Exceljs - javascript

"exceljs": "^3.9.0"
I need to create a spreadsheet with cells that have 2 different values that looks like this.
First value needs to be aligned left and second value needs to be aligned right.
My result right now is:
Here is my richText for the cells without "/"
[
{
"font": {
"size": 8,
"name": "Arial"
},
"alignment": {
"vertical": "middle",
"horizontal": "distributed"
},
"text": "392.3 "
},
{
"font": {
"color": {
"argb": "00c90a00"
},
"size": 8,
"name": "Arial"
},
"alignment": {
"vertical": "middle",
"horizontal": "distributed"
},
"text": " -10%"
}
]
And richText for cell with "/"
[
{
"font": {
"size": 8,
"name": "Arial"
},
"alignment": {
"vertical": "middle",
"horizontal": "distributed"
},
"text": "392.3 "
},
{
"font": {
"size": 8,
"name": "Arial"
},
"alignment": {
"vertical": "middle",
"horizontal": "distributed"
},
"text": " / "
},
{
"font": {
"color": {
"argb": "00c90a00"
},
"size": 8,
"name": "Arial"
},
"alignment": {
"vertical": "middle",
"horizontal": "distributed"
},
"text": " -10%"
}
]
Is it possible to do what the first screenshot looks like?

Is it possible to do what the first screenshot looks like?
Yes, that is possible, though you're not able to align text differently in the same cell. It isn't doable with Excel itself and thus definitely not with ExcelJS! There are hundreds of articles asking the question about Excel, but one quote hits the nail on it's head:
Unlike Word, Excel does not have the concept of paragraphs within a cell. Horizontal and vertical alignment apply to a cell as a whole.
Quote taken from the User Hansv MVP from this thread.
You can approach the project via different roads, depending on which suits you the most:
Split the cells with the data. ExcelJS does has the .spliceRows() function, so you could use that (with RichText formatting on respective cells).
You could implement the logic for writing from the get-go, i.e. implement one part of the data in one cell, the next part in the cell after that and so on. Afterwards you're able to color the border to the neighboring data to your background color, thus vanishing it.
etc.
I highly suggest the second approach. In my opinion it should be the easiest solution as you can properly set up a "formatting logic" in the sense of being free with each values you're writing.

Related

Plotting Away and Home Goal Difference for Crystal Palace 2020/21

Using javascript, vega editor and this data: https://github.com/StanWaldron/StanWaldron.github.io/blob/main/final.csv, which I got from SportDataAPI and organised using pandas, I have attempted to make a graph that plots Crystal Palace's home and away goal differences over the course of the 2020/21 season. As you can see though, I can't get a smooth plot.
The issue seems to be that the NaNs in the data are being put in as 0s for home games when they have played away and vice versa. When trying to resolve this by looping through like so:
for c in final['Home_GD']:
if math.isnan(c) == True:
c = 0.0
It doesn't seem to change the data at all. If this worked, I would just be able to simply add it to the previous value and plot it that way, for every game.
In the javascript side I have also used layers, but have struggled to find any way of separating the data completely and then using two different data sources which I can layer on the same graph.
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"title": {
"text": "Home and Away Goal Difference For Crystal Palace 2020/21",
"subtitle":["Exclusively in the Premier League"],
"subtitleFontStyle":"italic",
"subtitleFontSize":10,
"anchor": "start",
"color": "black"},
"data": {
"url":
"https://raw.githubusercontent.com/StanWaldron/StanWaldron.github.io/main/final.csv"
},
"repeat": {"layer": ["Away_GD", "Home_GD"]},
"height": 300,
"width": 300,
"spec": {
"mark": {
"type":"line",
"strokeWidth":2},
"encoding": {
"x": {
"field": "Date",
"type": "temporal",
"title":null,
"axis":{
"grid": false
}},
"y": {
"field": {"repeat": "layer"},
"type": "quantitative",
"title": null},
"color": {
"datum": {"repeat": "layer"},
"scale": {"range": ["blue", "red"]},
"legend": {
"orient":"top-left",
"fillColor":"white"}}
}
}
}
I would probably do this by filtering each value individually within a layer; here's an example (open in editor):
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {
"url": "https://raw.githubusercontent.com/StanWaldron/StanWaldron.github.io/main/final.csv"
},
"transform": [{"fold": ["Home_GD", "Away_GD"], "as": ["key", "Goals"]}],
"encoding": {
"x": {"field": "Date", "type": "temporal"},
"y": {"field": "Goals", "type": "quantitative"},
"color": {"field": "key", "type": "nominal"}
},
"layer": [
{
"transform": [{"filter": "datum.key == 'Home_GD' && datum.Home_GD != ''"}],
"mark": "line"
},
{
"transform": [{"filter": "datum.key == 'Away_GD' && datum.Away_GD != ''"}],
"mark": "line"
}
]
}

How do you create a partial pie chart on vega-lite for single data point?

I am using vega-lite to create a pie chart (on Airtable). I have a single data point, which is a target set by me, and the percentage complete for that target. For example, as below:
{
"Target": "Get 10 customers",
"Percentage complete": "60"
}
I would like to make a pie chart that is 60% complete, and the rest empty. Similar to the interactive single arc pie chart displayed https://vega.github.io/vega-lite/docs/arc.html.
My code currently looks like this
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"title": "Customer Acquired",
"width": "container",
"height": "container",
"data": {
"values": [
{
"Target": "Get 10 customers",
"Percentage complete": "60"
}
]},
"mark": {
"type": "arc",
"tooltip": true
},
"encoding": {
"theta": {
"field": "Percentage complete",
"type": "quantitative"
}
}
}
And my pie chart currently just looks like this:
I realise I could force the pie chart to appear the way I want it by manually setting the theta2 property like so
"mark": {
"type": "arc",
"tooltip": true,
"theta2": 3.5
}
However I don't know what the "Percentage complete" field will be and this value may change often, so I would rather not have to do it manually. Is this at all possible with vega-lite?
The domain for the theta encoding will automatically be set to the minimum and maximum of your input data. To show the correct portion of the chart, you need to set the domain to [0, 100]:
"encoding": {
"theta": {
"field": "Percentage complete",
"type": "quantitative",
"scale": {"domain": [0, 100]}
}
}
You can view the resulting chart in the vega editor:

Append to tooltips in Amcharts

i have made some charts for spreader beams in Amcharts (Worpress) and want to change the toolstips,
reverse the order of the 2 values.
append "tonnes" and "metres" after the respective values.
I can swap the order they appear in the code to change the order they appear, but how to append in plain text after the digit values so it shows "8 tonnes: 2 metres"?
Code for these is below in the tooltipText:
"series": [{
"type": "LineSeries",
"name": "30° Sling To Vertical Angle",
"xAxis": "id-1",
"yAxis": "id-2",
"baseAxis": "id-1",
"dataFields": {
"valueY": "value1",
"categoryX": "category"
},
"fillOpacity": 0.5,
"strokeWidth": 2,
"sequencedInterpolation": true,
"sequencedInterpolationDelay": 100,
"tooltipText": "{name}\n{categoryX}: {valueY}"
}, {
"type": "LineSeries",
"name": "45° Sling To Vertical Angle",
"xAxis": "id-1",
"yAxis": "id-2",
"dataFields": {
"valueY": "value2",
"categoryX": "category"
},
"simplifiedProcessing": true,
"calculatePercent": true,
"fillOpacity": 0.5,
"strokeWidth": 2,
"sequencedInterpolation": true,
"sequencedInterpolationDelay": 100,
"tooltipText": "{name}\n{categoryX}: {valueY}"
url is https://applifting.ga/modular-spreader-beams/sectionlift-6/
Thanks
Just swapped the order of the tool tip values and appended in plain text the denominator.

Multiple series data on HighCharts column

I'm using HighCharts on a project, and I'm having trouble formatting the data in the way I'd like. I currently have something that works, but it doesn't feel quite right.
What I have is a column chart with everything in one series. I'd rather have each data point be in it's own series & properly labeled in the legend & tooltips. Below are samples of the relevant bits to format the data.
I'm not sure what I'm doing wrong, the changes I've made feel like they should work given their docs & this demo. Also, Do I need the categories if multiple series works?
Working:
"series": [
{
"data": [
{
"y": 92,
"name": "Apples: 92ms for 83,481,430 requests",
"color": "#91cb73"
},
{
"y": 761,
"name": "Bananas: 761ms for 58,050,877 requests",
"color": "#ab7053"
},
{
"y": 774,
"name": "Kiwis: 774ms for 362,294 requests",
"color": "#44719c"
}
]
}
]
Demo: http://jsfiddle.net/b65kp/
Not working:
"series": [
{
"name": "Apples",
"data": {
"y": 92,
"name": "92ms for 83,481,430 requests",
"color": "#91cb73"
}
},
{
"name": "Bananas",
"data": {
"y": 761,
"name": "761ms for 58,050,877 requests",
"color": "#ab7053"
}
},
{
"name": "Kiwis",
"data": {
"y": 774,
"name": "774ms for 362,294 requests",
"color": "#44719c"
}
}
]
Demo: http://jsfiddle.net/u74Qw/1/
The problem is that "data" expects an array, and you are giving it an object. Wrap each object in an array. For example:
"data": [{
"y": 92,
"name": "92ms for 83,481,430 requests",
"color": "#91cb73"
}]
Here is your full fix, but it might not give the result you expect, personally I like your first attempt better
FWIW, alternate approach to setting this up:
http://jsfiddle.net/jlbriggs/zbW4D/
Things to consider:
1) using a legend instead of just directly labeling each bar makes the user do a lot of looking back and forth to see which is which (doing both just adds extra clutter to distract the user)
2) rotating labels always adds more work for the user
3) multiple colors for the bars is not necessary when each bar is labeled appropriately, and again just adds distraction
A horizontal bar chart with no legend and single color for data solves these problems.

Highcharts separate categories

Check this fiddle to get an idea of what I am talking about
This is my xAxis configuration:
"xAxis": {
"categories": ["Category ONE", "Category TWO"],
"allowDecimals": false,
"title": {
"text": " ",
"align": "middle",
"style": {
"color": "steelblue"
}
},
"labels": {
"y": 12,
"style": {
"color": "steelblue"
}
}
},
I need category one and category two to be separated by a few pixels (50,100, whatever amount I want) but cannot find the solution for this issue. I know there is a way to do it for series but there is no equivalent for when you only want to separate the categories.
Thanks in advance
plotOptions have some options which can control series. Padding is possible to get by changing value of groupPadding:
"plotOptions": {
"column": {
"groupPadding": 0.1
}
}
And see it live: http://jsfiddle.net/JEGGf/42/

Categories