D3 - Icicle Partitioning minmum cell size? - d3.js

I am new to d3js, and I really like the library.
I intended to use Sunbrust and Icicle visualizations to show dependency trees of applications, in which the user can see the dependency hierarchy (who depends on who, etc...).
However, the icicle and sunburst visualizations always produce some "cells" that are too small, requiring the user to hover the cell to get the label.
Is it possible to tell d3 to create these cells with a minium height?
So that each cell can display the label inside and not require users to hover these cells?
See here:
See Observable code here:https://observablehq.com/#d3/icicle
See fiddle, here:
https://jsfiddle.net/68q0thc5/
<script src="https://d3js.org/d3.v7.min.js"></script>
<div id="chart"></div>
<script>
chart = Icicle(getData(), {
value: d => d.size, // size of each node (file); null for internal nodes (folders)
label: d => d.name, // display name for each cell
title: (d, n) => `${n.ancestors().reverse().map(d => d.data.name).join(".")}\n${n.value.toLocaleString("en")}`, // hover text
link: (d, n) => n.children
? `https://github.com/prefuse/Flare/tree/master/flare/src/${n.ancestors().reverse().map(d => d.data.name).join("/")}`
: `https://github.com/prefuse/Flare/blob/master/flare/src/${n.ancestors().reverse().map(d => d.data.name).join("/")}.as`,
width: 1152,
height: 2400
})
document.getElementById("chart").appendChild(chart)
// Copyright 2021 Observable, Inc.
// Released under the ISC license.
// https://observablehq.com/#d3/icicle
function Icicle(data, { // data is either tabular (array of objects) or hierarchy (nested objects)
path, // as an alternative to id and parentId, returns an array identifier, imputing internal nodes
id = Array.isArray(data) ? d => d.id : null, // if tabular data, given a d in data, returns a unique identifier (string)
parentId = Array.isArray(data) ? d => d.parentId : null, // if tabular data, given a node d, returns its parent’s identifier
children, // if hierarchical data, given a d in data, returns its children
format = ",", // format specifier string or function for values
value, // given a node d, returns a quantitative value (for area encoding; null for count)
sort = (a, b) => d3.descending(a.value, b.value), // how to sort nodes prior to layout
label, // given a node d, returns the name to display on the rectangle
title, // given a node d, returns its hover text
link, // given a node d, its link (if any)
linkTarget = "_blank", // the target attribute for links (if any)
width = 640, // outer width, in pixels
height = 400, // outer height, in pixels
margin = 0, // shorthand for margins
marginTop = margin, // top margin, in pixels
marginRight = margin, // right margin, in pixels
marginBottom = margin, // bottom margin, in pixels
marginLeft = margin, // left margin, in pixels
padding = 1, // cell padding, in pixels
round = false, // whether to round to exact pixels
color = d3.interpolateRainbow, // color scheme, if any
fill = "#ccc", // fill for node rects (if no color encoding)
fillOpacity = 0.6, // fill opacity for node rects
} = {}) {
// If id and parentId options are specified, or the path option, use d3.stratify
// to convert tabular data to a hierarchy; otherwise we assume that the data is
// specified as an object {children} with nested objects (a.k.a. the “flare.json”
// format), and use d3.hierarchy.
const root = path != null ? d3.stratify().path(path)(data)
: id != null || parentId != null ? d3.stratify().id(id).parentId(parentId)(data)
: d3.hierarchy(data, children);
// Compute the values of internal nodes by aggregating from the leaves.
value == null ? root.count() : root.sum(d => Math.max(0, value(d)));
// Compute formats.
if (typeof format !== "function") format = d3.format(format);
// Sort the leaves (typically by descending value for a pleasing layout).
if (sort != null) root.sort(sort);
// Compute the partition layout. Note that x and y are swapped!
d3.partition()
.size([height - marginTop - marginBottom, width - marginLeft - marginRight])
.padding(padding)
.round(round)
(root);
// Construct a color scale.
if (color != null) {
color = d3.scaleSequential([0, root.children.length - 1], color).unknown(fill);
root.children.forEach((child, i) => child.index = i);
}
const svg = d3.create("svg")
.attr("viewBox", [-marginLeft, -marginTop, width, height])
.attr("width", width)
.attr("height", height)
.attr("style", "max-width: 100%; height: auto; height: intrinsic;")
.attr("font-family", "sans-serif")
.attr("font-size", 10);
const cell = svg
.selectAll("a")
.data(root.descendants())
.join("a")
.attr("xlink:href", link == null ? null : d => link(d.data, d))
.attr("target", link == null ? null : linkTarget)
.attr("transform", d => `translate(${d.y0},${d.x0})`);
cell.append("rect")
.attr("width", d => d.y1 - d.y0)
.attr("height", d => d.x1 - d.x0)
.attr("fill", color ? d => color(d.ancestors().reverse()[1]?.index) : fill)
.attr("fill-opacity", fillOpacity);
const text = cell.filter(d => d.x1 - d.x0 > 10).append("text")
.attr("x", 4)
.attr("y", d => Math.min(9, (d.x1 - d.x0) / 2))
.attr("dy", "0.32em");
if (label != null) text.append("tspan")
.text(d => label(d.data, d));
text.append("tspan")
.attr("fill-opacity", 0.7)
.attr("dx", label == null ? null : 3)
.text(d => format(d.value));
if (title != null) cell.append("title")
.text(d => title(d.data, d));
return svg.node();
}
function getData() {
return { "name": "flare", "children": [{ "name": "analytics", "children": [{ "name": "cluster", "children": [{ "name": "AgglomerativeCluster", "size": 3938 }, { "name": "CommunityStructure", "size": 3812 }, { "name": "HierarchicalCluster", "size": 6714 }, { "name": "MergeEdge", "size": 743 }] }, { "name": "graph", "children": [{ "name": "BetweennessCentrality", "size": 3534 }, { "name": "LinkDistance", "size": 5731 }, { "name": "MaxFlowMinCut", "size": 7840 }, { "name": "ShortestPaths", "size": 5914 }, { "name": "SpanningTree", "size": 3416 }] }, { "name": "optimization", "children": [{ "name": "AspectRatioBanker", "size": 7074 }] }] }, { "name": "animate", "children": [{ "name": "Easing", "size": 17010 }, { "name": "FunctionSequence", "size": 5842 }, { "name": "interpolate", "children": [{ "name": "ArrayInterpolator", "size": 1983 }, { "name": "ColorInterpolator", "size": 2047 }, { "name": "DateInterpolator", "size": 1375 }, { "name": "Interpolator", "size": 8746 }, { "name": "MatrixInterpolator", "size": 2202 }, { "name": "NumberInterpolator", "size": 1382 }, { "name": "ObjectInterpolator", "size": 1629 }, { "name": "PointInterpolator", "size": 1675 }, { "name": "RectangleInterpolator", "size": 2042 }] }, { "name": "ISchedulable", "size": 1041 }, { "name": "Parallel", "size": 5176 }, { "name": "Pause", "size": 449 }, { "name": "Scheduler", "size": 5593 }, { "name": "Sequence", "size": 5534 }, { "name": "Transition", "size": 9201 }, { "name": "Transitioner", "size": 19975 }, { "name": "TransitionEvent", "size": 1116 }, { "name": "Tween", "size": 6006 }] }, { "name": "data", "children": [{ "name": "converters", "children": [{ "name": "Converters", "size": 721 }, { "name": "DelimitedTextConverter", "size": 4294 }, { "name": "GraphMLConverter", "size": 9800 }, { "name": "IDataConverter", "size": 1314 }, { "name": "JSONConverter", "size": 2220 }] }, { "name": "DataField", "size": 1759 }, { "name": "DataSchema", "size": 2165 }, { "name": "DataSet", "size": 586 }, { "name": "DataSource", "size": 3331 }, { "name": "DataTable", "size": 772 }, { "name": "DataUtil", "size": 3322 }] }, { "name": "display", "children": [{ "name": "DirtySprite", "size": 8833 }, { "name": "LineSprite", "size": 1732 }, { "name": "RectSprite", "size": 3623 }, { "name": "TextSprite", "size": 10066 }] }, { "name": "flex", "children": [{ "name": "FlareVis", "size": 4116 }] }, { "name": "physics", "children": [{ "name": "DragForce", "size": 1082 }, { "name": "GravityForce", "size": 1336 }, { "name": "IForce", "size": 319 }, { "name": "NBodyForce", "size": 10498 }, { "name": "Particle", "size": 2822 }, { "name": "Simulation", "size": 9983 }, { "name": "Spring", "size": 2213 }, { "name": "SpringForce", "size": 1681 }] }, { "name": "query", "children": [{ "name": "AggregateExpression", "size": 1616 }, { "name": "And", "size": 1027 }, { "name": "Arithmetic", "size": 3891 }, { "name": "Average", "size": 891 }, { "name": "BinaryExpression", "size": 2893 }, { "name": "Comparison", "size": 5103 }, { "name": "CompositeExpression", "size": 3677 }, { "name": "Count", "size": 781 }, { "name": "DateUtil", "size": 4141 }, { "name": "Distinct", "size": 933 }, { "name": "Expression", "size": 5130 }, { "name": "ExpressionIterator", "size": 3617 }, { "name": "Fn", "size": 3240 }, { "name": "If", "size": 2732 }, { "name": "IsA", "size": 2039 }, { "name": "Literal", "size": 1214 }, { "name": "Match", "size": 3748 }, { "name": "Maximum", "size": 843 }, { "name": "methods", "children": [{ "name": "add", "size": 593 }, { "name": "and", "size": 330 }, { "name": "average", "size": 287 }, { "name": "count", "size": 277 }, { "name": "distinct", "size": 292 }, { "name": "div", "size": 595 }, { "name": "eq", "size": 594 }, { "name": "fn", "size": 460 }, { "name": "gt", "size": 603 }, { "name": "gte", "size": 625 }, { "name": "iff", "size": 748 }, { "name": "isa", "size": 461 }, { "name": "lt", "size": 597 }, { "name": "lte", "size": 619 }, { "name": "max", "size": 283 }, { "name": "min", "size": 283 }, { "name": "mod", "size": 591 }, { "name": "mul", "size": 603 }, { "name": "neq", "size": 599 }, { "name": "not", "size": 386 }, { "name": "or", "size": 323 }, { "name": "orderby", "size": 307 }, { "name": "range", "size": 772 }, { "name": "select", "size": 296 }, { "name": "stddev", "size": 363 }, { "name": "sub", "size": 600 }, { "name": "sum", "size": 280 }, { "name": "update", "size": 307 }, { "name": "variance", "size": 335 }, { "name": "where", "size": 299 }, { "name": "xor", "size": 354 }, { "name": "_", "size": 264 }] }, { "name": "Minimum", "size": 843 }, { "name": "Not", "size": 1554 }, { "name": "Or", "size": 970 }, { "name": "Query", "size": 13896 }, { "name": "Range", "size": 1594 }, { "name": "StringUtil", "size": 4130 }, { "name": "Sum", "size": 791 }, { "name": "Variable", "size": 1124 }, { "name": "Variance", "size": 1876 }, { "name": "Xor", "size": 1101 }] }, { "name": "scale", "children": [{ "name": "IScaleMap", "size": 2105 }, { "name": "LinearScale", "size": 1316 }, { "name": "LogScale", "size": 3151 }, { "name": "OrdinalScale", "size": 3770 }, { "name": "QuantileScale", "size": 2435 }, { "name": "QuantitativeScale", "size": 4839 }, { "name": "RootScale", "size": 1756 }, { "name": "Scale", "size": 4268 }, { "name": "ScaleType", "size": 1821 }, { "name": "TimeScale", "size": 5833 }] }, { "name": "util", "children": [{ "name": "Arrays", "size": 8258 }, { "name": "Colors", "size": 10001 }, { "name": "Dates", "size": 8217 }, { "name": "Displays", "size": 12555 }, { "name": "Filter", "size": 2324 }, { "name": "Geometry", "size": 10993 }, { "name": "heap", "children": [{ "name": "FibonacciHeap", "size": 9354 }, { "name": "HeapNode", "size": 1233 }] }, { "name": "IEvaluable", "size": 335 }, { "name": "IPredicate", "size": 383 }, { "name": "IValueProxy", "size": 874 }, { "name": "math", "children": [{ "name": "DenseMatrix", "size": 3165 }, { "name": "IMatrix", "size": 2815 }, { "name": "SparseMatrix", "size": 3366 }] }, { "name": "Maths", "size": 17705 }, { "name": "Orientation", "size": 1486 }, { "name": "palette", "children": [{ "name": "ColorPalette", "size": 6367 }, { "name": "Palette", "size": 1229 }, { "name": "ShapePalette", "size": 2059 }, { "name": "SizePalette", "size": 2291 }] }, { "name": "Property", "size": 5559 }, { "name": "Shapes", "size": 19118 }, { "name": "Sort", "size": 6887 }, { "name": "Stats", "size": 6557 }, { "name": "Strings", "size": 22026 }] }, { "name": "vis", "children": [{ "name": "axis", "children": [{ "name": "Axes", "size": 1302 }, { "name": "Axis", "size": 24593 }, { "name": "AxisGridLine", "size": 652 }, { "name": "AxisLabel", "size": 636 }, { "name": "CartesianAxes", "size": 6703 }] }, { "name": "controls", "children": [{ "name": "AnchorControl", "size": 2138 }, { "name": "ClickControl", "size": 3824 }, { "name": "Control", "size": 1353 }, { "name": "ControlList", "size": 4665 }, { "name": "DragControl", "size": 2649 }, { "name": "ExpandControl", "size": 2832 }, { "name": "HoverControl", "size": 4896 }, { "name": "IControl", "size": 763 }, { "name": "PanZoomControl", "size": 5222 }, { "name": "SelectionControl", "size": 7862 }, { "name": "TooltipControl", "size": 8435 }] }, { "name": "data", "children": [{ "name": "Data", "size": 20544 }, { "name": "DataList", "size": 19788 }, { "name": "DataSprite", "size": 10349 }, { "name": "EdgeSprite", "size": 3301 }, { "name": "NodeSprite", "size": 19382 }, { "name": "render", "children": [{ "name": "ArrowType", "size": 698 }, { "name": "EdgeRenderer", "size": 5569 }, { "name": "IRenderer", "size": 353 }, { "name": "ShapeRenderer", "size": 2247 }] }, { "name": "ScaleBinding", "size": 11275 }, { "name": "Tree", "size": 7147 }, { "name": "TreeBuilder", "size": 9930 }] }, { "name": "events", "children": [{ "name": "DataEvent", "size": 2313 }, { "name": "SelectionEvent", "size": 1880 }, { "name": "TooltipEvent", "size": 1701 }, { "name": "VisualizationEvent", "size": 1117 }] }, { "name": "legend", "children": [{ "name": "Legend", "size": 20859 }, { "name": "LegendItem", "size": 4614 }, { "name": "LegendRange", "size": 10530 }] }, { "name": "operator", "children": [{ "name": "distortion", "children": [{ "name": "BifocalDistortion", "size": 4461 }, { "name": "Distortion", "size": 6314 }, { "name": "FisheyeDistortion", "size": 3444 }] }, { "name": "encoder", "children": [{ "name": "ColorEncoder", "size": 3179 }, { "name": "Encoder", "size": 4060 }, { "name": "PropertyEncoder", "size": 4138 }, { "name": "ShapeEncoder", "size": 1690 }, { "name": "SizeEncoder", "size": 1830 }] }, { "name": "filter", "children": [{ "name": "FisheyeTreeFilter", "size": 5219 }, { "name": "GraphDistanceFilter", "size": 3165 }, { "name": "VisibilityFilter", "size": 3509 }] }, { "name": "IOperator", "size": 1286 }, { "name": "label", "children": [{ "name": "Labeler", "size": 9956 }, { "name": "RadialLabeler", "size": 3899 }, { "name": "StackedAreaLabeler", "size": 3202 }] }, { "name": "layout", "children": [{ "name": "AxisLayout", "size": 6725 }, { "name": "BundledEdgeRouter", "size": 3727 }, { "name": "CircleLayout", "size": 9317 }, { "name": "CirclePackingLayout", "size": 12003 }, { "name": "DendrogramLayout", "size": 4853 }, { "name": "ForceDirectedLayout", "size": 8411 }, { "name": "IcicleTreeLayout", "size": 4864 }, { "name": "IndentedTreeLayout", "size": 3174 }, { "name": "Layout", "size": 7881 }, { "name": "NodeLinkTreeLayout", "size": 12870 }, { "name": "PieLayout", "size": 2728 }, { "name": "RadialTreeLayout", "size": 12348 }, { "name": "RandomLayout", "size": 870 }, { "name": "StackedAreaLayout", "size": 9121 }, { "name": "TreeMapLayout", "size": 9191 }] }, { "name": "Operator", "size": 2490 }, { "name": "OperatorList", "size": 5248 }, { "name": "OperatorSequence", "size": 4190 }, { "name": "OperatorSwitch", "size": 2581 }, { "name": "SortOperator", "size": 2023 }] }, { "name": "Visualization", "size": 16540 }] }] }
}
</script>

