Rendering your data to see anomalies

By Gianni Castaldi

In the last blog posts, we discovered ways to search and consume data and build queries to do detections. Today we will learn ways to better understand data by rendering it. This is also a great way to find your timeline when performing hunting activities. By the end of this blog post we will know everything to transform this:

into:

Just by looking at the chart, we can see that something happened on the 13th of July.

First, let us start with the basics. For the sample data I have created a small dataset from a fruit shop and who sells fruit to some of the greatest Microsoft companies. The sample data is available on GitHub and we will use it with the external data operator.

let Orders = externaldata(OrderDate:datetime, Fruit:string, Weight:int, Customer:string, Sell:int)
[@"https://gist.githubusercontent.com/Castaldio86/a12123a7f0e251a324b176d62deef9b8/raw/02da1d82bc548afc0cf45f7732b456f25d4d8080/Sentinel-Render-SampleData"
]
with(format="csv")
;
Orders

To render charts of our data we can use the render command followed by one of the following 6 flavors and 12 kinds.

FlavorKind
areachartstacked(default)
stacked100
unstacked
barchartstacked(default)
stacked100
unstacked
columnchartstacked(default)
stacked100
unstacked
piechartdefault
scatterchartdefault
timechartdefault

The flavor we will use is the area chart. The default kind of the areachart is stacked. We are going to track the count of fruit shipments, per fruit per week.

let Orders = externaldata(OrderDate:datetime, Fruit:string, Weight:int, Customer:string, Sell:int)
[@"https://gist.githubusercontent.com/Castaldio86/a12123a7f0e251a324b176d62deef9b8/raw/02da1d82bc548afc0cf45f7732b456f25d4d8080/Sentinel-Render-SampleData"
]
with(format="csv")
;
Orders
| summarize count() by bin(OrderDate, 7d), Fruit
| render areachart

The second flavor we can use is the stacked100 flavor. This form of rendering shows us the percentage of the total.

This way we can see that between the 10th and the 24th of August we have sold a lot of cherries. The third kind is the unstacked kind.

let Orders = externaldata(OrderDate:datetime, Fruit:string, Weight:int, Customer:string, Sell:int)
[@"https://gist.githubusercontent.com/Castaldio86/a12123a7f0e251a324b176d62deef9b8/raw/02da1d82bc548afc0cf45f7732b456f25d4d8080/Sentinel-Render-SampleData"
]
with(format="csv")
;
Orders
| summarize count() by bin(OrderDate, 7d), Fruit
| render areachart with(kind=unstacked)

The next flavor is the barchart. We will use it to see how many shipments there were per customer per week.

let Orders = externaldata(OrderDate:datetime, Fruit:string, Weight:int, Customer:string, Sell:int)
[@"https://gist.githubusercontent.com/Castaldio86/a12123a7f0e251a324b176d62deef9b8/raw/02da1d82bc548afc0cf45f7732b456f25d4d8080/Sentinel-Render-SampleData"
]
with(format="csv")
;
Orders
| summarize count() by bin(OrderDate, 7d), Customer
| render barchart

The second kind of the barchart is the stacked100.

let Orders = externaldata(OrderDate:datetime, Fruit:string, Weight:int, Customer:string, Sell:int)
[@"https://gist.githubusercontent.com/Castaldio86/a12123a7f0e251a324b176d62deef9b8/raw/02da1d82bc548afc0cf45f7732b456f25d4d8080/Sentinel-Render-SampleData"
]
with(format="csv")
;
Orders
| summarize count() by bin(OrderDate, 7d), Customer
| render barchart with(kind=stacked100)

And the third kind is the unstacked barchart.

let Orders = externaldata(OrderDate:datetime, Fruit:string, Weight:int, Customer:string, Sell:int)
[@"https://gist.githubusercontent.com/Castaldio86/a12123a7f0e251a324b176d62deef9b8/raw/02da1d82bc548afc0cf45f7732b456f25d4d8080/Sentinel-Render-SampleData"
]
with(format="csv")
;
Orders
| summarize count() by bin(OrderDate, 7d), Customer
| render barchart with(kind=unstacked)

