Okay, so I'm Arun Ghatuk and I'm working as a software engineer at Fusion Charts currently. All right. So at Fusion Charts, we had been building charts, gauges and maps, which we will be licensing, which we license to our 26,000 customers and around, say, 700,000 developers worldwide. Many of you over here might know about Fusion Charts as a flash-based charting company. Right. About six years ago, we have completely transitioned to JavaScript-based charting and since then we have been making charts in JavaScript and HTML5 only. So last year what happened, we got a customer requirement to deal with large amount of data. Now, dealing with large amount of data is a pretty general use case as of now, right? Because we all often have to deal with large amount of data at one point or the other. So the question is, can we visualize this amount of data on our browsers? Can we explore them or just can we make some sense out of this large amount of data on our browsers? So, well, yes, the answer is yes, but the options are pretty restricted. Why? Because the rendering capabilities of the browsers are quite limited when we are talking about in context of this large amount of data. So how to tackle these limitations? We can have two approaches. One, we can handle the data. Second, we can handle the browsers. So first I will be speaking on how can you handle the data? So this is a perspective one we will be speaking. So as we know, browsers are not quite comfortable to handle large volume of data. Okay, sorry about that. So browsers are not quite comfortable to handle large amount of data. So can we just think about like, can we scale down the entire data? So what happens if we can somehow scale down the entire large data? We will be reducing the number of elements and specifically speaking, we will be reducing the number of visual elements if we try to plot them out. So if the requirement around the data permits us, then we can actually go for data crunching. So here we will be just giving a brief introduction of what are some of the common data crunching techniques. So I'll give just overview or discuss them right now in detail over here. So go with data aggregation. All of us, many of us are aware of what is data aggregation, right? So in this data aggregation, we cannot change the, we actually visualize or treat the entire data at a go. And the information is not changed. Only what is changed is the level of depth on which we are viewing the data. Say for example, we are trying to daily sales of a e-commerce website. So instead of daily sales, we see the monthly sales or we go on a step farther. So in data aggregation, what we are changing the depth of the details for viewing it. So this is one of the way we can reduce the data. Second is like filtering. We apply different kinds of filters and conditions which will actually reduce the entire large data to smaller subsets. So this is one way we can reduce our data sampling is but picking up a small data set from a large population and getting it represent representative of the entire population. So this also helps and you know, like data analyst and the statisticians love the sampling part and they have been using for long. So all these kinds of optimizations are actually work if the requirement around your data. If the requirement around the data permits us. What does when what does happen when it actually doesn't permit? Let us analyze that part. So we had large data, right? If we if we are talking here about large data, we see couple of patterns. So what I'll just mention two of the patterns, which is the most common ones. This is working. Oh, yeah. So these are the two common patterns, right, which we speak when you are speaking in the context of large data. We see lots of clusters. So if you actually plot or visualize large data, we see clusters, you see gaping and there's also distributions like some data will be tightly distributed. Some there will be loosely distributed. We see a lot of patterns when the pattern when the patterns gets repeated. We see trends and there is also an exceptions part, which either there is exception in the patterns or there is an exception, which we call as outliers in the data. So this was about the importance of large data. But what we are missing is some of the meanings even if you are speaking about large data. We also miss some of the meanings if you actually crunch the data. Let us say if you have a what benefit if we give if you are treating the high volume data is actually large. The chances are pretty high that you are answering much more specific questions. You can ask your data a lot of questions and you get there's a high probability that you get a lot specific answers and you have the freedom to go atomic. So from any level you can drill down to any minor details. So that's how we can go atomic to any level if we actually have the entire large data and that is the thing. So here we will be revisiting all of these in the live visualizations, which will be coming later. But let us speak of the other side of the coin. Let us speak of the other perspective that is this was the how we handle the data. Let us see how can we handle the browsers or what if the browsers can render all of the data high volume of data. So not only that, even if it can handle at what extent it can actually handle that. So we will be seeing a live demo for this. So here we have our data of the weights and the prices of a large set of diamonds. And we want to see how the price of the diamonds is actually varying with its weight. So let's check out this live version. So is it visible? So you see this is quite faded. So visibly we see this is how about approximately there is a million data point over here. It's down with opacity so we can't actually judge much. There's some amounts of plot over there. So this is how a million data if we actually render on the browsers looks like. So before I dive into the technical details like how we can actually render this kind of data high volume data on our browsers. Let us see if the problems whatever we were speaking previously is actually getting solved. So we will be exploring this entire visualization previously demonstrated visualization using one one of the common data exploration. A month or that is your Snyder's man mantra. So what he says is like first you give an overview of the entire visualization. Allow the user to zoom and filter and then you ask the details on demand. So let's see how this visualization helps how it helps us. Right. So first you see there is a lot of patterns over here. So you see there are some spikes and this is the overall pattern. So if you actually see this lot of clustering in comparison to this part of the screen it's so much clustered and clustered over here. So all we need to do is just you know zoom a portion of it and you will get a visual that this is this is the clustered visual what was coming before. On on a detailed look you see there is a white distinct line over there or a portion of there. This has got a special kind of meaning. This is the gap pattern which we are speaking about. So there's a discrete gap inside the visualization. It can have some different interpretations but this is how it helped us in analyzing the clusters and gaps which we are referring. What about the distributions? See some parts are very tightly distributed and we if you go over there there are some very loose distributions. Right. So we also have a distributions. We can see different types of distributions over here. We get a lot of trains. So this is one of the trains and at some part of the see the trains actually broke the width of this is actually smaller than that. So you know the often we also there is some exceptions on the patterns. Right. Apart from that we also have some outliers which is so much far and only you can realize these outliers only when you zoom zoom zoom the stuff. So when you see outlier the natural inclination is what is that point? Why why has it been plotted so far? What is so special meaning about it? And this kind of details on demand attaching a tooltip or any such activities help us. Let us see how filtering here the Snyder's man mantra we had been referring about filtering. So how does actually filtering helps us? So if you see that gap what we were speaking, so this is a discrete kind of gap. Now this is not a quite uniform behavior. If you actually filtered the different data and data sets, so these are actually different data sets. You see for some data sets this is not discretized. So filtering also gives us some inference some hint which were not very obvious in the initial phase. So to summarize this Snyder's man mantra is that what we got is like we got a glimpse how actually visualizing the entire large data is actually giving some more insights more inference out of it. So do you think like this all rendering in even as a large as a million data point was a straightforward rendering, right? Definitely not. And if you're an SVG is never an option for this because like for every plot every circles if you are thinking that if you are thinking that we will be having a DOM element. Now that's not an easy options and that that won't happen because it will be too much hazardous for the browser. We switched to canvas rendering. So we thought about, okay, let's try with canvas and try to render the as large data as a million data point. So what was the experience about when we tried with canvas? Right. So canvas was pretty fast when we tried rendering around 1000, 2000, 5000, 10,000 even 30, 40,000 something really peculiar happened when we tried rendering around 50,000 data. And what happened is we didn't get any script error. We didn't get any kind of error. What we got is like a blank visual. So it was pretty strange for me like what's happening. So if you if you have to understand that then it's just as simple like we all have been working with canvas. So how does canvas works? We need to understand that. So we give set of instructions to canvas say move to this point Roy circle move to that point Roy circle like this set of instructions we give on keep on giving the canvas. And at the end, all while this process, the canvas starts remembering or memorizing it saving in technical terms like saving it in context. All right. So what happens when we actually give this sequential informations for around 50,000 data, the canvas loses its context and it fails to render or visualize anything. So we actually land up getting a so we actually land up getting a blank screen. So that's how over-tasking of canvas led us to the context. So we already saw that we could have rendered 50 more than 50,000 data. But then what? How did we stretch the limit? So this is how we actually thought about like, let's do it like this. It's nothing but a batch processing. So you have an entire data. You divide the entire data into smaller number of chunks and then you visualize it. Say we I have to render around say or 10 10 circles. So instead of giving all the 10 commands, I give it in a set of two. And every time I give the command, I ask the browser to render itself. And this is so what happening is like there is a progressive rendering hovering occurring over here. So you see the this actually progressive rendering gives us two advantages, right? The browser didn't have a blank visual as we were talking previously. And second time the first visual was coming in the least possible time. Now that was pretty important because when you have a large data, you take some time. No matter what you take some time to render for. So you cannot keep your end user to wait until the entire rendering is actually complete. So what do you do? You give him something to see. And when he is seeing that on the next couple of iterations, we ended the entire part of it, right? So having said that, like, you know, this might be entirely not scientific to represent a smaller chunk of data instead of the larger one. But as it's a large data, even that smaller chunk has some patterns or some properties resembling that of the original one or the large data one. So what is all about rendering? So this was the only optimization that was required for rendering part. So was it all about rendering? I guess not. We had been speaking about clusters and when I tried to just render it, it was giving us so much faded view. I can't even see anything. So we needed something which will help us to analyze it better. What was it like? We needed the feature of zooming, right? So how can we actually technically have this zooming feature in inscribed, right? So how can we have it? See, like, this was the cluster, and this was the clusters we were speaking and we were not getting enough details out of it. So what we did is we zoomed in this part and we get something very interesting out of this clusters and gaps out of it. So technically speaking, this was pretty easy, right? Because zooming means only you have to do is to multiply the every coordinates of your plots with some scale factors so that it grows big. So if you say if you have 100 into 100 pixel area, so when you zoomed 10 pixel into 10 pixel window out of it, all you need to do is to multiply the entire coordinates with 10 times. So actually it grows 10 times bigger. So that's all about zooming. It was pretty easy. What about panning? And why do we need to pan actually? So when you say you actually zoomed in a small region and you find something interesting out of this. Now we look whether this kind of pattern, whether this kind of gaps or anything like that occurred in some adjacent place. So our natural inclination is after zooming, we seek for panning across. So how can we actually pan the data or scroll the data? All right. So this represents the currently visible window and after zooming, this is the effective canvas area, the zoomed canvas area, whatever speaking. So there was kind of two approaches for panning. One, we could translate the pre-rendered canvas, what was the previous one we were speaking. So you zoom 10 times, I redraw the entire canvas in a 10 times scaled version. And all I need to do with every mouse move on panning to translate the entire canvas. That is the most smoothest operation we can have while this panning interaction. But this has got a severe drawback. What is that? So you have a large data and you want to drill down to a specific plot. So it's like zooming 100 and 1000 times something like this. So if we actually try to make our effective canvas area 1000 times the size of our device screen height or width, that was a pretty impossible thing and the browser failed to do so. So this approach of increasing the total effective area was not going to work. If we actually plan to render, if we actually plan to pan in this manner. So what was the next option? Can we render the entire plot on demand? So say if you zoomed only a portion and that part of the portion of the canvas gets rendered. So that was pretty good for zooming. But when we actually tried this for panning, what happened for every mouse move, the coordinates gets replaced and for every mouse move, we have to actually re-render the plots. Now that was really expensive and it was a pretty bad UI. So because that was not happening. So what we thought is, let's move to the solution. Like we can apply this nine grid algorithm over here. So what is this nine grid algorithm is pretty interesting. So we never draw the full canvas. What we do, this is a visual area. We first draw this grid. And next what we do, we draw the eight adjacent grids next to eight each one in the background. So the user never sees this nine grids at a time. User concentrates on the center grid. And while he is busy in seeing the center grid, the rest eight adjacent grids actually is already been rendered or pre-rendered. So when the user actually starts panning, say to the right side, what happens is this center of the visible grid changes to this and only this three incremental grids needs to be rendered. So this was actually working pretty fine. So if I have to explain this over here, so what happens is like if you have to, so when I'm at maximum user can start from this leftmost point and scroll up to the rightmost point. So at maximum you have to render at least one grid out over here. So if we do that, then only it solves the purpose. So that's why we chose for this nine grid and we don't need more than nine because at maximum user cannot shift more than one grid at a time. So this was the incremental rendering that actually helps us the problem of mouse lag, of zooming even in the nth level. So that's pretty cool. Now, so let's recollect the Snyder's Man once again. So what we had previously was like we first gave you the overview of the plot, overview of the visualizations, then we actually zoomed and filtered and showed that there are some interesting patterns out here. And now the next thing, once we actually zoom and filter, things becomes interesting for us because these plots were so small in the initial view we didn't even think of having any details out of it. When we actually zoomed and found it, we found that this is an outlier. What is there? So we get interested out of it. We try to fetch some details out of it. So how can we do that? So because this thing at tooltip is not a big deal, but how can we do that in canvas? Because as I already said, we had been using canvas. So how can I actually have a tooltip over canvas or how can you have interactions over a canvas? So because in canvas, we actually doesn't keep track of the points what we draw. Like in SVG what happened, we had a specific, we know where the plots are drawn and we can attach the browser events to that and display the tooltip. So we will be using a cool approach over here. So this is how simulating browser events algorithmically. It will help you to add interactions even on a canvas element. So what you do is like you render a transparent circle over here, transparent SVG circle over here. And on every mouse move we track algorithmically that whether there is any point underlying that Howard point. So if we can track at every mouse move accurate enough and fast enough, what happens on tracking this transparent circle which was drawn in the left corner of the screen immediately transforms back to that point. And now when it actually comes under your cursor, now as this is transparent, the user does not get aware of this. And now you can actually attach any click event, any mouse over event, any kinds of interactions right on this. So it's like hacking the interactions events on a flat canvas element. So this was a cool approach. This was fine, but how to track so fast, so accurate, how can we actually track our mouse with every mouse move we need to search from a million data point that whether there is a point underlying that point being hovered. So for that approach, we chose to we chose to implement this Katy tree implementation. So this is the nearest implementation for algorithm for finding the nearest neighborhood. So what is Katy tree is like a space partitioning data structure where we actually divide the entire portion into k dimensional space. Here we will be speaking only about the two dimension because that's the point of interest over here. We are interested about x and y. This would be our dimensions. So primarily we will be showing that how to build a Katy tree and how can you search effectively using Katy tree, right? So these are the sample points which will be I'll be using to illustrate how to build a Katy tree and also how to search Katy tree in a pretty fast manner. So the algorithm steps for the algorithm is pick a random dimension that can be x, that can be y, pick any dimension, find the median point along that, all right, find the median point split or partition the data into two halves and then keep on recursively doing that with the alternate dimension. Let's see what we are speaking. So first we are taking the dimension y. Okay, this is the y direction. It keeps growing, increasing in the upward direction and x increases in this direction. It's a normal coordinate axis convention. So what happens when we find the median across the, with the y coordinates for this set of points, one seems to be the median, median most point and one comes in the center of the, center of the tree and the entire space gets divided into two, two partitions. On the next step for the next set of three, the logic or the convention is whichever coordinate is less goes on the left leg and whichever is on the greater goes on the right leg. So this part of the, sorry, so this part of the, this part of the tree goes on the right and this downward part goes on the left. So similarly, but this time we had to find the median across the x direction because previously we had chose, we had find the median across the y direction. So similarly, if we recursively iterate the process, we are nothing but partitioning the entire data into alternate grades, right? Each time we are choosing the alternate dimension and finding the median point dividing into two partitions. So this is the corresponding tree, sorry. So this is the corresponding KD tree that we've actually formed with this sample number of data. So how can you, so KD tree is already built, right? So how can you actually find, find what is my nearest neighbor point, right? Say this is my, this is the query point, right? In the green over here. So I actually have to find which is the nearest point, right? So all what I did is in first comparison, I compare whether the y coordinate for this query point lies to the, lies, is a y coordinate for this query point is less than that of one or greater than that of one. If as we see the y coordinate for this is less than, so if we actually for just one comparison, we actually discard this entire part of the tree. Similarly, on the next iterations we find, alright, so we need to find whether the x coordinate for this query point is less than that of the two or greater than that of the two. So in this way we find that it is greater than, so we discard the left part of the tree. And on the next we find that, okay, this is close to nine in comparison to, what is that point three I guess? So a five, yeah? So it's closer to nine. So just you see if you, sorry. So if you actually see that by making just four comparisons you can, we can actually find which is the nearest, nearest point we were speaking. So that's the beauty of KD tree. Now this four has some special meaning. This tree we had been showing with 10 elements, but this tree has four depths which can accommodate around 16 elements. So even if we had a 16 number of elements, just by doing four comparisons we can actually find which is the nearest point. So if you calculate for even a million points, so even if we have a million points just by making four, just by making 20 comparisons, right? Then we can find the nearest neighborhood point. So this was working pretty fine and it was making things pretty good. But what was happening is the building time for KD tree implementation was pretty high. Why? Because for every dimensions, every dimension when we are showing how we will be building the tree, we were showing that we have to find the median. Now we used to find the median using the sorting. First we used to sort and then we used to find the median point. Now every time for every depth formation, if we actually have to sort, now as sorting was the most heaviest operation over here, it was taking time. So we decided to do a little tweak to this KD tree which we named internally modified KD tree. So let us see how this works. So this is nothing but... So in this type of structure, previously every point had two legs, right? Here we have actually seven legs, right? So we have four tree structure. The smaller nodes represent trees and these middle larger ones represent the pivot points. So every level has seven elements, four trees and three pivot points. Now how to divide them? Again, division remains the same. Instead of median, you sort the array and then you find what are the four points which will actually divide the entire space into four partitions. So on the first level of building the tree, we divide the entire space into four partitions. And in the next level, similarly with alternate axis, we divided into another four structures. But as we didn't have so many amount of elements over here, so you can see in the next level of tree, there is only two elements. But as I said, every node should have seven elements. So I haven't actually drawn all the legs over here because that would be so much clumsy. Now that was the building the tree part. So if we recollect what was the tree structure for these same elements previously for KD tree, how is it actually different from this modified KD tree? The first observations will tell us that it has only two depths, whereas the previously KD tree had four depths. So the depth of the tree has increased. And as I said, sorting was the main thing that was taking, that was the main time consuming stuff. So as we here, we have decreased the depth of the tree. We had an advantage of this tree building time. So let's see how we can search this. So that was the building part and modified tree. Actually you can build in a much faster way than that of KD tree. What about searching part? So same example. This is the query point and I'm interested to find which is the nearest neighbor. So in the first comparison, I have to find that whether this point, we take each pivot point and we find whether the coordinate is less than that of that pivot point or greater than. So in this case, even just by making one comparison that this point is actually less than that of the first pivot point we actually discarded this entire tree. So just by making one comparisons, we discarded the entire eight elements and this is the remaining two elements, which on the next iteration we could have just got. So even by making just two comparisons, we can have a point that we, the neighbor point that we were looking for. Okay, so, right, but there is a catch previously in KD tree. There was only two legs here. Luckily we had that by making one comparison. This was falling in this tree and we were not, we are not comparing any other trees, but if the point is lying on the left, right most of right most tree. So if the point of our interest lies in this tree, so we needed to make four comparisons. Okay. Now that's the heaviest thing. While searching KD tree each level, we had to search only once. Here we need to make four search in the worst case. So what, so in a nutshell, modified KD tree although helped us in building the tree in the minimum possible time, rather better than that of the KD tree, but modified KD tree takes a longer time to search, you know, in the worst case scenario.  So it might be seeming that, you know, if we increase the breadth of the tree, if we keep on increasing the breadth of the tree, it will happen, but we needed to take a trade off between building time and searching time. Okay. So these are some of the references I have been using in this presentation. You can learn about the visualization techniques in the Now You See It book written by Stephensview. The data which has been used is available over this link. I have provided a fiddle version of this, of the prototype which we were explaining. And in my data profile, we have updated some of the minimum codes. The major roadblocks, whatever we were speaking, whatever the major challenges, how we get them. So all you need to do is go over there and just try it out. It doesn't have the exact finish of the fusion charts, zoom scattered chart, but it definitely will help you understand the major roadblocks and how we can optimize them. So that's it from me. I'll be looking for some feedbacks and questions. Any questions? Whatever now the whole process of this rendering and then decision tree or I mean whatever that tree identification neighborhood you have done. Can you tell what was the volume of data you tested and how much time you took to render or to do all this process and render in a browser? Okay, so if you try for a million data points, it would have been taking around 3, the first visual will come around 1.5 seconds almost. And in the background, it keeps on rendering the rest part of it. So the user actually, we can engage the user with the first visual around 1 or 1.5 seconds. Okay, now instead of SDG, the canvas concept will be more performance what you are telling, right? So when we go for the zooming, is that like I mean the pixel, when we zoom the clarity will go compared to SVG concept on canvas. So how does that actually, are you limiting the zooming as well like he has to go to that point or how it is like? I didn't get you. If you're zooming in? If you use the canvas thing, when you apply zoom on that, as on one getting zoom, the clarity will go off that object. It's not that much clear. No, no, no, no. It's not pixelated view, right? It's not an image view. We are actually re-rendering the plot. So it's the same canvas element on zooming it. So let me illustrate. So say, you actually try to zoom this part. So what you're doing, this is in the zoom mode. So when you are doing this, you are actually re-rendering the entire screen. It's not the pixelated ones, right? So it's down because of the opacity what it might appear, but it's not the pixelation what you are doing. So that's not the thing. We are again re-rendering, which will keep the image intact. So at that point only you are applying the tooltips. Which points? You know, when the page loads in the starting, so there are a lot of million of data points, right? So that mouseover, when you try at that point of time, maybe because there are a lot of million points, it might not, I mean, we don't know which point we are doing. So you are applying the logic, that algorithm, what you explained. It is from the first level only. Yeah, it is actually from the first level. So the flow is something like this. So that's the part of the data. Then in the background, when the user is actually seeing the entire data, the overview, the first part, the overview of the data, the user is seeing the data, that time in the background we develop the tree. So for that few milliseconds time, when we were actually building the tree, that time if the user actually interacts, he might not get the tooltip because that time we are building the tree. But within next few milliseconds, once the tree building is complete, from that point of time, when the user interacts, the tooltip algorithm just works. Okay. Yeah. Well, it can be anything. So using the standard fusion charts model, I have tested around, it worked pretty good for 3 million data points, but there are some other optimizations which we have to, there are some other features which we have to ship out. So we cannot optimize the entire part of it in fusion charts model, but if you sacrifice some of these features, then it, this entire logic is capable to render around, I have tested it for 8 million data. Okay. So 8 million data, I couldn't create more than 9 million dynamically. So it's pretty good to even render around 8 million data. And you can actually drill down to a single data from this 8 million and have a tooltip. That's the beauty of this entire part. You know. It's so good to actually visualize the large data. That's it. Hello. Yeah. My question was about whether all the charts are drawn in here. Yeah. Whether all the charts are drawn in canvas or only few charts are drawn in canvas where this kind of performance issues are there. All right. So interesting things happening. See with every legend click, I'm just toggling the visibility, right? So here we have thought about having each canvas for each data set so that this becomes easy. So on every data click you just toggle the visibility of that canvas apart from that, like this this grid, whatever you are saying, you can have nine grids, nine canvas for that nine grids. That's pretty fine. Or you can all do in a single move also. Okay. Yeah. My question is about, let's say if there is a pie chart, right? There is a pie chart. There is a pie chart. There is a bar chart. There is a line chart. Okay. So does the same rule of using canvas for those charts apply or is it based on the data points you choose? It's nothing to do with specific charts. You can apply. This is a generic logic. You can apply this in any types of chart or any types of rendering. Okay. So the benchmark, as you said 40,000 data points for all types of charts, right? Yeah. It's actually canvas is like more of like painting an image. The more you paint in a canvas, the greater time it takes. Right. So it's something like this. It's nothing to do with a specific chart type or specific type of visualization. Yeah. So for this visualization, do you use D3 or any of the No, this is we had been using this with fusion chart zoom scatter model. All right. So zoom scatter, we have built this chart. The scattered chart is nothing but a XY chart capable of handling even a million data points. So that's it. All right. So D3 is a open source library. Great library are actually so we can also do you can also try out same things in D3. Right. But the problem is here in D3, it's more like a fundamental. All right. It's more like a drawing library here. You get the back up product directly. So as we have a license product, we cannot actually discuss our entire source code, but you using fusion charts like you get the better product. So when you can concentrate on other things and you get easily done, but everything what I said is pretty generic and it has nothing to do that you can't use it with this and that. You can definitely try out D3 for this. But again, if it will lack the final polish and you have to a lot of do these things. That's what we are doing on our part. All right. Hello. Yeah. My question was about how do you test these charts because you guys here so you guys actually sell these charts, right? So you have to be make sure that when you do changes in the code also the chart works perfectly. So do you do testing? I mean the testing of the charts? I can't follow. Yeah, say for example you released our next version of your product where the charts are some improvements are there. So how do you test these charts? How do you test these charts? Yeah, we have we have our automation systems running. So what testing you're speaking about the future testing? Yeah, all the features. So we have automated testing that runs on our servers. So every day whatever code we commit and everything that gets tested and the next day the QA team gets the report that okay fine these features have been broken or this has been improved. And even for the memory part, like whether the time taken to render because this is a highly performance intensive chart, we actually keep track of the things that whether we have degraded on the performance or not in order to give some extra features. So any testing frameworks you use? So it's like we have our internal testing framework. We use it for image comparison mainly. So we compare the both images in the two releases and that's how do you recommend any open source available? Sorry? Do you recommend any open source similar libraries available for testing? You can try out anything like Karma or you can try out like unit testing any frameworks right? Or even Mocha works good. Okay, thank you. Please meet the speaker outside. We're really running out of time. Okay, thank you.