Related

Issue- Not displaying the custom visualization in vega

I am trying to make a custom word cloud visualization from the existing index using vega in kibana dashboard.
It is showing error as "Cannot read properties of undefined (reading 'datum')".
I have used type-formula in "transform property" to create custom visualization word cloud rather than these any types are there?
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"title": "A Wordcloud",
"width": 900,
"height": 500,
"padding": 100,
"autosize": "none",
"background": "pink",
"data": [
{
"name": "table",
"url": {
"index": "nupur2",
"body": {
"aggs": {
"2": {
"terms": {"field": "hashtags","order":{"_count": "asc"}, "size": 100},
"aggs": {
"_count": {
"avg": {"field": "vaderSentiment"}
}
}
}
}
}
},
"format": {"property": "aggregations.2.buckets"},
"transform": [
{
"type": "formula",
"as": "angle",
"expr": "datum.size >= 4 ? 0 : [-45,-30, -15, 0, 15, 30, 45][floor(random() * 7)]"
}
]
}
],
"scales": [
{
"name": "color",
"type": "ordinal",
"domain": {"data": "table", "field": "hashtags"},
"range": ["green", "orange", "red"]
}
],
"marks": [
{
"type": "group",
"from": {"data": "table"},
"encode": {
"enter": {
"text": {"field": "hashtags"},
"align": {"value": "center"},
"baseline": {"value": "alphabetic"},
"fill": {"scale": "color", "field": "hashtags"}
},
"update": {
"fillOpacity": {"value": 1}
},
"hover": {
"fillOpacity": {"value": 0.5}
}
},
"transform": [
{
"type": "wordcloud",
"size": [800, 400],
"text": {"field": "hashtags"},
"rotate": {"field": "datum.angle"},
"font": "Helvetica Neue, Arial",
"fontSize": {"field": "datum.size"},
"fontWeight": {"field": "datum.weight"},
"fontSizeRange": [12, 56],
"padding": 2
}
]
}
]
}
This is the image which I got output : https://i.stack.imgur.com/nbb8f.png

