diff --git a/changelog/12622.txt b/changelog/12622.txt new file mode 100644 index 000000000..5c2d56928 --- /dev/null +++ b/changelog/12622.txt @@ -0,0 +1,3 @@ +```release-note:bug +ui: update bar chart when model changes +``` \ No newline at end of file diff --git a/ui/lib/core/addon/components/bar-chart.js b/ui/lib/core/addon/components/bar-chart.js index 230adbeb2..f875fcd76 100644 --- a/ui/lib/core/addon/components/bar-chart.js +++ b/ui/lib/core/addon/components/bar-chart.js @@ -64,10 +64,6 @@ class BarChartComponent extends Component { return this.args.mapLegend; } - get dataset() { - return this.args.dataset || null; - } - hasLegend() { if (!this.args.mapLegend || !Array.isArray(this.args.mapLegend)) { return false; @@ -78,12 +74,12 @@ class BarChartComponent extends Component { } @action - renderBarChart(element) { + renderBarChart(element, data) { let elementId = guidFor(element); - let totalCount = this.dataset.reduce((prevValue, currValue) => prevValue + currValue.total, 0); + let [dataset] = data; + let totalCount = dataset.reduce((prevValue, currValue) => prevValue + currValue.total, 0); let handleClick = this.args.onClick; let labelKey = this.labelKey; - let dataset = this.dataset; let stackFunction = stack().keys(this.mapLegend.map(l => l.key)); // creates an array of data for each map legend key // each array contains coordinates for each data bar @@ -117,6 +113,8 @@ class BarChartComponent extends Component { // creates group for each array of stackedData let groups = chartSvg .selectAll('g') + .remove() + .exit() .data(stackedData) .enter() .append('g') @@ -124,8 +122,8 @@ class BarChartComponent extends Component { .attr('transform', `translate(${CHART_MARGIN.left}, ${CHART_MARGIN.top})`) .style('fill', (d, i) => BAR_COLOR_DEFAULT[i]); - let yAxis = axisLeft(yScale); - yAxis(groups.append('g')); + let yAxis = axisLeft(yScale).tickSize(0); + yAxis(chartSvg.append('g').attr('transform', `translate(${CHART_MARGIN.left}, ${CHART_MARGIN.top})`)); let truncate = selection => selection.text(string => @@ -134,9 +132,10 @@ class BarChartComponent extends Component { chartSvg.selectAll('.tick text').call(truncate); - let rects = groups + groups .selectAll('rect') - .data(d => d) + // iterate through the stacked data and chart respectively + .data(stackedData => stackedData) .enter() .append('rect') .attr('class', 'data-bar') @@ -214,8 +213,8 @@ class BarChartComponent extends Component { select('.chart-tooltip') .style('opacity', 1) .style('max-width', '200px') - .style('left', `${event.pageX - 95}px`) - .style('top', `${event.pageY - 155}px`) + .style('left', `${event.pageX - 400}px`) + .style('top', `${event.pageY - 150}px`) .text( `${Math.round((chartData.total * 100) / totalCount)}% of total client counts: ${chartData.non_entity_tokens} non-entity tokens, ${chartData.distinct_entities} unique entities. @@ -264,8 +263,8 @@ class BarChartComponent extends Component { .on('mousemove', function(chartData) { if (chartData.label.length >= CHAR_LIMIT) { select('.chart-tooltip') - .style('left', `${event.pageX - 100}px`) - .style('top', `${event.pageY - 50}px`) + .style('left', `${event.pageX - 400}px`) + .style('top', `${event.pageY - 100}px`) .text(`${chartData.label}`) .style('max-width', 'fit-content'); } else { @@ -273,21 +272,11 @@ class BarChartComponent extends Component { } }); - // TODO: these render twice, need to only render and append once per line - // creates total count text and coordinates to display to the right of data bars - let totalCountData = []; - rects.each(function(d) { - let textDatum = { - total: d.data.total, - x: parseFloat(select(this).attr('width')) + parseFloat(select(this).attr('x')), - y: parseFloat(select(this).attr('y')) + parseFloat(select(this).attr('height')), - }; - totalCountData.push(textDatum); - }); - - groups + chartSvg + .append('g') + .attr('transform', `translate(${CHART_MARGIN.left}, ${CHART_MARGIN.top + 2})`) .selectAll('text') - .data(totalCountData) + .data(dataset) .enter() .append('text') .text(d => d.total) @@ -295,13 +284,13 @@ class BarChartComponent extends Component { .attr('class', 'total-value') .style('font-size', '.8rem') .attr('text-anchor', 'start') - .attr('y', d => `${d.y}`) - .attr('x', d => `${d.x + 1}%`); + .attr('alignment-baseline', 'mathematical') + .attr('x', chartData => `${xScale(chartData.total)}%`) + .attr('y', chartData => yScale(chartData.label)); - // removes axes lines - groups.selectAll('.domain, .tick line').remove(); + chartSvg.select('.domain').remove(); - // TODO: make more flexible, make legend a div instead of svg? + // TODO: if mapLegend has more than 4 keys, y attrs ('cy' and 'y') will need to be set to a variable. Currently map keys are centered in the legend SVG (50%) // each map key symbol & label takes up 20% of legend SVG width let startingXCoordinate = 100 - this.mapLegend.length * 20; // subtract from 100% to find starting x-coordinate let legendSvg = select('.legend'); diff --git a/ui/lib/core/addon/templates/components/bar-chart.hbs b/ui/lib/core/addon/templates/components/bar-chart.hbs index 0955be26e..584aa02e0 100644 --- a/ui/lib/core/addon/templates/components/bar-chart.hbs +++ b/ui/lib/core/addon/templates/components/bar-chart.hbs @@ -1,4 +1,4 @@ -
+

{{@title}}

@@ -7,18 +7,21 @@ {{/if}}
- {{#if this.dataset}} + {{#if @dataset}} {{yield}} {{/if}}
- {{#unless this.dataset}} + {{#unless @dataset}}
{{else}}
- +
diff --git a/ui/tests/integration/components/bar-chart-test.js b/ui/tests/integration/components/bar-chart-test.js index dda99be3b..519e33cd8 100644 --- a/ui/tests/integration/components/bar-chart-test.js +++ b/ui/tests/integration/components/bar-chart-test.js @@ -1,6 +1,6 @@ import { module, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; -import { render } from '@ember/test-helpers'; +import { findAll, render } from '@ember/test-helpers'; import { hbs } from 'ember-cli-htmlbars'; module('Integration | Component | bar-chart', function(hooks) { @@ -75,7 +75,11 @@ module('Integration | Component | bar-chart', function(hooks) { `); - - assert.dom('.bar-chart-wrapper').exists('it renders'); + assert.dom('[data-test-bar-chart]').exists('bar chart renders'); + assert.dom('[data-test-bar-chart] .chart-title').hasText('Top Namespaces', 'displays title'); + assert + .dom('[data-test-bar-chart] .chart-description') + .hasText('Each namespaces client count includes clients in child namespaces.', 'displays description'); + assert.equal(findAll('.data-bar').length, 8, 'bars render'); }); });