The projection is quite fair, it's not after a gap of about close to two or three years that the industry is looking forward for a double-digit growth and a good double-digit growth and that should happen because I have my doubts on growth until June, July, until July because IPL will wash away a lot of money from the market and so while IPL as a category will grow, the whole advertising may not grow that much and also the impact of GST in any country in the world when such large taxation changes has happened, it has taken two years to stabilize. So I am assuming that it will take about June, July and after that election of four states and then further general election will push the whole table up. One thing that I want to communicate is that if this industry has to grow it has to come a little ahead and regulate itself better to have a liberal and open environment and help the category itself grow so that more and more manufacturers and service providers come into the fold of advertising that's so unless we don't go to the bottom of the pyramid, this whole advertising industry would not be able to grow from the existing set of advertisers that we have and if we continue to measure everything in terms of CPRP and rating which itself is always questionable and debatable, it would not be a wise idea to think about advertising spend based only on that.


What's up everybody, Jason here for jaskiescasebrakes.com We just sold out another impeccable R&B picker team number three spots So we can sell out the break. This R&B features a lot of teams. I think like 12 Bills, Patriots, Dolphins, Jags, Broncos, Coles, Seahawks, Cardinals, Ravens, Panthers, Bears, Browns So again, you get a piece of these teams via a random number block, serial number break We go by the first number on the left side of the serial number dashes to determine the hits and There's your examples there dice roller here. Here's the customer names Matthew down to Raymond and we got zero one two three four five six seven eight nine roll two and a one three times three times one two three and Matthew down to Raymond that was three And again those teams there is just for the ship sorting purposes. All right, so we've got three three one two three Seven down to nine now. Let me just erase this really quick Just so I can Alphatize this really quick out there, but Matthew you have seven Joe with four Steve Herrick with three Junior you have eight Raymond with zero and in all redemptions Andy Rass You have one of ones if there is any spot one Steve Herrick with five six a around with two and then Raymond with nine So there you go guys So coming up next guys is the break itself. Good luck guys. I've been waiting for another impeccable here. Appreciate it