Draw tree Layout chart in vega

I want to have a tree chart of my data using vega in kibana 7.9.0, but I don't know how to write the query for that.
the below code is an example of tree chart from github website. I want such layout for my own index which I have it in kibanan.
Help me how to do that.
tree chart example
Sample tree chart code:
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "An example of Cartesian layouts for a node-link diagram of hierarchical data.",
"width": 1000,
"height": 1600,
"padding": 5,
"signals": [
{
"name": "labels", "value": true,
"bind": {"input": "checkbox"}
},
{
"name": "layout", "value": "tidy",
"bind": {"input": "radio", "options": ["tidy", "cluster"]}
},
{
"name": "links", "value": "diagonal",
"bind": {
"input": "select",
"options": ["line", "curve", "diagonal", "orthogonal"]
}
},
{
"name": "separation", "value": false,
"bind": {"input": "checkbox"}
}
],
"data": [
{
"name": "tree",
"url": "data/flare.json",
"transform": [
{
"type": "stratify",
"key": "id",
"parentKey": "parent"
},
{
"type": "tree",
"method": {"signal": "layout"},
"size": [{"signal": "height"}, {"signal": "width - 100"}],
"separation": {"signal": "separation"},
"as": ["y", "x", "depth", "children"]
}
]
},
{
"name": "links",
"source": "tree",
"transform": [
{ "type": "treelinks" },
{
"type": "linkpath",
"orient": "horizontal",
"shape": {"signal": "links"}
}
]
}
],
"scales": [
{
"name": "color",
"type": "linear",
"range": {"scheme": "magma"},
"domain": {"data": "tree", "field": "depth"},
"zero": true
}
],
"marks": [
{
"type": "path",
"from": {"data": "links"},
"encode": {
"update": {
"path": {"field": "path"},
"stroke": {"value": "#ccc"}
}
}
},
{
"type": "symbol",
"from": {"data": "tree"},
"encode": {
"enter": {
"size": {"value": 100},
"stroke": {"value": "#fff"}
},
"update": {
"x": {"field": "x"},
"y": {"field": "y"},
"fill": {"scale": "color", "field": "depth"}
}
}
},
{
"type": "text",
"from": {"data": "tree"},
"encode": {
"enter": {
"text": {"field": "name"},
"fontSize": {"value": 9},
"baseline": {"value": "middle"}
},
"update": {
"x": {"field": "x"},
"y": {"field": "y"},
"dx": {"signal": "datum.children ? -7 : 7"},
"align": {"signal": "datum.children ? 'right' : 'left'"},
"opacity": {"signal": "labels ? 1 : 0"}
}
}
}
]
}
I recommend going and learning the Kibana Vega interaction, Vega spec and elasticsearch search api. This is too broad of a question, you are basically asking someone to do the work for you which is easily deducible from the the documentation.
https://www.elastic.co/guide/en/kibana/current/vega.html
https://vega.github.io/vega/docs/
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html