After the bar charts, we will continue using the column charts. This is the last flavor we will use with 3 kinds. The first one is the stacked kind. We will use the column chart to see how much weight there was shipped per kind of fruit and per week.

let Orders = externaldata(OrderDate:datetime, Fruit:string, Weight:int, Customer:string, Sell:int)
[@"https://gist.githubusercontent.com/Castaldio86/a12123a7f0e251a324b176d62deef9b8/raw/02da1d82bc548afc0cf45f7732b456f25d4d8080/Sentinel-Render-SampleData"
]
with(format="csv")
;
Orders
| summarize count() by bin(OrderDate, 7d), Weight, Fruit
| render columnchart

The next kind is the stacked100.

let Orders = externaldata(OrderDate:datetime, Fruit:string, Weight:int, Customer:string, Sell:int)
[@"https://gist.githubusercontent.com/Castaldio86/a12123a7f0e251a324b176d62deef9b8/raw/02da1d82bc548afc0cf45f7732b456f25d4d8080/Sentinel-Render-SampleData"
]
with(format="csv")
;
Orders
| summarize count() by bin(OrderDate, 7d), Weight, Fruit
| render columnchart with(kind=stacked100)

And the last kind for the column chart is the unstacked kind.

let Orders = externaldata(OrderDate:datetime, Fruit:string, Weight:int, Customer:string, Sell:int)
[@"https://gist.githubusercontent.com/Castaldio86/a12123a7f0e251a324b176d62deef9b8/raw/02da1d82bc548afc0cf45f7732b456f25d4d8080/Sentinel-Render-SampleData"
]
with(format="csv")
;
Orders
| summarize count() by bin(OrderDate, 7d), Weight, Fruit
| render columnchart with(kind=unstacked)

While all the previous charts have their purposes, the next chart will be a good one to create a total overview of all the data. We will use the piechart flavor. And we will render a pie chart to compare the total weight shipped, per fruit.

let Orders = externaldata(OrderDate:datetime, Fruit:string, Weight:int, Customer:string, Sell:int)
[@"https://gist.githubusercontent.com/Castaldio86/a12123a7f0e251a324b176d62deef9b8/raw/02da1d82bc548afc0cf45f7732b456f25d4d8080/Sentinel-Render-SampleData"
]
with(format="csv")
;
Orders
| summarize count() by Weight, Fruit
| render piechart

While we are reaching the end of this blog post we still have 2 flavors to discover. The first is the scatter chart, this can be used if you want a cleaner look for your charts.

let Orders = externaldata(OrderDate:datetime, Fruit:string, Weight:int, Customer:string, Sell:int)
[@"https://gist.githubusercontent.com/Castaldio86/a12123a7f0e251a324b176d62deef9b8/raw/02da1d82bc548afc0cf45f7732b456f25d4d8080/Sentinel-Render-SampleData"
]
with(format="csv")
;
Orders
| summarize count() by bin(OrderDate, 7d), Weight, Fruit
| render scatterchart

The last flavor is the timechart flavor. This draws a line on the scatter chart which can help to determin trends in the chart.

let Orders = externaldata(OrderDate:datetime, Fruit:string, Weight:int, Customer:string, Sell:int)
[@"https://gist.githubusercontent.com/Castaldio86/a12123a7f0e251a324b176d62deef9b8/raw/02da1d82bc548afc0cf45f7732b456f25d4d8080/Sentinel-Render-SampleData"
]
with(format="csv")
;
Orders
| summarize count() by bin(OrderDate, 7d), Weight, Fruit
| render timechart

I hope this has clarified the render operator and its flavors and kinds.

Thanks for reading and if you have any questions or ideas for a blog post let me know.

Alternative Text

By Gianni Castaldi

MVP | NinjaCat | Researching and Engineering Cyber Security @ KustoWorks

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close