This paper examines the effect of chromium on segregating iron-based phases in aluminum-silicon alloys. Iron is a common impurity that can be difficult to remove from molten alloy, but adding chromium can reduce its negative effects. Experiments were conducted and analyzed to determine how much chromium was needed to prevent segregated iron-based phases from forming. The results showed that more chromium was required for higher iron contents, and that this increased chromium caused the formation of sludge particles. In conclusion, chromium can be used to reduce segregation of iron-based phases in aluminum-silicon alloys. This article was authored by Dana Balabrkova, Lukas Richterak, and Vladislav Orlovichs.


Hi beautiful, woof, you look so gorgeous today. Oh, you're making me nervous.  It's really a lot, but I'm gonna try and get through it. Today we're watching some people dye their hair pastel. I'm really excited for this because I love a good pastel moment. It's just so pretty and like reminds me of unicorns and unicorns are just so gorgeous. So it's gonna be so cool. And I am just excited to watch what magic happens. Hopefully it's good. Pastel is not very easy to do it in your own hair because you have to have really, really blonde hair to start and you can't have any yellow in it or else it just makes a weird mess on your head. So hopefully they make it nice and white. They color it nice and pastel and it turns out beautifully. But we'll see. Let's check it out. Yeah, I know. Where are you for any adventures now? I'm morphing and doing an adventure. Up first we have a video by Kaylee Boyle and it's called Bleaching My Hair at Home and Dying at Lavender. Why did I do this? I'm opening nose besides you Kaylee. We're gonna try and go for light purple. This is my natural hair color. I have the front pieces bleached and then I have the underlayer bleached.  I got plenty of bleached. This is half full. This is a new one. She's about to have a whole different look and go through a whole process to do this because she's starting off with beautiful level six natural hair. This is great though because bleaching that is gonna be pretty so not simple. It would be simple if she went into professional but since she's doing it herself it might be a little bit difficult but she should get a very nice even lift and a very pure white color when she's done if she does it right. Well, she probably won't do it right so we'll see. Okay, we're ready to start. The first thing I have to do is I have to section out the pieces that are already bleached. Oh, I need to change my shirt first. That transition was epic. First of all, great first two steps. We're gonna change her shirt, make sure she's not gonna stain our entire shirt.  Don't get me wrong, I'm really nervous. Totally feel like I'm gonna mess up my hair. I would hate to see her completely ruin it. However, I'm excited for her change. I know what it feels like when you change your hair it's like the best feeling ever. That's why I do this for a living but I'm excited because even if she messes up a little bit like I think it'll still be good. I mean, it's gonna take a lot to fry her hair off because it's so healthy to start to be fine but I've seen people definitely up their hair even if it's healthy before. My roots have grown in a lot in some places not and there's like brassy. So I'm gonna have to like touch up at like the end so that it doesn't sit on my hair as long and then this is the bleach part in the back. Because the heat of the scalp heats up like the bleach and it processes quicker than everything else. Brad, what are you? This is the Wella powder lightener and then the 30 Devolyte. Why am I saying Devolyte? Devolyte, I'm into that. I have my drag name Devolyte. Devolyte. Devolyte bleach. Give me Devolyte. Pump up Devolyte. You tried to just low it to volume. Because they always have to lower the volume. Emma always thinks the music is so loud. I'm like, lower Devolyte. Oh, we're taking big sections. I'm happy that she's working from the bottom up though I will say that. Laying it this way over would be annoying rather than laying it on top. You know what I'm saying. She's definitely saturating. I don't know if it's enough but she's definitely trying but her sections are a little too big. I'm gonna say, I'm just gonna say it. I'm gonna give you a five out of 10 for sectioning because it's just too big but at least you're sectioning. Look how much she's using. This makes me so happy. I look how blonde it's getting. Wow, this is gonna look really good.  My eyes are watering so bad. I would recommend not bleaching your face. You're actually not supposed to bleach your face. That's probably why your eyes are burning. However, I'm not a doctor. Who knows? You know, Emma? What do you think? Unless you have no feelings and your nerve senses don't work then. I have no feelings? Yeah, that was a bad example. Unless your eyes don't work properly, I think that it's a very common thing.  Oh, Jesus. Yes. As she have any chemical burns. Looks like it's starting to happen. Her face is very red. It's really yellow. Missed a patch. It holds our patch back there. I did my roots after but I think I did it too far from my roots so this part's a little darker. Okay, listen. Her hair does look really healthy still and she can bleach it again. Her roots look nice. It's not too off from the ends. If it was dry, I think it would look a lot more even. So I don't think it's that bad. I think that she definitely could have done better and left it on longer. I don't know how long she left it on for but it seems like there wasn't enough of something going on, not bleaching or not enough time. And I'm probably gonna go with time but she did a lot of things right. Like covered her head with plastic. That way all the heat stays in and everything processes faster and lifts a lot nicer. I'm not mad. Besides the fact that she missed the whole spot in the back of her head. I'm mad about that.  We'll have to see. Sometimes it's hard to tell but I think that's what's gonna happen. So my hair was still kind of yellow after. I went to my boyfriend's house and my boyfriend's sister. She went to like cosmetology school. She helped me out. What you're gonna see in the next few clips is me showing you my hair and then her touching up the spots that I missed because I missed some big patches in the back. And then we did a bleach wash and then we proceeded to put the dye. I don't know if a bleach wash is gonna be enough to get that yellow out of your hair.  I love this makeshift sink moment we got going on here. Okay, we're getting somewhere. Oh wow. Obviously it is not perfect. Going into this, I knew this was not gonna be perfect. I knew there was probably gonna be yellow pieces. I think your hair looks good. Definitely isn't perfect, like you said. It's a little yellow in some spots. Obviously there's a lot of yellow in it. My hair would not take the purple in some spots. There could be many reasons for that but I think later on when this does wash out because it is a semi-permanent, I'm gonna go in with a demi-permanent, maybe a little bit darker purple. I think it turned out really good. Listen, I'm not so mad about this. I just want it to be a little bit better. Next time when this fades out, please bleach your mids and ends again like 20 volume for 25, 30 minutes until it gets nice and pure to almost white with a little bit of yellow in it. Then rinse it out and do the lavender all over again. Just make it a little more even. That will look so good on you.  That way it looks more purposeful and it also covers up those kind of imperfections you have going on. But I think it all around looks really dope. I love the change of color for you. I think it makes you look a lot more like fun and fabulous. I'm glad you love it. You look amazing. Let's check out the next video. Up next we have a video by Ellie Addis and this is called, I Died My Hair Pastel Rainbow. I have like a proper well-up, how to bleach and developer. I've also got this Arctic Fox one and then I've got this like random Jerome Russell BB Blonde. This is like what the UK girls used to dye their hair from home. I like that she has just a smorgasbord of product, just like whatever she had her hands on, perfect. Just keep it nice and confusing, you know? I just bleached my hair and I didn't film. Just remain positive, stay positive guys. I look like Ross Lynch in Austin and Ali right now. I actually hate, hate, hate, hate. It's just not it for me. It's the yellow-orange roots for me. Listen, so what you can do better next time is actually put bleach on your f***ing scalp. It was so dried. It didn't even look like you had bleach on it. There was such a thin coating. It looks more even though, I will say. Obviously you start off with some multicolored moment going on and we're about to get some more multicolored moment going on. This is the developing lotion and this is the colorant. This is the Bleach London White Toner. Okay, so you're supposed to put it on towel-dried hair. What I should be doing is sectioning it and painting it on. It's hot and bothered. I don't want to. This is so draining. So what she's doing is like a pre-toner to her toner. I think she's trying to make her hair nice and bright white before putting the pastel colors on there, which I think is a great idea. Sometimes I like to do that with clients and make their hair completely white before even going in with those pastel colors. That way the pastel colors show up as vibrant and perfect as possible and you're not getting any variation in tone. You're actually getting what you mix in the bowl on their head. So I think it's a great idea. And yes, I agree with you. You should have f***ing sectioned your hair out before putting this sh*** on. The fumes from the- Ooh! Oh, the bleach. Something has happened. Like I can't put my legs. I can't put my body properly and it's good enough for what I want to do. Why does her hair actually look really good? I have five hair dyes here. Time for the pastel. It's Arctic Fox Frozen. Crazy color, peppermint, canary yellow, lavender, bubblegum blue. That's a lot of colors, girl. I've got the purple. Are we sure about this? Okay, so I'm gonna speed up the footage and I'm just gonna dye my hair strips of mint, pink, yellow, blue, and purple. What? Oh, I mean, it looks really cool. This just seems really way too risky for this girl who seems a little bit out of it. It was not good. Oh, no, no, no, no, no, no, no. Didn't take the purple, didn't take- I knew it was gonna look bad. I knew it. I've got the bleach and I'm washing out liquid on my head and I'm gonna leave that for like 10 minutes and then wash it out. This is what happens if you put light colors over yellow hair. They all just start to look muddy and gross. Okay, it didn't turn out as bad as I thought it was going to.  So there's like weird muted yellow there because what I was gonna do so I didn't even expect to keep it for five minutes. I actually might, because it looks like quite purpley with like pops of blue and yellow and stuff. I like it and I'm gonna leave it. Okay, let me just say something. Let me say it. No, let me say it. Let me f*** it. This pastel pink on you is quadruple chef's kiss. Like it looks so good. Your eyes look so amazing. The pink eyeshadow with it, give me more. I also really like the yellow in between the pink but I think it should be a little more purposeful next time. And like maybe just do a few little dashes of yellow up here and down there. Make it a little more pastel yellow rather than so bright. I don't know, I love this color combo. It looks really nice. I just think the placement could be a bit better next time. For what you did, you should be happy with what you have and you are. And you look great. So bravo. This next video is by Abby Hoyt. This is called dye my hair pastel rainbow at home. I am going to be dyeing my hair pastel rainbow by myself. I guess first we should take my hair out of this. Okay, so now that my hair looks like this, I'm gonna brush it. She has a great palette to start with. It's pretty even, even enough and it's light enough to do pastel colors. So at least we have that. Okay, so there's my pink strand. Is that green enough? I can't tell if I wanna add more green. I think the blue and the green are actually looking very similar on my hair. Girl, these are way too light. I feel like they're not even gonna show up at all when you rinse it off. It's gonna be so depressing when you put all that work in and you rinse it off and it's all gone. Yeah, I'm gonna add a little more to each one. Thank you, hair gods. Okay, and that all of a sudden does not look pastel anymore. This also is not looking that pastel anymore. So I might add a little more conditioner to this one too. I think that's a good feeling that you should naturally have right now because I'm terrified. Okay, we're halfway done with my hair. We have done two sections and we only have two more to go. I don't know what's gonna happen here. Might be okay, except the placement seems very half hazard and random, which is never a good sign. So I'm gonna say this is probably, oh, I almost changed my mind. This actually looks kinda good. Is this gonna come out good? This is what it's looking like. I see a lot of green. Not much pink and purple going on and I wanted mostly pink and purple and it literally looks like it's the only thing that showed up is green and that's all blended together and it just turned green. So I'm going to blow dry it and style it. It's giving me coral reef vibes. Bottom of the ocean, coral reef, some greeny tones, a little bit of pink in there. It'll be lighter when it's dry, so it'll be good. Okay, guys, so this is what my hair looks like and literally almost all the pink and purple came out and you can only see green. So I'm gonna go over in the pink and purple spots with more pink and purple and leave it in for like 20 more minutes and then wash it out again and blow dry my hair and come back and make it way more vibrant because I think if it all stayed in, it would be really pretty. So this is the thing. If you went to a salon and got this done, we would section it out. We have a whole map in our heads on how each color will lay and blend with each other and we section it out according to that to kinda map in our head. Here, you kinda just put colors where you saw fit.  That way you know where to put the next color and how it's gonna look when it's all dried. Okay, guys, so this is my hair. I actually think it turned out so cute because it actually is pastel and it is all like really blended but I don't think it looks bad. Like it's literally what I wanted and I think it's just so pretty. I really like it as well. I also think you should like do a little wave in your hair. You know, distract from the imperfections a little bit more but her hair looks really nice and shiny and pretty. I'm into the variations of color and the tones of the color you did are actually gorgeous as well. So, kinda been pressed, kinda shocked it didn't come out horrible, it looks good. It looks really nice. I think this is a really good look for you and next time just map it out and make sure you know what you're doing before you start doing it and also do some like ombre pieces where it goes from like blue to pink on one hair strand. That'll add to that like variation in color all over. It'll look really gorgeous. Those pastel moments were actually really quite nice. I mean definitely none of them were like flawless but they ended up with pretty decent hair. I love a good pastel moment. I just wish they were like a lot more perfect next time. Let's just work on it, let's work on our technique. Make sure you guys subscribe right down below if you're not already. Click the like button and the bell icon if you're not already doing that.  So do it now. Did you do it? You didn't, okay. Well, let's move on. Make sure you follow me everywhere else. Here are all my different social media handles. I'm everywhere. You can literally find me everywhere at all times. I don't sleep. If you guys wanna check out my hair, Caroline, you can do so right down below at xmodohair.com. You can also check us out on Instagram at xmodohair and xmodocolor on Instagram to see what we have going on. If you guys would like to text me, yes, this is a real number. This really goes to my phone and yes, I really use all your messages. I'll be responding to a few of you guys if you text me right now. You'll also be notified every time I post a new video if you text this number. Today's Instagram shout-out goes to Khlo. She says, hi, Brad. I have a few questions for you about my hair. My hair is very thick and curly, but it's also very dry and frizzy. I don't know how to deal with it. So if you have any tips on how to deal with it and make my hair healthier, that'd be great. Well, Khlo, I'm obviously gonna recommend my own products because I know they work and I'm confident in them. I would say use a really moisturizing shampoo and conditioner like Hydra Glow, hydrating shampoo and conditioner by my own brand X-Mondo. That'll really help tame that frizz. We've combined amazing oils in there and defrizing benefits into the product and it'll help rehydrate your hair and make it so much more manageable and healthy. Along with that, I would definitely use a wave-forming foam like Wave Tech, my product. And if your ends need an extra moisture and a little bit more of a kick of moisture, you can totally put some of my Viper oil over the Wave Tech and scrunch it all in.  So I hope that helps, Khlo, and your hair is beautiful. It just needs a little more product and a little more love. That's all for today, guys. Thank you so much for watching.  I'll see you next time. Bye, guys.