ElasticSearch-Kibana-Vega Plugin

I'm very new with elastic search and kibana . I'm using vega plugin in kibana visualization.
But not able to create Bar Chart using elastic search aggs.
I'm getting proper result when I'm using kibana dev tools.
I'am attaching the following details with the sample code after run this I'm getting a blank page
Visualization Section:
{
"$schema": "https://vega.github.io/schema/vega/v3.0.json",
"autosize": "fit",
"padding": 6,
"data": [
{
"name": "traffic-revenue",
"url": {
"index": "brnl_tms_plaza",
"body": {
"size": "0",
"aggs": {
"group_by_vehicle_subcat": {
"terms": {
"field": "VehicleSubCatCode.keyword"
}
}
}
},
"format": {
"property": "aggregations.group_by_vehicle_subcat.buckets"
}
}
}
],
"scales": [
{
"name": "xscale",
"type": "band",
"domain": {
"data": "traffic-revenue",
"field": "key"
},
"range": "width",
"padding": 0.05,
"round": true
},
{
"name": "yscale",
"domain": {
"data": "traffic-revenue",
"field": "doc_count"
},
"nice": true,
"range": "height"
}
],
"axes": [
{
"orient": "bottom",
"scale": "xscale"
},
{"orient": "left", "scale": "yscale"}
],
"marks": [
{
"type": "rect",
"from": {
"data": "traffic-revenue"
},
"encode": {
"enter": {
"x": {
"scale": "xscale",
"field": "key",
"axis": {"title": "Vehicle category"}
},
"width": {
"scale": "xscale",
"band": 1
},
"y": {
"scale": "yscale",
"field": "doc_count",
"axis": {"title": "Vehicle Rate Count"}
},
"y2": {
"scale": "yscale",
"value": 0
}
},
"update": {
"fill": {"value": "steelblue"}
},
"hover": {"fill": {"value": "red"}}
}
}
]
}
Data Set
{
"took": 7,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 48,
"max_score": 0,
"hits": []
},
"aggregations": {
"group_by_vehicle_subcat": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "LMV",
"doc_count": 35
},
{
"key": "BUS",
"doc_count": 3
},
{
"key": "LCV",
"doc_count": 3
},
{
"key": "MAV-5",
"doc_count": 3
},
{
"key": "MAV-4 with trailer",
"doc_count": 2
},
{
"key": "MAV-3 without trailer",
"doc_count": 1
},
{
"key": "MINI-BUS",
"doc_count": 1
}
]
}
}
}
I would recommend debugging your vega code using static data to make sure it is defined properly.
I'm not sure why, but I was able to get your visualization to draw when I set the autosize property to none and set the height and width explicitly.
Here is a vega specification based off of the one you provided which should run in the online vega editor.
{
"$schema": "https://vega.github.io/schema/vega/v3.0.json",
"autosize": "none",
"width": 400,
"height": 500,
"padding": 20,
"data": [
{
"name": "traffic-revenue",
"values": [
{"key": "a", "doc_count": 5},
{"key": "b", "doc_count": 22},
{"key": "c", "doc_count": 1},
{"key": "d", "doc_count": 7},
{"key": "e", "doc_count": 12},
{"key": "f", "doc_count": 2}
]
}
],
"scales": [
{
"name": "xscale",
"type": "band",
"domain": {
"data": "traffic-revenue",
"field": "key"
},
"range": "width",
"padding": 0.05,
"round": true
},
{
"name": "yscale",
"domain": {
"data": "traffic-revenue",
"field": "doc_count"
},
"nice": true,
"range": "height"
}
],
"axes": [
{
"orient": "bottom",
"scale": "xscale"
},
{"orient": "left", "scale": "yscale"}
],
"marks": [
{
"type": "rect",
"from": {
"data": "traffic-revenue"
},
"encode": {
"enter": {
"x": {
"scale": "xscale",
"field": "key",
"axis": {"title": "Vehicle category"}
},
"width": {
"scale": "xscale",
"band": 1
},
"y": {
"scale": "yscale",
"field": "doc_count",
"axis": {"title": "Vehicle Rate Count"}
},
"y2": {
"scale": "yscale",
"value": 0
}
},
"update": {
"fill": {"value": "steelblue"}
},
"hover": {"fill": {"value": "red"}}
}
}
]
}
You may already know this since you have the format tag on your elasticsearch data, but if your visualization is working with statically defined data, and not when you pull data from an elasticsearch query, try looking at the data source directly using the vega debuggging functions described here https://vega.github.io/vega/docs/api/debugging/.
Running the following in the browser console should let you look at the data in the format vega is receiving it. VEGA_DEBUG.view.data("")

