sorting on field with an additional filter in Vega-lite - vega-lite

This might be a somewhat obscure use case.
As you can see below, I have the bar (count) overlaid. I want to sort the bars in the background (where is_overview set to 1), but currently, the filtering is set to all of count, which includes is_overview being set to 0.
I need the sort to be on a filtered field.
I went through the sorting documentation but I cannot figure out a way to support this use case. If you might have ideas, I would really appreciate the help!
Editor code

If you want custom sort behavior, often the best approach is to use a calculate transform, which makes available all of the vega expression syntax, and define a new custom field on which to sort.
In your example, you could do something like this:
"transform": [
{"calculate": "datum.is_overview ? datum.count : null", "as": "order"}
],
and then sort on the order property.
The result looks like this (vega editor):

Related

Can you create a title case function in Vega-Lite?

is there a way to create or add a title case function in Vega-Lite? I've tried using this Vega Documentation and am currently using a "hacky" way to get Title Case with a replace function, but I'd like to use a more sustainable/acceptable way for getting this done. Below is the current code I'm using, which is temporarily okay but not sustainable:
{"calculate": "replace(replace(replace(replace(replace(replace(datum['classification'],'_',' '),'_',' '),'_',' '),'all','All'),' r',' R'),' j',' J')","as": "Classification"}

How to add more XPATH in parsefilter.json in stormcrawler

I am using stormcrawler (v 1.16) & Elasticsearch(v 7.5.0) for extracting data from about 5k news websites. I have added some XPATH patterns for extracting author name in parsefilter.json.
Parsefilter.json is as shown below:
{
"com.digitalpebble.stormcrawler.parse.ParseFilters": [
{
"class": "com.digitalpebble.stormcrawler.parse.filter.XPathFilter",
"name": "XPathFilter",
"params": {
"canonical": "//*[#rel=\"canonical\"]/#href",
"parse.description": [
"//*[#name=\"description\"]/#content",
"//*[#name=\"Description\"]/#content"
],
"parse.title": [
"//TITLE",
"//META[#name=\"title\"]/#content"
],
"parse.keywords": "//META[#name=\"keywords\"]/#content",
"parse.datePublished": "//META[#itemprop=\"datePublished\"]/#content",
"parse.author":[
"//META[#itemprop=\"author\"]/#content",
"//input[#id=\"authorname\"]/#value",
"//META[#name=\"article:author\"]/#content",
"//META[#name=\"author\"]/#content",
"//META[#name=\"byline\"]/#content",
"//META[#name=\"dc.creator\"]/#content",
"//META[#name=\"byl\"]/#content",
"//META[#itemprop=\"authorname\"]/#content",
"//META[#itemprop=\"article:author\"]/#content",
"//META[#itemprop=\"byline\"]/#content",
"//META[#itemprop=\"dc.creator\"]/#content",
"//META[#rel=\"authorname\"]/#content",
"//META[#rel=\"article:author\"]/#content",
"//META[#rel=\"byline\"]/#content",
"//META[#rel=\"dc.creator\"]/#content",
"//META[#rel=\"author\"]/#content",
"//META[#id=\"authorname\"]/#content",
"//META[#id=\"byline\"]/#content",
"//META[#id=\"dc.creator\"]/#content",
"//META[#id=\"author\"]/#content",
"//META[#class=\"authorname\"]/#content",
"//META[#class=\"article:author\"]/#content",
"//META[#class=\"byline\"]/#content",
"//META[#class=\"dc.creator\"]/#content",
"//META[#class=\"author\"]/#content"
]
}
},
I have also made change in crawler-conf.yaml and it is as shown below.
indexer.md.mapping:
- parse.author=author
metadata.persist:
- author
The issue i am facing is : I am getting result only for 1st pattern (i.e. "//META[#itemprop="author"]/#content") of "parse.author". What changes I should do so that all patterns can be taken as input.
What changes I should do so that all patterns can be taken as input.
I read this as "How can I make a single XPath expression that tries all different ways an author can appear in the document?"
Simplest approach: Join the all expressions you already have into a single one with the XPath Union operator |:
input[...]|meta[...]|meta[...]|meta[...]
And since this potentially selects more than one node, we could state explicitly that we only care for the first match:
(input[...]|meta[...]|meta[...]|meta[...])[1]
This probably works but it will be very long and hard to read. XPath can do better.
Your expressions are all pretty repetitive, that's a good starting point to reduce the size of the expression. For example, those two are the same, except for the attribute value:
//meta[#class='author']/#content|//meta[#class='authorname']/#content
We could use or and it would get shorter already:
//meta[#class='author' or #class='authorname']/#content
But when you have 5 or 6 potential values, it still is pretty long. Next try, a predicate for the attribute:
//meta[#class[.='author' or .='authorname']]/#content
A little shorter, as we don't need to type #class all the time. But still pretty long with 5 or 6 potential values. How about a value list and a substring search (I'm using / as a delimiter character):
//meta[contains(
'/author/authorname/',
concat('/', #class, '/')
)]/#content
Now we can easily expand the list of valid values, and even look at different attributes, too:
//meta[contains(
'/author/authorname/article:author/',
concat('/', #class|#id , '/')
)]/#content
And since we're looking for almost the same possible strings across multiple possible attributes, we could use a fixed list of values that all possible attributes are checked against:
//meta[
contains(
'/author/article:author/authorname/dc.creator/byline/byl/',
concat('/', #name|#itemprop|#rel|#id|#class, '/')
)
]/#content
Combined with the first two points, we could end up with this:
(
//meta[
contains(
'/author/article:author/authorname/dc.creator/byline/byl/',
concat('/', #name|#itemprop|#rel|#id|#class, '/')
)
]/#content
|
//input[
#id='authorname'
]/#value
)[1]
Caveat: This only works as expected when a <meta> will never have both e.g. #name and #rel, or if, that they at least both have the same value. Otherwise concat('/', #name|#itemprop|#rel|#id|#class, '/') might pick the wrong one. It's a calculated risk, I think it's not usual for this to happen in HTML. But you need to decide, you're the one who knows your input data.