elasticsearch nested aggregation inside a reverse nested aggregation

Elasticsearch version: 2.3.1
JVM version: 1.8.0_66 / 25.66-b17
OS version: Mac OS X 10.11.4
I am having trouble getting the correct values to show up in a 4 level deep aggregation scenario where the first two levels are nested, the third is reverse_nested, and the fourth is nested again.
Here is my index mapping:
curl -XDELETE localhost:9200/orders-d
curl -XPUT localhost:9200/orders-d
curl -XPUT localhost:9200/orders-d/order-d/_mapping -d '{
"order-d": {
"properties": {
"id": {
"type": "string"
},
"orderNumber": {
"type": "string"
},
"groupId": {
"type": "string"
},
"groupOrderNumber": {
"type": "string"
},
"dateCreated": {
"type": "date"
},
"dateUpdated": {
"type": "date"
},
"location": {
"type": "object"
},
"orderSubmitter": {
"type": "object"
},
"distributor": {
"type": "object"
},
"salesRep": {
"type": "object"
},
"status": {
"type": "string"
},
"total": {
"type": "double"
},
"isTTOrder": {
"type": "boolean"
},
"lineItems": {
"type": "nested",
"include_in_parent": true,
"properties": {
"product": {
"type": "object"
},
"category": {
"type": "object"
},
"subCategory": {
"type": "object"
},
"quantity": {
"type": "double"
},
"unitPrice": {
"type": "double"
},
"totalPrice": {
"type": "double"
},
"pricedByUnitPrice": {
"type": "double"
}
}
}
}
}
}'
Here are the documents:
curl -XPUT localhost:9200/orders-d/order-d/0 -d '{
"id": "571652632a19085c008b4577",
"orderNumber": "1617590686",
"groupId": "571652632a19085c008b4578",
"groupOrderNumber": "3485944627",
"dateCreated": "2016-04-19",
"dateUpdated": null,
"location": {
"id": "54e53853505eb66b008b4569",
"name": "Andrews Diner"
},
"orderSubmitter": {
"id": "54e53853505eb66b008b4567",
"name": "Kostantino Plaitis"
},
"distributor": {
"id": "55c3879459ad0c63008b4569",
"name": "Performance Foodservice Metro NY"
},
"salesRep": null,
"status": "pending",
"total": 5410.21,
"isTTOrder": true,
"lineItems": [{
"product": {
"id": "55bfb445c440b26a008b4571",
"name": "Sabrett Sauerkraut 12 x 2 lb bags"
},
"category": {
"id": "53df845b3b8e77710e7b23ec",
"name": "Groceries & Dry Food"
},
"subCategory": {
"id": "53e1e8723b8e77a52b8b4586",
"name": "Other Sauces Dipping\/Condiments\/Savoury Toppings\/Savoury Spreads\/Marinades (Perishable)"
},
"quantity": 1,
"unitPrice": 25.24,
"totalPrice": 25.24,
"pricedByUnitPrice": 0
}, {
"product": {
"id": "55bc219238c0376e008b4570",
"name": "Franks Red Hot Cayenne Pepper Sauce 4 x 1 gallon"
},
"category": {
"id": "53df845b3b8e77710e7b23ec",
"name": "Groceries & Dry Food"
},
"subCategory": {
"id": "53e1e8723b8e77a52b8b4606",
"name": "Other Sauces Dipping\/Condiments\/Savoury Toppings\/Savoury Spreads\/Marinades (Shelf Stable)"
},
"quantity": 1,
"unitPrice": 45.06,
"totalPrice": 45.06,
"pricedByUnitPrice": 0
}, {
"product": {
"id": "56d76c41bd821fda008b459a",
"name": "Cereal, Classic Variety Pack, Kelloggs 1\/60 ct."
},
"category": {
"id": "53df845b3b8e77710e7b23ec",
"name": "Groceries & Dry Food"
},
"subCategory": {
"id": "53e1e8723b8e77a52b8b462d",
"name": "Grains\/Cereal - Ready to Eat - (Shelf Stable)"
},
"quantity": 1,
"unitPrice": 56.03,
"totalPrice": 56.03,
"pricedByUnitPrice": 0
}]
}'
curl -XPUT localhost:9200/orders-d/order-d/0 -d '{
"id": "571652632a19085c008b4576",
"orderNumber": "2041063294",
"groupId": "571652632a19085c008b4578",
"groupOrderNumber": "3485944627",
"dateCreated": "2016-04-19",
"dateUpdated": null,
"location": {
"id": "54e53853505eb66b008b4569",
"name": "Andrews Diner"
},
"orderSubmitter": {
"id": "54e53853505eb66b008b4567",
"name": "Kostantino Plaitis"
},
"distributor": {
"id": "55cdeece0a41216c008b4583",
"name": "Driscoll Foods"
},
"salesRep": null,
"status": "pending",
"total": 7575.27,
"isTTOrder": true,
"lineItems": [{
"product": {
"id": "55ad05e08d28c36b008b456c",
"name": "Pepper 3000 pcs"
},
"category": {
"id": "53df845b3b8e77710e7b23ec",
"name": "Groceries & Dry Food"
},
"subCategory": {
"id": "53e1e8723b8e77a52b8b4582",
"name": "Herbs\/Spices (Shelf Stable)"
},
"quantity": 3,
"unitPrice": 8.95,
"totalPrice": 26.85,
"pricedByUnitPrice": 0
}, {
"product": {
"id": "55b3a12f6b415c68008b4568",
"name": "Venice Maid Deluxe Corned Beef Hash 6 x 6 lb 10 oz"
},
"category": {
"id": "53df846c3b8e77710e7b23f7",
"name": "Meat"
},
"subCategory": {
"id": "54d8c56a279871b9078b4581",
"name": "Beef - Prepared\/Processed"
},
"quantity": 1,
"unitPrice": 59.75,
"totalPrice": 59.75,
"pricedByUnitPrice": 0
}, {
"product": {
"id": "55b145798c26dc69008b4568",
"name": "Aladdin Bakers Sesame Bread Sticks 150 x 2 packs"
},
"category": {
"id": "53df845b3b8e77710e7b23ec",
"name": "Groceries & Dry Food"
},
"subCategory": {
"id": "53e1e8723b8e77a52b8b45b0",
"name": "Dried Breads (Shelf Stable)"
},
"quantity": 8,
"unitPrice": 15.5,
"totalPrice": 124,
"pricedByUnitPrice": 0
}, {
"product": {
"id": "55ad074a8d28c36f008b456d",
"name": "Smuckers Breakfast Syrup 100 cups"
},
"category": {
"id": "53df845b3b8e77710e7b23ec",
"name": "Groceries & Dry Food"
},
"subCategory": {
"id": "53e1e8723b8e77a52b8b457d",
"name": "Syrup\/Treacle\/Molasses (Shelf Stable)"
},
"quantity": 10,
"unitPrice": 8.95,
"totalPrice": 89.5,
"pricedByUnitPrice": 0
}]
}'
Here is my query:
curl -XPOST localhost:9200/orders-d/_search -d '{
"from": 0,
"size": 0,
"aggregations": {
"totalLineItems": {
"aggs": {
"totalLineItems": {
"terms": {
"field": "lineItems.category.id",
"size": 0
},
"aggs": {
"totalLineItems": {
"terms": {
"field": "lineItems.product.id",
"size": 0
},
"aggs": {
"totalLineItems": {
"aggs": {
"totalLineItems": {
"terms": {
"field": "distributor.id",
"size": 0
},
"aggs": {
"totalLineItems": {
"aggs": {
"totalLineItems": {
"sum": {
"field": "lineItems.totalPrice"
}
}
},
"nested": {
"path": "lineItems"
}
}
}
}
},
"reverse_nested": {}
}
}
}
}
}
},
"nested": {
"path": "lineItems"
}
}
},
"query": {
"bool": {
"must": [{
"range": {
"dateCreated": {
"format": "yyyy-MM-dd",
"gte": "2016-01-01",
"lte": "2016-04-30"
}
}
}]
}
}
}'
...and here are my results:
{
"took": 8,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.0,
"hits": []
},
"aggregations": {
"totalLineItems": {
"doc_count": 4,
"totalLineItems": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [{
"key": "53df845b3b8e77710e7b23ec",
"doc_count": 3,
"totalLineItems": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [{
"key": "55ad05e08d28c36b008b456c",
"doc_count": 1,
"totalLineItems": {
"doc_count": 1,
"totalLineItems": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [{
"key": "55cdeece0a41216c008b4583",
"doc_count": 1,
"totalLineItems": {
"doc_count": 4,
"totalLineItems": {
"value": 300.1
}
}
}]
}
}
}, {
"key": "55ad074a8d28c36f008b456d",
"doc_count": 1,
"totalLineItems": {
"doc_count": 1,
"totalLineItems": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [{
"key": "55cdeece0a41216c008b4583",
"doc_count": 1,
"totalLineItems": {
"doc_count": 4,
"totalLineItems": {
"value": 300.1
}
}
}]
}
}
}, {
"key": "55b145798c26dc69008b4568",
"doc_count": 1,
"totalLineItems": {
"doc_count": 1,
"totalLineItems": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [{
"key": "55cdeece0a41216c008b4583",
"doc_count": 1,
"totalLineItems": {
"doc_count": 4,
"totalLineItems": {
"value": 300.1
}
}
}]
}
}
}]
}
}, {
"key": "53df846c3b8e77710e7b23f7",
"doc_count": 1,
"totalLineItems": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [{
"key": "55b3a12f6b415c68008b4568",
"doc_count": 1,
"totalLineItems": {
"doc_count": 1,
"totalLineItems": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [{
"key": "55cdeece0a41216c008b4583",
"doc_count": 1,
"totalLineItems": {
"doc_count": 4,
"totalLineItems": {
"value": 300.1
}
}
}]
}
}
}]
}
}]
}
}
}
}
As you can see from the results, all the aggregated values for each drilldown of totalLineItems have the same exact value. This is obviously incorrect.
Did I do something wrong, is it a bug, or is nesting inside a reverse nesting unsupported?