SSRS - How to indent rows in a table with a given content

In SSRS I want to indent certain rows when they start with e.g. 'aa'. See this example:
What is the best practice in this case? As I don't have a parent-child situation here (to use recursive hierarchy group), do I have an option e.g. via the properties to set something like an IIf to solve this? If yes, could you please provide some information where to set this?
Every info is welcome! I'm new to SSRS.
This is simple to do...
Click on the cell that you want to indent.
In the properties panel, expand the Indent properties and then click the drop-down in the Left Indent property and choose Expression.
Then set the expressions to something like
=SWITCH (
LEFT(Fields!FieldIwantToCheck.Value, 2) = "aa", "10pt",
LEFT(Fields!FieldIwantToCheck.Value, 2) = "bb", "30pt",
True, "0pt"
)
You could do this with an IIF expression but if you need to make it more flexible than 1 or two cases then SWITCH is much easier to read/manage.
All we are doing here is checking the left 2 characteras of the FieldIwantToCheck field and setting an indent value respectivley. If none of the criteria match, the final True, Nothing acts like an ELSE and leaves the property as the default Nothing value.

Filter tablix with two "Like" operations combined by an "Or"

I need to filter on a tablix to return where values in the string contains "BLACK" OR "RED":
Expression: =Fields!DrawOfficeNum.Value Like "*BLACK*" AND Fields!DrawOfficeNum.Value Like "*RED*"
Operator: Like
Value: True
I'm getting no results back and I know there is results. Help will be greatly apreciated!
I would do it like this:
Expression (Text type):
=IIf(InStr(Fields!DrawOfficeNum.Value, "BLACK") > 0 or InStr(Fields!DrawOfficeNum.Value, "RED") > 0
, "Include"
, "Exclude")
Operator: =
Value: Exclude
This gives results:
Only thing to not is that I turned the filter from a Boolean to a Text type - in the past I've always had problems with Boolean filters and the option above works well, as per the screenshot.
Quote, emphasis mine:
I need to filter...where values in the string contains "BLACK" OR "RED":
Quote, emphasis mine:
=Fields!DrawOfficeNum.Value Like "*BLACK*" AND Fields!DrawOfficeNum.Value Like "*RED*"
Change the AND into OR in your expression, then you're good to go.
It seems to work more easily in this way :
In the "Expression" box, put [DrawOfficeNum]
In the Operator box, choose In
In the Value box, put BLACK; RED
It will know that you works on a string type (depends on your field type), and generate a list separated with ;
If i am wrong, can anyone tell me?

SSRS- charts colour coding

I have SSRS solution for SQL 2005 and 2008.
I am showing output in the form of chart- column chart with each column representing different database.
Is there a way to display each column in different color?
Regards
Manjot
You can use a formula to set the colour of each column, but that would work best if you knew what the individual series values ('databases'?) were going to be.
Right-click on your chart and bring up its properties. Now switch to the Data tab and select the first item in the Values list. Click the Edit... button to show the properties for the values (the columns) in your chart. Over on the Appearance tab there's a Series Style... button which takes you to another dialog.
On this new Style Properties dialog, switch to the Fill tab. That's where you set the colour for each of your columns. This can be a formula, so you might make it something like:
=Switch(
Fields!Database.Value = "master", "Blue",
Fields!Database.Value = "msdb", "Red",
"Green")
If you don't know in advance which 'databases' are going to be represented on the chart, this method won't work very well. In that case you might be able to come up with a formula which hashes the database name and comes up with a colour to match. That sounds like an interesting challenge, so add to your question if you need help doing something like that.
Edit
I just got a hash-based-colour-scheme working. It's a pretty nasty piece of code, but it did manage to get me a unique colour for every (string valued) column. Perhaps someone can come up with a better algorithm and post it here. Here's mine:
="#" & left(Hex(Fields!Database.GetHashCode()), 6)
So that's getting the HashCode for the string (a numeric value) and converting it to hex, then taking the leftmost six characters and prepending it with a "#" sign. That gives us a string that looks like a colour value (eg #AB12F0).