Getting full documents using ElasticSearch aggregations

I've got an index like:
[
{
"Name": "Alex",
"LastName": "Ich",
"Department": 2
},
{
"Name": "Charlie",
"LastName": "Sheen",
"Department": 3
},
{
"Name": "Peter",
"LastName": "Petrelli",
"Department": 5
},
{
"Name": "Alan",
"LastName": "Harper",
"Department": 6
},
{
"Name": "Ann",
"LastName": "Bottle",
"Department": 3
},
]
And I want to get the results with distinct Department, I don't care about order, just 1 result per Department. I tried with aggregations but I could only manage to get the different Deppartments with the doc_count associated. They query I tried is something like:
{
"aggs": {
"deppartments": {
"terms": {
"field": "Department"
}
}
},"size": 0
}
It returns:
"buckets": [
{
"key": 2,
"doc_count": 1
},
{
"key": 3,
"doc_count": 2
},
{
"key": 5,
"doc_count": 1
},
{
"key": 6,
"doc_count": 1
},
]
When I want something like:
[
{
"Name": "Alex",
"LastName": "Ich",
"Department": 2
},
{
"Name": "Charlie",
"LastName": "Sheen",
"Department": 3
},
{
"Name": "Peter",
"LastName": "Petrelli",
"Department": 5
},
{
"Name": "Alan",
"LastName": "Harper",
"Department": 6
}
]
You can use Top hits aggregation for this
{
"aggs": {
"departments": {
"terms": {
"field": "Department",
"size": 10
},
"aggs": {
"search_results": {
"top_hits": {
"size": 10 <--- you can change the size to 1 if you want
}
}
}
}
},
"size": 0
}
Does this help?

Resources