From fd700e965773bc32c254b03a8d2acd19bd087d08 Mon Sep 17 00:00:00 2001 From: Luca Mattiazzi Date: Thu, 9 Apr 2020 10:35:01 +0200 Subject: [PATCH 01/43] created gauge chart - squashed --- packages/core/demo/data/gauge.ts | 13 + packages/core/demo/data/index.ts | 18 ++ packages/core/src/charts/gauge.ts | 46 +++ packages/core/src/charts/index.ts | 1 + packages/core/src/components/graphs/gauge.ts | 288 +++++++++++++++++++ packages/core/src/components/index.ts | 1 + packages/core/src/configuration.ts | 40 ++- packages/core/src/interfaces/charts.ts | 16 ++ packages/core/src/interfaces/events.ts | 10 + packages/core/src/tools.ts | 21 ++ packages/core/stories/all.stories.ts | 7 +- 11 files changed, 454 insertions(+), 7 deletions(-) create mode 100644 packages/core/demo/data/gauge.ts create mode 100644 packages/core/src/charts/gauge.ts create mode 100644 packages/core/src/components/graphs/gauge.ts diff --git a/packages/core/demo/data/gauge.ts b/packages/core/demo/data/gauge.ts new file mode 100644 index 0000000000..ea461f6ed0 --- /dev/null +++ b/packages/core/demo/data/gauge.ts @@ -0,0 +1,13 @@ +export const gaugeData = [ + { group: "Dataset", key: "current", value: 85 }, + { group: "Dataset", key: "old", value: 100 }, + { group: "Dataset", key: "total", value: 200 } +]; + +export const gaugeOptions = { + title: "Gauge", + resizable: true, + gauge: { + arcRatio: 0.5 + } +}; diff --git a/packages/core/demo/data/index.ts b/packages/core/demo/data/index.ts index 099476b985..ced412f9f3 100644 --- a/packages/core/demo/data/index.ts +++ b/packages/core/demo/data/index.ts @@ -3,6 +3,7 @@ import * as bubbleDemos from "./bubble"; import * as donutDemos from "./donut"; import * as lineDemos from "./line"; import * as pieDemos from "./pie"; +import * as gaugeDemos from "./gauge"; import * as scatterDemos from "./scatter"; import * as stepDemos from "./step"; import * as timeSeriesAxisDemos from "./time-series-axis"; @@ -12,6 +13,7 @@ export * from "./bubble"; export * from "./donut"; export * from "./line"; export * from "./pie"; +export * from "./gauge"; export * from "./scatter"; export * from "./step"; @@ -61,6 +63,11 @@ export const chartTypes = { angular: "ibm-pie-chart", vue: "ccv-pie-chart" }, + GaugeChart: { + vanilla: "GaugeChart", + angular: "ibm-gauge-chart", + vue: "ccv-gauge-chart" + }, DonutChart: { vanilla: "DonutChart", angular: "ibm-donut-chart", @@ -211,6 +218,17 @@ let allDemoGroups = [ } ] }, + { + title: "Gauge", + demos: [ + { + options: gaugeDemos.gaugeOptions, + data: gaugeDemos.gaugeData, + chartType: chartTypes.GaugeChart, + isDemoExample: true + } + ] + }, { title: "Scatter", demos: [ diff --git a/packages/core/src/charts/gauge.ts b/packages/core/src/charts/gauge.ts new file mode 100644 index 0000000000..24324f9e20 --- /dev/null +++ b/packages/core/src/charts/gauge.ts @@ -0,0 +1,46 @@ +// Internal Imports +import { PieChart } from "./pie"; +import * as Configuration from "../configuration"; +import { + ChartConfig, + GaugeChartOptions +} from "../interfaces/index"; +import { Tools } from "../tools"; + +// Components +import { + Gauge, + // the imports below are needed because of typescript bug (error TS4029) + Legend, + LayoutComponent, + Tooltip +} from "../components/index"; + +export class GaugeChart extends PieChart { + constructor(holder: Element, chartConfigs: ChartConfig) { + super(holder, chartConfigs, true); + + // Merge the default options for this chart + // With the user provided options + this.model.setOptions( + Tools.mergeDefaultChartOptions( + Configuration.options.gaugeChart, + chartConfigs.options + ) + ); + + // Initialize data, services, components etc. + this.init(holder, chartConfigs); + } + + getComponents() { + // Specify what to render inside the graph-frame + const graphFrameComponents = [ + new Gauge(this.model, this.services) + ]; + + const components: any[] = this.getChartComponents(graphFrameComponents); + components.push(new Tooltip(this.model, this.services)); + return components; + } +} diff --git a/packages/core/src/charts/index.ts b/packages/core/src/charts/index.ts index 652290e923..9eea0e7c70 100644 --- a/packages/core/src/charts/index.ts +++ b/packages/core/src/charts/index.ts @@ -6,3 +6,4 @@ export * from "./line"; export * from "./scatter"; export * from "./pie"; export * from "./donut"; +export * from "./gauge"; diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts new file mode 100644 index 0000000000..b200b2a364 --- /dev/null +++ b/packages/core/src/components/graphs/gauge.ts @@ -0,0 +1,288 @@ +// Internal Imports +import { Component } from "../component"; +import { DOMUtils } from "../../services"; +import { clamp, groupBy } from "lodash-es"; +import { + Roles, + TooltipTypes, + Events +} from "../../interfaces"; + +// D3 Imports +import { select } from "d3-selection"; +import { arc } from "d3-shape"; +import { interpolateNumber } from "d3-interpolate"; + +export class Gauge extends Component { + type = "gauge"; + + // We need to store our arcs + // So that addEventListeners() + // Can access them + arc: any; + hoverArc: any; + backgroundArc: any; + + init() { + const eventsFragment = this.services.events; + + // Highlight correct circle on legend item hovers + eventsFragment.addEventListener("legend-item-onhover", this.handleLegendOnHover); + + // Un-highlight circles on legend item mouseouts + eventsFragment.addEventListener("legend-item-onmouseout", this.handleLegendMouseOut); + } + + getDataList() { + const displayData = this.model.getDisplayData(); + const current = displayData.find(d => d.key === "current"); + const old = displayData.find(d => d.key === "old"); + const total = displayData.find(d => d.key === "total"); + return [ + { + label: "Dataset", + current: current ? current.value : 0, + total: total ? total.value : 0, + old: old ? old.value : 0, + value: current ? current.value : 0 + } + ]; + } + + getCurrentRatio(): number { + const total = this.getTotal(); + const current = this.getCurrent(); + const ratio = total === 0 ? 0 : current / total; + return clamp(ratio, 0, 1); + } + + getDelta(): number { + const current = this.getCurrent(); + const old = this.getOld(); + const delta = current - old; + const ratio = old === 0 ? Infinity : delta / old; + return clamp(ratio, -1, Infinity); + } + + getTotal(): number { + const datalist = this.getDataList(); + console.log('datalist', datalist) + const value = datalist[0].total || 0; + return value; + } + + getCurrent(): number { + const datalist = this.getDataList(); + const value = datalist[0].current || 0; + return value; + } + + getOld(): number { + const datalist = this.getDataList(); + const value = datalist[0].old || 0; + return value; + } + + getArcSize(): number { + const options = this.model.getOptions(); + const { arcRatio = 1 } = options.gauge; + const clampedArcRatio = clamp(arcRatio, 0, 1); + return clampedArcRatio * Math.PI * 2; + } + + getStartAngle(): number { + const arcSize = this.getArcSize(); + if (arcSize === 2 * Math.PI) { + return 0; + } + return -arcSize / 2; + } + + render(animate = true) { + const self = this; + const svg = this.getContainerSVG(); + const options = this.model.getOptions(); + const ratio = this.getCurrentRatio(); + const datalist = this.getDataList(); + const delta = this.getDelta(); + const arcSize = this.getArcSize(); + const startAngle = this.getStartAngle(); + const rotationAngle = ratio * arcSize; + const currentAngle = startAngle + rotationAngle; + const endAngle = startAngle + arcSize; + + // Compute the outer radius needed + const radius = this.computeRadius(); + + this.backgroundArc = arc() + .innerRadius(this.getInnerRadius()) + .outerRadius(radius) + .startAngle(currentAngle) + .endAngle(endAngle); + + this.arc = arc() + .innerRadius(this.getInnerRadius()) + .outerRadius(radius) + .startAngle(startAngle) + .endAngle(currentAngle); + + // Set the hover arc radius + this.hoverArc = arc() + .innerRadius(this.getInnerRadius()) + .outerRadius(radius + options.pie.hoverArc.outerRadiusOffset) + .startAngle(startAngle) + .endAngle(currentAngle); + + // Add background arc + + DOMUtils.appendOrSelect(svg, "g.background") + .append("path") + .attr("d", this.backgroundArc) + .attr("fill", "#bbb") + .attr("role", Roles.GROUP); + + // Add data arc + + DOMUtils.appendOrSelect(svg, "g.arc") + .append("path") + .data(datalist) + .attr("d", this.arc) + .classed("arc", true) + .attr("fill", "#00f"); + + // Position Pie + const gaugeTranslateX = radius + options.pie.xOffset; + const gaugeTranslateY = radius + options.pie.yOffset; + svg.attr("transform", `translate(${gaugeTranslateX}, ${gaugeTranslateY})`); + + // Add the number shown in the center of the gauge and the delta + // under it. + + DOMUtils.appendOrSelect(svg, "text.gauge-value") + .attr("text-anchor", "middle") + .attr("alignment-baseline", "middle") + .style("font-size", () => options.gauge.center.valueFontSize(radius, arcSize)) + .transition(this.services.transitions.getTransition("donut-figure-enter-update", animate)) + .attr("y", options.gauge.center.valueYPosition(radius, arcSize)) + .tween("text", function() { + return self.centerNumberTween(select(this), ratio * 100); + }); + + DOMUtils.appendOrSelect(svg, "text.gauge-delta") + .attr("text-anchor", "middle") + .attr("alignment-baseline", "middle") + .style("font-size", () => options.gauge.center.deltaFontSize(radius, arcSize)) + .attr("y", options.gauge.center.deltaYPosition(radius, arcSize)) + .text(() => { + const sign = Math.sign(delta) + const deltaPerc = (delta * 100).toFixed(2); + const arrow = sign === 0 ? "=" : sign === -1 ? "▼" : "▲"; + return `${arrow} ${deltaPerc}%`; + }); + + // Add event listeners + this.addEventListeners(); + } + + + getInnerRadius() { + // Compute the outer radius needed + const radius = this.computeRadius(); + return radius * (3 / 4); + } + + centerNumberTween(d3Ref, value: number) { + const options = this.model.getOptions(); + // Remove commas from the current value string, and convert to an int + const currentValue = parseInt(d3Ref.text().replace(/[, ]+/g, ""), 10) || 0; + const i = interpolateNumber(currentValue, value); + + return t => { + const { numberFormatter } = options.gauge.center; + const number = i(t); + const formattedNumber = numberFormatter(number); + return d3Ref.text(formattedNumber); + }; + } + + // Highlight elements that match the hovered legend item + handleLegendOnHover = (event: CustomEvent) => { + const { hoveredElement } = event.detail; + + this.parent.selectAll("path.arc") + .transition(this.services.transitions.getTransition("legend-hover-bar")) + .attr("opacity", d => (d.data.label !== hoveredElement.datum()["key"]) ? 0.3 : 1); + } + + // Un-highlight all elements + handleLegendMouseOut = (event: CustomEvent) => { + this.parent.selectAll("path.arc") + .transition(this.services.transitions.getTransition("legend-mouseout-bar")) + .attr("opacity", 1); + } + + addEventListeners() { + const self = this; + this.parent.selectAll("path.arc") + .on("mouseover", function (datum) { + // Dispatch mouse event + self.services.events.dispatchEvent(Events.Gauge.ARC_MOUSEOVER, { + element: select(this), + datum + }); + }) + .on("mousemove", function (datum) { + const hoveredElement = select(this); + + hoveredElement.classed("hovered", true) + .transition(self.services.transitions.getTransition("pie_slice_mouseover")) + .attr("d", self.hoverArc); + + // Dispatch mouse event + self.services.events.dispatchEvent(Events.Gauge.ARC_MOUSEMOVE, { + element: hoveredElement, + datum + }); + + // Show tooltip + self.services.events.dispatchEvent("show-tooltip", { + hoveredElement, + type: TooltipTypes.DATAPOINT + }); + }) + .on("click", function (datum) { + // Dispatch mouse event + self.services.events.dispatchEvent(Events.Gauge.ARC_CLICK, { + element: select(this), + datum + }); + }) + .on("mouseout", function (datum) { + const hoveredElement = select(this); + hoveredElement.classed("hovered", false) + .transition(self.services.transitions.getTransition("pie_slice_mouseover")) + .attr("d", self.arc); + + // Dispatch mouse event + self.services.events.dispatchEvent(Events.Gauge.ARC_MOUSEOUT, { + element: hoveredElement, + datum + }); + + // Hide tooltip + self.services.events.dispatchEvent("hide-tooltip", { hoveredElement }); + }); + } + + // Helper functions + protected computeRadius() { + const arcSize = this.getArcSize(); + const options = this.model.getOptions(); + const multiplier = Math.min(Math.PI / arcSize, 1); + + const { width, height } = DOMUtils.getSVGElementSize(this.parent, { useAttrs: true }); + const radius: number = Math.min(width, height) * multiplier; + + return radius + options.pie.radiusOffset; + } +} diff --git a/packages/core/src/components/index.ts b/packages/core/src/components/index.ts index c323f462c5..f57cf48d76 100644 --- a/packages/core/src/components/index.ts +++ b/packages/core/src/components/index.ts @@ -16,6 +16,7 @@ export * from "./graphs/bubble"; export * from "./graphs/line"; export * from "./graphs/scatter"; export * from "./graphs/pie"; +export * from "./graphs/gauge"; export * from "./graphs/donut"; // Layout diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index c04f3b49b7..3b8a569ddb 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -7,6 +7,7 @@ import { BarChartOptions, StackedBarChartOptions, PieChartOptions, + GaugeChartOptions, DonutChartOptions, BubbleChartOptions, // Components @@ -22,6 +23,7 @@ import { } from "./interfaces"; import enUSLocaleObject from "date-fns/locale/en-US/index"; + /* ***************************** * User configurable options * @@ -260,15 +262,46 @@ const pieChart: PieChartOptions = Tools.merge({}, chart, { } } as PieChartOptions); +/** + * options specific to gauge charts + */ + +function getGaugeFontSize(radius: number, arcSize: number, maxSize: number) { + const adjustedRadius = (radius * Math.PI / arcSize) / 100; + return Tools.interpolateAndClamp(adjustedRadius, maxSize); +} + +const gaugeChart: GaugeChartOptions = Tools.merge({}, pieChart, { + gauge: { + center: { + valueFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 48) + "px", + deltaFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 24) + "px", + titleFontSize: radius => Tools.interpolateAndClamp((radius / 100), 15) + "px", + valueYPosition: (radius, arcSize) => { + const deltaYPosition = ((arcSize - 2 * Math.PI) / Math.PI) * getGaugeFontSize(radius, arcSize, 24); + const valueYPosition = ((arcSize - 2 * Math.PI) / Math.PI) * getGaugeFontSize(radius, arcSize, 48); + return (deltaYPosition + valueYPosition) + "px"; + }, + deltaYPosition: (radius, arcSize) => { + const deltaYPosition = ((arcSize - 2 * Math.PI) / Math.PI) * getGaugeFontSize(radius, arcSize, 24); + const valueYPosition = ((arcSize - 2 * Math.PI) / Math.PI) * getGaugeFontSize(radius, arcSize, 48); + const deltaFontSize = getGaugeFontSize(radius, arcSize, 24) + return (deltaYPosition + valueYPosition + deltaFontSize * 1.5) + "px"; + }, + numberFormatter: number => number.toFixed(2).toLocaleString() + "%" + } + } +} as GaugeChartOptions); + /** * options specific to donut charts */ const donutChart: DonutChartOptions = Tools.merge({}, pieChart, { donut: { center: { - numberFontSize: radius => Math.min((radius / 100) * 24, 24) + "px", - titleFontSize: radius => Math.min((radius / 100) * 15, 15) + "px", - titleYPosition: radius => Math.min((radius / 80) * 20, 20), + numberFontSize: radius => Tools.interpolateAndClamp((radius / 100), 24) + "px", + titleFontSize: radius => Tools.interpolateAndClamp((radius / 100), 15) + "px", + titleYPosition: radius => Tools.interpolateAndClamp((radius / 80), 20), numberFormatter: number => Math.floor(number).toLocaleString() } } @@ -284,6 +317,7 @@ export const options = { lineChart, scatterChart, pieChart, + gaugeChart, donutChart }; diff --git a/packages/core/src/interfaces/charts.ts b/packages/core/src/interfaces/charts.ts index 8821191a7f..c672d847c0 100644 --- a/packages/core/src/interfaces/charts.ts +++ b/packages/core/src/interfaces/charts.ts @@ -173,6 +173,22 @@ export interface PieChartOptions extends BaseChartOptions { }; } +/** + * options specific to gauge charts + */ +export interface GaugeChartOptions extends PieChartOptions { + gauge?: { + center?: { + valueFontSize?: Function; + deltaFontSize?: Function; + titleFontSize?: Function; + deltaYPosition?: Function; + valueYPosition?: Function; + numberFormatter?: Function; + }; + arcRatio?: number + }; +} /** diff --git a/packages/core/src/interfaces/events.ts b/packages/core/src/interfaces/events.ts index 93ab6b034a..b38f72aad7 100644 --- a/packages/core/src/interfaces/events.ts +++ b/packages/core/src/interfaces/events.ts @@ -33,6 +33,16 @@ export enum Pie { SLICE_MOUSEOUT = "pie-slice-mouseout" } +/** + * enum of all gauge graph events + */ +export enum Gauge { + ARC_MOUSEOVER = "gauge-arc-mouseover", + ARC_MOUSEMOVE = "gauge-arc-mousemove", + ARC_CLICK = "gauge-arc-click", + ARC_MOUSEOUT = "gauge-arc-mouseout" +} + /** * enum of all bar graph events */ diff --git a/packages/core/src/tools.ts b/packages/core/src/tools.ts index 2fb852e6eb..5a91601070 100644 --- a/packages/core/src/tools.ts +++ b/packages/core/src/tools.ts @@ -162,6 +162,27 @@ export namespace Tools { return percentage < 1 ? percentage.toPrecision(1) : Math.floor(percentage); } + /** + * Linearly interpolates a value between minValue and maxValue, then + * clamps the result to the two limits. + * The first parameter is always the value to interpolate. When called + * with one additional parameter, minValue is set to 0, while the only + * parameter is used as maxValue. When called with 2 additional + * parameters, they are read as minValue and maxValue, respectively. + * @export + * @param {number} value + * @param {number} firstLimit + * @param {number} [secondLimit] + * @returns The interpolated value + */ + export function interpolateAndClamp(value: number, firstLimit: number, secondLimit?: number): number { + const minValue = secondLimit === undefined ? 0 : firstLimit; + const maxValue = secondLimit === undefined ? firstLimit : secondLimit; + const interpolated = maxValue * value; + return lodashClamp(interpolated, minValue, maxValue); + } + + /************************************** * Object/array related checks * *************************************/ diff --git a/packages/core/stories/all.stories.ts b/packages/core/stories/all.stories.ts index c67ce62b39..02fb0ff294 100644 --- a/packages/core/stories/all.stories.ts +++ b/packages/core/stories/all.stories.ts @@ -144,10 +144,9 @@ if (process.env.NODE_ENV !== "production") { storyUtils.addRadioButtonEventListeners(container); const getNewRow = () => { - const row = document.createElement("div"); - row.className = "bx--row"; - - return row; + const newRow = document.createElement("div"); + newRow.setAttribute("class", "bx--row"); + return newRow; }; const grid = document.createElement("div"); From 6cbbb500f3b00907cab4e8a51d9c6b1cff129e44 Mon Sep 17 00:00:00 2001 From: Luca Mattiazzi Date: Wed, 15 Apr 2020 10:43:55 +0200 Subject: [PATCH 02/43] added to react --- packages/react/src/gauge-chart.js | 25 +++++++++++++++++++++++++ packages/react/src/index.js | 2 ++ 2 files changed, 27 insertions(+) create mode 100644 packages/react/src/gauge-chart.js diff --git a/packages/react/src/gauge-chart.js b/packages/react/src/gauge-chart.js new file mode 100644 index 0000000000..5d785ff48b --- /dev/null +++ b/packages/react/src/gauge-chart.js @@ -0,0 +1,25 @@ +import React from "react"; + +import { GaugeChart as GC } from "@carbon/charts"; +import BaseChart from "./base-chart"; + +export default class GaugeChart extends BaseChart { + componentDidMount() { + this.chart = new GC( + this.chartRef, + { + data: this.props.data, + options: this.props.options + } + ); + } + + render() { + return ( +
this.chartRef = chartRef} + className="chart-holder"> +
+ ); + } +} diff --git a/packages/react/src/index.js b/packages/react/src/index.js index 0893d26325..2360b0a515 100644 --- a/packages/react/src/index.js +++ b/packages/react/src/index.js @@ -3,6 +3,7 @@ import SimpleBarChart from "./bar-chart-simple"; import StackedBarChart from "./bar-chart-stacked"; import BubbleChart from "./bubble-chart"; import DonutChart from "./donut-chart"; +import GaugeChart from "./gauge-chart"; import LineChart from "./line-chart"; import PieChart from "./pie-chart"; import ScatterChart from "./scatter-chart"; @@ -13,6 +14,7 @@ export { StackedBarChart, BubbleChart, DonutChart, + GaugeChart, LineChart, PieChart, ScatterChart From 94e9439b51e642c94f823fb99c9a4f36b2136861 Mon Sep 17 00:00:00 2001 From: Luca Mattiazzi Date: Wed, 15 Apr 2020 10:52:29 +0200 Subject: [PATCH 03/43] added to all packages --- packages/angular/src/charts.module.ts | 3 ++ packages/angular/src/gauge-chart.component.ts | 34 +++++++++++++++++++ packages/angular/src/index.ts | 1 + packages/vue/src/ccv-donut-chart.vue | 4 +-- packages/vue/src/ccv-gauge-chart.vue | 19 +++++++++++ packages/vue/src/index.js | 7 ++-- 6 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 packages/angular/src/gauge-chart.component.ts create mode 100644 packages/vue/src/ccv-gauge-chart.vue diff --git a/packages/angular/src/charts.module.ts b/packages/angular/src/charts.module.ts index 6ef20be4a0..28221f33d2 100644 --- a/packages/angular/src/charts.module.ts +++ b/packages/angular/src/charts.module.ts @@ -7,6 +7,7 @@ import { GroupedBarChartComponent } from "./bar-chart-grouped.component"; import { StackedBarChartComponent } from "./bar-chart-stacked.component"; import { BubbleChartComponent } from "./bubble-chart.component"; import { DonutChartComponent } from "./donut-chart.component"; +import { GaugeChartComponent } from "./gauge-chart.component"; import { LineChartComponent } from "./line-chart.component"; import { PieChartComponent } from "./pie-chart.component"; import { ScatterChartComponent } from "./scatter-chart.component"; @@ -22,6 +23,7 @@ import { ScatterChartComponent } from "./scatter-chart.component"; StackedBarChartComponent, BubbleChartComponent, DonutChartComponent, + GaugeChartComponent, LineChartComponent, PieChartComponent, ScatterChartComponent @@ -33,6 +35,7 @@ import { ScatterChartComponent } from "./scatter-chart.component"; StackedBarChartComponent, BubbleChartComponent, DonutChartComponent, + GaugeChartComponent, LineChartComponent, PieChartComponent, ScatterChartComponent diff --git a/packages/angular/src/gauge-chart.component.ts b/packages/angular/src/gauge-chart.component.ts new file mode 100644 index 0000000000..2b56959bad --- /dev/null +++ b/packages/angular/src/gauge-chart.component.ts @@ -0,0 +1,34 @@ +import { + Component, + AfterViewInit +} from "@angular/core"; + +import { BaseChart } from "./base-chart.component"; + +import { GaugeChart } from "@carbon/charts"; + +/** + * Wrapper around `GaugeChart` in carbon charts library + * + * Most functions just call their equivalent from the chart library. + */ +@Component({ + selector: "ibm-gauge-chart", + template: `` +}) +export class GaugeChartComponent extends BaseChart implements AfterViewInit { + /** + * Runs after view init to create a chart, attach it to `elementRef` and draw it. + */ + ngAfterViewInit() { + this.chart = new GaugeChart( + this.elementRef.nativeElement, + { + data: this.data, + options: this.options + } + ); + + Object.assign(this, this.chart); + } +} diff --git a/packages/angular/src/index.ts b/packages/angular/src/index.ts index e530cc0b46..c07b49b2ff 100644 --- a/packages/angular/src/index.ts +++ b/packages/angular/src/index.ts @@ -6,6 +6,7 @@ export * from "./bar-chart-grouped.component"; export * from "./bar-chart-stacked.component"; export * from "./bubble-chart.component"; export * from "./donut-chart.component"; +export * from "./gauge-chart.component"; export * from "./line-chart.component"; export * from "./pie-chart.component"; export * from "./scatter-chart.component"; diff --git a/packages/vue/src/ccv-donut-chart.vue b/packages/vue/src/ccv-donut-chart.vue index fca39148c0..6203ed28e0 100644 --- a/packages/vue/src/ccv-donut-chart.vue +++ b/packages/vue/src/ccv-donut-chart.vue @@ -12,8 +12,8 @@ export default { mounted() { this.coreChart = new DonutChart(this.$el, { data: this.data, - options: this.options + options: this.options, }); - } + }, }; diff --git a/packages/vue/src/ccv-gauge-chart.vue b/packages/vue/src/ccv-gauge-chart.vue new file mode 100644 index 0000000000..005935c170 --- /dev/null +++ b/packages/vue/src/ccv-gauge-chart.vue @@ -0,0 +1,19 @@ + + + diff --git a/packages/vue/src/index.js b/packages/vue/src/index.js index ad4ac6d89c..d92c126c4b 100644 --- a/packages/vue/src/index.js +++ b/packages/vue/src/index.js @@ -3,6 +3,7 @@ import CcvGroupedBarChart from './ccv-grouped-bar-chart.vue'; import CcvStackedBarChart from './ccv-stacked-bar-chart.vue'; import CcvBubbleChart from './ccv-bubble-chart.vue'; import CcvDonutChart from './ccv-donut-chart.vue'; +import CcvGaugeChart from './ccv-gauge-chart.vue'; import CcvLineChart from './ccv-line-chart.vue'; import CcvPieChart from './ccv-pie-chart.vue'; import CcvScatterChart from './ccv-scatter-chart.vue'; @@ -13,9 +14,10 @@ const components = [ CcvStackedBarChart, CcvBubbleChart, CcvDonutChart, + CcvGaugeChart, CcvLineChart, CcvPieChart, - CcvScatterChart + CcvScatterChart, ]; /* @@ -56,7 +58,8 @@ export { CcvStackedBarChart, CcvBubbleChart, CcvDonutChart, + CcvGaugeChart, CcvLineChart, CcvPieChart, - CcvScatterChart + CcvScatterChart, }; From 253b82934bea25cb55b93c2665cc1fff7395cc70 Mon Sep 17 00:00:00 2001 From: Luca Mattiazzi Date: Wed, 15 Apr 2020 12:18:02 +0200 Subject: [PATCH 04/43] resized gauge, corrected colors --- packages/core/src/components/graphs/gauge.ts | 21 ++++++++++---------- packages/core/src/configuration.ts | 1 + 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index b200b2a364..7e10b7b4b8 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -66,7 +66,6 @@ export class Gauge extends Component { getTotal(): number { const datalist = this.getDataList(); - console.log('datalist', datalist) const value = datalist[0].total || 0; return value; } @@ -113,22 +112,23 @@ export class Gauge extends Component { // Compute the outer radius needed const radius = this.computeRadius(); + const innerRadius = this.getInnerRadius(); this.backgroundArc = arc() - .innerRadius(this.getInnerRadius()) + .innerRadius(innerRadius) .outerRadius(radius) .startAngle(currentAngle) .endAngle(endAngle); this.arc = arc() - .innerRadius(this.getInnerRadius()) + .innerRadius(innerRadius) .outerRadius(radius) .startAngle(startAngle) .endAngle(currentAngle); // Set the hover arc radius this.hoverArc = arc() - .innerRadius(this.getInnerRadius()) + .innerRadius(innerRadius) .outerRadius(radius + options.pie.hoverArc.outerRadiusOffset) .startAngle(startAngle) .endAngle(currentAngle); @@ -138,7 +138,7 @@ export class Gauge extends Component { DOMUtils.appendOrSelect(svg, "g.background") .append("path") .attr("d", this.backgroundArc) - .attr("fill", "#bbb") + .attr("fill", "rgb(224,224,224)") .attr("role", Roles.GROUP); // Add data arc @@ -148,7 +148,7 @@ export class Gauge extends Component { .data(datalist) .attr("d", this.arc) .classed("arc", true) - .attr("fill", "#00f"); + .attr("fill", "rgb(88,134,247)"); // Position Pie const gaugeTranslateX = radius + options.pie.xOffset; @@ -162,7 +162,7 @@ export class Gauge extends Component { .attr("text-anchor", "middle") .attr("alignment-baseline", "middle") .style("font-size", () => options.gauge.center.valueFontSize(radius, arcSize)) - .transition(this.services.transitions.getTransition("donut-figure-enter-update", animate)) + .transition(this.services.transitions.getTransition("gauge-figure-enter-update", animate)) .attr("y", options.gauge.center.valueYPosition(radius, arcSize)) .tween("text", function() { return self.centerNumberTween(select(this), ratio * 100); @@ -188,7 +188,8 @@ export class Gauge extends Component { getInnerRadius() { // Compute the outer radius needed const radius = this.computeRadius(); - return radius * (3 / 4); + const options = this.model.getOptions(); + return radius - options.gauge.arcWidth; } centerNumberTween(d3Ref, value: number) { @@ -245,7 +246,7 @@ export class Gauge extends Component { }); // Show tooltip - self.services.events.dispatchEvent("show-tooltip", { + self.services.events.dispatchEvent(Events.Tooltip.SHOW, { hoveredElement, type: TooltipTypes.DATAPOINT }); @@ -270,7 +271,7 @@ export class Gauge extends Component { }); // Hide tooltip - self.services.events.dispatchEvent("hide-tooltip", { hoveredElement }); + self.services.events.dispatchEvent(Events.Tooltip.HIDE, { hoveredElement }); }); } diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 3b8a569ddb..d5e1dc26ce 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -273,6 +273,7 @@ function getGaugeFontSize(radius: number, arcSize: number, maxSize: number) { const gaugeChart: GaugeChartOptions = Tools.merge({}, pieChart, { gauge: { + arcWidth: 16, center: { valueFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 48) + "px", deltaFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 24) + "px", From 176f8f0d8df69a3b43b47499bafe5803048db7d3 Mon Sep 17 00:00:00 2001 From: Luca Mattiazzi Date: Thu, 16 Apr 2020 11:11:39 +0200 Subject: [PATCH 05/43] fixed tooltip --- packages/core/src/charts/gauge.ts | 6 +++--- packages/core/src/components/graphs/gauge.ts | 20 +++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/core/src/charts/gauge.ts b/packages/core/src/charts/gauge.ts index 24324f9e20..a279e8a073 100644 --- a/packages/core/src/charts/gauge.ts +++ b/packages/core/src/charts/gauge.ts @@ -3,7 +3,7 @@ import { PieChart } from "./pie"; import * as Configuration from "../configuration"; import { ChartConfig, - GaugeChartOptions + GaugeChartOptions, } from "../interfaces/index"; import { Tools } from "../tools"; @@ -13,7 +13,7 @@ import { // the imports below are needed because of typescript bug (error TS4029) Legend, LayoutComponent, - Tooltip + TooltipPie } from "../components/index"; export class GaugeChart extends PieChart { @@ -40,7 +40,7 @@ export class GaugeChart extends PieChart { ]; const components: any[] = this.getChartComponents(graphFrameComponents); - components.push(new Tooltip(this.model, this.services)); + components.push(new TooltipPie(this.model, this.services)); return components; } } diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index 7e10b7b4b8..b86e7f0c7a 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -40,11 +40,13 @@ export class Gauge extends Component { const total = displayData.find(d => d.key === "total"); return [ { - label: "Dataset", - current: current ? current.value : 0, - total: total ? total.value : 0, - old: old ? old.value : 0, - value: current ? current.value : 0 + data: { + group: "Dataset", + current: current ? current.value : 0, + total: total ? total.value : 0, + old: old ? old.value : 0, + value: current ? current.value : 0 + } } ]; } @@ -66,19 +68,19 @@ export class Gauge extends Component { getTotal(): number { const datalist = this.getDataList(); - const value = datalist[0].total || 0; + const value = datalist[0].data.total || 0; return value; } getCurrent(): number { const datalist = this.getDataList(); - const value = datalist[0].current || 0; + const value = datalist[0].data.current || 0; return value; } getOld(): number { const datalist = this.getDataList(); - const value = datalist[0].old || 0; + const value = datalist[0].data.old || 0; return value; } @@ -261,7 +263,7 @@ export class Gauge extends Component { .on("mouseout", function (datum) { const hoveredElement = select(this); hoveredElement.classed("hovered", false) - .transition(self.services.transitions.getTransition("pie_slice_mouseover")) + .transition(self.services.transitions.getTransition("gauge_slice_mouseover")) .attr("d", self.arc); // Dispatch mouse event From 82ff6a7ffab8789175924a7b846c88fa82a024a9 Mon Sep 17 00:00:00 2001 From: Luca Mattiazzi Date: Fri, 17 Apr 2020 17:34:13 +0200 Subject: [PATCH 06/43] two stories for gauge: circular and semicircular --- packages/core/demo/data/gauge.ts | 14 ++++++++++++-- packages/core/demo/data/index.ts | 8 +++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/core/demo/data/gauge.ts b/packages/core/demo/data/gauge.ts index ea461f6ed0..a26663c8bf 100644 --- a/packages/core/demo/data/gauge.ts +++ b/packages/core/demo/data/gauge.ts @@ -4,10 +4,20 @@ export const gaugeData = [ { group: "Dataset", key: "total", value: 200 } ]; -export const gaugeOptions = { - title: "Gauge", +export const gaugeOptionsSemi = { + title: "Gauge semicircular", resizable: true, + height: "250px", gauge: { arcRatio: 0.5 } }; + +export const gaugeOptionsCircular = { + title: "Gauge circular", + resizable: true, + height: "250px", + gauge: { + arcRatio: 1 + } +}; diff --git a/packages/core/demo/data/index.ts b/packages/core/demo/data/index.ts index ced412f9f3..d86a2231a0 100644 --- a/packages/core/demo/data/index.ts +++ b/packages/core/demo/data/index.ts @@ -222,7 +222,13 @@ let allDemoGroups = [ title: "Gauge", demos: [ { - options: gaugeDemos.gaugeOptions, + options: gaugeDemos.gaugeOptionsSemi, + data: gaugeDemos.gaugeData, + chartType: chartTypes.GaugeChart, + isDemoExample: true + }, + { + options: gaugeDemos.gaugeOptionsCircular, data: gaugeDemos.gaugeData, chartType: chartTypes.GaugeChart, isDemoExample: true From 275b76ceffbfa43cf0c3ae6266a4734d834cb4b6 Mon Sep 17 00:00:00 2001 From: Luca Mattiazzi Date: Fri, 17 Apr 2020 17:37:37 +0200 Subject: [PATCH 07/43] hidden legend --- packages/core/src/charts/gauge.ts | 2 -- packages/core/src/configuration.ts | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/core/src/charts/gauge.ts b/packages/core/src/charts/gauge.ts index a279e8a073..c906a8481f 100644 --- a/packages/core/src/charts/gauge.ts +++ b/packages/core/src/charts/gauge.ts @@ -11,8 +11,6 @@ import { Tools } from "../tools"; import { Gauge, // the imports below are needed because of typescript bug (error TS4029) - Legend, - LayoutComponent, TooltipPie } from "../components/index"; diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index d5e1dc26ce..f250cd324f 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -272,6 +272,9 @@ function getGaugeFontSize(radius: number, arcSize: number, maxSize: number) { } const gaugeChart: GaugeChartOptions = Tools.merge({}, pieChart, { + legend: { + enabled: false + }, gauge: { arcWidth: 16, center: { From 560152e2cc1b40069844cb2b3df240d4d05b7faf Mon Sep 17 00:00:00 2001 From: Luca Mattiazzi Date: Fri, 17 Apr 2020 18:32:03 +0200 Subject: [PATCH 08/43] changed perc symbol size and position, also gauge size --- packages/core/src/components/graphs/gauge.ts | 28 ++++++++++++++------ packages/core/src/configuration.ts | 7 ++--- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index b86e7f0c7a..92ba503312 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -160,15 +160,27 @@ export class Gauge extends Component { // Add the number shown in the center of the gauge and the delta // under it. - DOMUtils.appendOrSelect(svg, "text.gauge-value") + const gaugeText = DOMUtils + .appendOrSelect(svg, "text.gauge-value") .attr("text-anchor", "middle") - .attr("alignment-baseline", "middle") - .style("font-size", () => options.gauge.center.valueFontSize(radius, arcSize)) - .transition(this.services.transitions.getTransition("gauge-figure-enter-update", animate)) - .attr("y", options.gauge.center.valueYPosition(radius, arcSize)) - .tween("text", function() { - return self.centerNumberTween(select(this), ratio * 100); - }); + .attr("alignment-baseline", "middle"); + + DOMUtils.appendOrSelect(gaugeText, "tspan.gauge-value-number") + .style("font-size", () => options.gauge.center.valueFontSize(radius, arcSize)) + .transition(this.services.transitions.getTransition("gauge-figure-enter-update", animate)) + .attr("y", options.gauge.center.valueYPosition(radius, arcSize)) + .tween("text", function() { + return self.centerNumberTween(select(this), ratio * 100); + }); + + DOMUtils.appendOrSelect(gaugeText, "tspan.gauge-value-symbol") + .attr("text-anchor", "middle") + .attr("alignment-baseline", "baseline") + .style("font-size", () => options.gauge.center.percFontSize(radius, arcSize)) + .attr("dx", () => `-${options.gauge.center.valueFontSize(radius, arcSize)}`) + .attr("dy", () => `-${options.gauge.center.percFontSize(radius, arcSize)}`) + .attr("y", options.gauge.center.valueYPosition(radius, arcSize)) + .text("%"); DOMUtils.appendOrSelect(svg, "text.gauge-delta") .attr("text-anchor", "middle") diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index f250cd324f..459260f878 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -278,8 +278,9 @@ const gaugeChart: GaugeChartOptions = Tools.merge({}, pieChart, { gauge: { arcWidth: 16, center: { - valueFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 48) + "px", - deltaFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 24) + "px", + valueFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 58) + "px", + percFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 23) + "px", + deltaFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 23) + "px", titleFontSize: radius => Tools.interpolateAndClamp((radius / 100), 15) + "px", valueYPosition: (radius, arcSize) => { const deltaYPosition = ((arcSize - 2 * Math.PI) / Math.PI) * getGaugeFontSize(radius, arcSize, 24); @@ -292,7 +293,7 @@ const gaugeChart: GaugeChartOptions = Tools.merge({}, pieChart, { const deltaFontSize = getGaugeFontSize(radius, arcSize, 24) return (deltaYPosition + valueYPosition + deltaFontSize * 1.5) + "px"; }, - numberFormatter: number => number.toFixed(2).toLocaleString() + "%" + numberFormatter: number => number.toFixed(2).toLocaleString() } } } as GaugeChartOptions); From 4690a1d3dbb08bf5ab0698d90890e754e08d9358 Mon Sep 17 00:00:00 2001 From: Luca Mattiazzi Date: Fri, 17 Apr 2020 18:45:38 +0200 Subject: [PATCH 09/43] distance between numbers --- packages/core/src/components/graphs/gauge.ts | 39 ++++++++++---------- packages/core/src/configuration.ts | 21 ++++------- 2 files changed, 27 insertions(+), 33 deletions(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index 92ba503312..a8e87c37c8 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -163,30 +163,28 @@ export class Gauge extends Component { const gaugeText = DOMUtils .appendOrSelect(svg, "text.gauge-value") .attr("text-anchor", "middle") - .attr("alignment-baseline", "middle"); - - DOMUtils.appendOrSelect(gaugeText, "tspan.gauge-value-number") - .style("font-size", () => options.gauge.center.valueFontSize(radius, arcSize)) - .transition(this.services.transitions.getTransition("gauge-figure-enter-update", animate)) - .attr("y", options.gauge.center.valueYPosition(radius, arcSize)) - .tween("text", function() { - return self.centerNumberTween(select(this), ratio * 100); - }); + .attr("alignment-baseline", "baseline"); + + DOMUtils.appendOrSelect(gaugeText, "tspan.gauge-value-number") + .style("font-size", () => options.gauge.center.valueFontSize(radius, arcSize)) + .transition(this.services.transitions.getTransition("gauge-figure-enter-update", animate)) + .attr("y", options.gauge.center.valueYPosition(radius, arcSize)) + .tween("text", function() { + return self.centerNumberTween(select(this), ratio * 100); + }); - DOMUtils.appendOrSelect(gaugeText, "tspan.gauge-value-symbol") - .attr("text-anchor", "middle") - .attr("alignment-baseline", "baseline") - .style("font-size", () => options.gauge.center.percFontSize(radius, arcSize)) - .attr("dx", () => `-${options.gauge.center.valueFontSize(radius, arcSize)}`) - .attr("dy", () => `-${options.gauge.center.percFontSize(radius, arcSize)}`) - .attr("y", options.gauge.center.valueYPosition(radius, arcSize)) - .text("%"); + DOMUtils.appendOrSelect(gaugeText, "tspan.gauge-value-symbol") + .style("font-size", () => options.gauge.center.percFontSize(radius, arcSize)) + .attr("dx", () => `-${options.gauge.center.valueFontSize(radius, arcSize)}`) + .attr("dy", () => `-${options.gauge.center.percFontSize(radius, arcSize)}`) + .attr("y", options.gauge.center.valueYPosition(radius, arcSize)) + .text("%"); - DOMUtils.appendOrSelect(svg, "text.gauge-delta") + const subText = DOMUtils.appendOrSelect(svg, "text.gauge-delta") .attr("text-anchor", "middle") - .attr("alignment-baseline", "middle") + .attr("alignment-baseline", "hanging") .style("font-size", () => options.gauge.center.deltaFontSize(radius, arcSize)) - .attr("y", options.gauge.center.deltaYPosition(radius, arcSize)) + .attr("y", options.gauge.center.valueYPosition(radius, arcSize) + options.gauge.distanceBetweenNumbers) .text(() => { const sign = Math.sign(delta) const deltaPerc = (delta * 100).toFixed(2); @@ -194,6 +192,7 @@ export class Gauge extends Component { return `${arrow} ${deltaPerc}%`; }); + // Add event listeners this.addEventListeners(); } diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 459260f878..70dc6d7598 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -277,21 +277,16 @@ const gaugeChart: GaugeChartOptions = Tools.merge({}, pieChart, { }, gauge: { arcWidth: 16, + distanceBetweenNumbers: 20, center: { - valueFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 58) + "px", - percFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 23) + "px", - deltaFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 23) + "px", - titleFontSize: radius => Tools.interpolateAndClamp((radius / 100), 15) + "px", + valueFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 58), + percFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 23), + deltaFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 23), + titleFontSize: radius => Tools.interpolateAndClamp((radius / 100), 15), valueYPosition: (radius, arcSize) => { - const deltaYPosition = ((arcSize - 2 * Math.PI) / Math.PI) * getGaugeFontSize(radius, arcSize, 24); - const valueYPosition = ((arcSize - 2 * Math.PI) / Math.PI) * getGaugeFontSize(radius, arcSize, 48); - return (deltaYPosition + valueYPosition) + "px"; - }, - deltaYPosition: (radius, arcSize) => { - const deltaYPosition = ((arcSize - 2 * Math.PI) / Math.PI) * getGaugeFontSize(radius, arcSize, 24); - const valueYPosition = ((arcSize - 2 * Math.PI) / Math.PI) * getGaugeFontSize(radius, arcSize, 48); - const deltaFontSize = getGaugeFontSize(radius, arcSize, 24) - return (deltaYPosition + valueYPosition + deltaFontSize * 1.5) + "px"; + const deltaYPosition = ((arcSize - 2 * Math.PI) / Math.PI) * getGaugeFontSize(radius, arcSize, 23); + const valueYPosition = ((arcSize - 2 * Math.PI) / Math.PI) * getGaugeFontSize(radius, arcSize, 58); + return (deltaYPosition + valueYPosition); }, numberFormatter: number => number.toFixed(2).toLocaleString() } From f6562306aabe314e3d1161ab45527db96ad85cbf Mon Sep 17 00:00:00 2001 From: Luca Mattiazzi Date: Fri, 17 Apr 2020 18:50:26 +0200 Subject: [PATCH 10/43] last fix for text size --- packages/core/src/configuration.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 70dc6d7598..038754b870 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -267,7 +267,7 @@ const pieChart: PieChartOptions = Tools.merge({}, chart, { */ function getGaugeFontSize(radius: number, arcSize: number, maxSize: number) { - const adjustedRadius = (radius * Math.PI / arcSize) / 100; + const adjustedRadius = (radius * Math.PI / arcSize) / 200; return Tools.interpolateAndClamp(adjustedRadius, maxSize); } From 6863cb14c354156c51a2e333115c9e1cebefb8c8 Mon Sep 17 00:00:00 2001 From: Luca Mattiazzi Date: Wed, 22 Apr 2020 16:04:51 +0200 Subject: [PATCH 11/43] carets with svgs --- packages/core/src/components/graphs/gauge.ts | 25 ++++++++++++++------ packages/core/src/configuration.ts | 1 + 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index a8e87c37c8..b07d6bf899 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -180,17 +180,28 @@ export class Gauge extends Component { .attr("y", options.gauge.center.valueYPosition(radius, arcSize)) .text("%"); - const subText = DOMUtils.appendOrSelect(svg, "text.gauge-delta") + const gaugeDelta = DOMUtils.appendOrSelect(svg, "g.gauge-delta"); + + const deltaArrow = DOMUtils.appendOrSelect(gaugeDelta, "svg.gauge-delta-arrow") + .attr("x", () => `-${options.gauge.center.valueFontSize(radius, arcSize)}`) + .attr( + "y", + options.gauge.center.valueYPosition(radius, arcSize) + options.gauge.distanceBetweenNumbers + options.gauge.center.caretSize / 4 + ) + .attr("width", `${options.gauge.center.caretSize}px`) + .attr("height", `${options.gauge.center.caretSize}px`) + .attr("viewBox", `0 0 ${options.gauge.center.caretSize} ${options.gauge.center.caretSize}`); + + DOMUtils.appendOrSelect(deltaArrow, "polygon.gauge-delta-arrow-polygon") + .attr("points", () => delta > 0 ? "4 10 8 6 12 10" : "12 6 8 10 4 6") + .attr("fill", "rgb(224,224,224)"); + + DOMUtils.appendOrSelect(gaugeDelta, "text.gauge-delta-number") .attr("text-anchor", "middle") .attr("alignment-baseline", "hanging") .style("font-size", () => options.gauge.center.deltaFontSize(radius, arcSize)) .attr("y", options.gauge.center.valueYPosition(radius, arcSize) + options.gauge.distanceBetweenNumbers) - .text(() => { - const sign = Math.sign(delta) - const deltaPerc = (delta * 100).toFixed(2); - const arrow = sign === 0 ? "=" : sign === -1 ? "▼" : "▲"; - return `${arrow} ${deltaPerc}%`; - }); + .text(() => `${(delta * 100).toFixed(2)}%`); // Add event listeners diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 038754b870..5d30121710 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -279,6 +279,7 @@ const gaugeChart: GaugeChartOptions = Tools.merge({}, pieChart, { arcWidth: 16, distanceBetweenNumbers: 20, center: { + caretSize: 16, valueFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 58), percFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 23), deltaFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 23), From 8584e591c6daa6475ab6a3e5b2223d094f3a9a90 Mon Sep 17 00:00:00 2001 From: Luca Mattiazzi Date: Tue, 28 Apr 2020 16:44:38 +0200 Subject: [PATCH 12/43] fixed pixel and dominant baseline for firefox --- packages/core/src/components/graphs/gauge.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index b07d6bf899..f5dedd1822 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -166,7 +166,7 @@ export class Gauge extends Component { .attr("alignment-baseline", "baseline"); DOMUtils.appendOrSelect(gaugeText, "tspan.gauge-value-number") - .style("font-size", () => options.gauge.center.valueFontSize(radius, arcSize)) + .style("font-size", () => `${options.gauge.center.valueFontSize(radius, arcSize)}px`) .transition(this.services.transitions.getTransition("gauge-figure-enter-update", animate)) .attr("y", options.gauge.center.valueYPosition(radius, arcSize)) .tween("text", function() { @@ -174,7 +174,7 @@ export class Gauge extends Component { }); DOMUtils.appendOrSelect(gaugeText, "tspan.gauge-value-symbol") - .style("font-size", () => options.gauge.center.percFontSize(radius, arcSize)) + .style("font-size", () => `${options.gauge.center.percFontSize(radius, arcSize)}px`) .attr("dx", () => `-${options.gauge.center.valueFontSize(radius, arcSize)}`) .attr("dy", () => `-${options.gauge.center.percFontSize(radius, arcSize)}`) .attr("y", options.gauge.center.valueYPosition(radius, arcSize)) @@ -183,10 +183,10 @@ export class Gauge extends Component { const gaugeDelta = DOMUtils.appendOrSelect(svg, "g.gauge-delta"); const deltaArrow = DOMUtils.appendOrSelect(gaugeDelta, "svg.gauge-delta-arrow") - .attr("x", () => `-${options.gauge.center.valueFontSize(radius, arcSize)}`) + .attr("x", () => `-${options.gauge.center.valueFontSize(radius, arcSize)}px`) .attr( "y", - options.gauge.center.valueYPosition(radius, arcSize) + options.gauge.distanceBetweenNumbers + options.gauge.center.caretSize / 4 + `${options.gauge.center.valueYPosition(radius, arcSize) + options.gauge.distanceBetweenNumbers + options.gauge.center.caretSize / 4}px` ) .attr("width", `${options.gauge.center.caretSize}px`) .attr("height", `${options.gauge.center.caretSize}px`) @@ -198,9 +198,9 @@ export class Gauge extends Component { DOMUtils.appendOrSelect(gaugeDelta, "text.gauge-delta-number") .attr("text-anchor", "middle") - .attr("alignment-baseline", "hanging") - .style("font-size", () => options.gauge.center.deltaFontSize(radius, arcSize)) - .attr("y", options.gauge.center.valueYPosition(radius, arcSize) + options.gauge.distanceBetweenNumbers) + .attr("dominant-baseline", "hanging") + .style("font-size", () => `${options.gauge.center.deltaFontSize(radius, arcSize)}px`) + .attr("y", `${options.gauge.center.valueYPosition(radius, arcSize) + options.gauge.distanceBetweenNumbers}px`) .text(() => `${(delta * 100).toFixed(2)}%`); From d4d204caa9289f7dd9a89e79ee1a8c0c934fbd58 Mon Sep 17 00:00:00 2001 From: Luca Mattiazzi Date: Tue, 28 Apr 2020 17:03:22 +0200 Subject: [PATCH 13/43] centers caret for firefox --- packages/core/src/components/graphs/gauge.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index f5dedd1822..2c340733f5 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -186,7 +186,7 @@ export class Gauge extends Component { .attr("x", () => `-${options.gauge.center.valueFontSize(radius, arcSize)}px`) .attr( "y", - `${options.gauge.center.valueYPosition(radius, arcSize) + options.gauge.distanceBetweenNumbers + options.gauge.center.caretSize / 4}px` + `${options.gauge.center.valueYPosition(radius, arcSize) + options.gauge.distanceBetweenNumbers + options.gauge.center.caretSize / 2}px` ) .attr("width", `${options.gauge.center.caretSize}px`) .attr("height", `${options.gauge.center.caretSize}px`) From 9f742ec99c8b60576da125659cc86cc8280e86db Mon Sep 17 00:00:00 2001 From: Luca Mattiazzi Date: Mon, 4 May 2020 10:52:22 +0200 Subject: [PATCH 14/43] fixed caret size and position --- packages/core/src/components/graphs/gauge.ts | 10 +++++----- packages/core/src/configuration.ts | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index 2c340733f5..c8913747ae 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -183,14 +183,14 @@ export class Gauge extends Component { const gaugeDelta = DOMUtils.appendOrSelect(svg, "g.gauge-delta"); const deltaArrow = DOMUtils.appendOrSelect(gaugeDelta, "svg.gauge-delta-arrow") - .attr("x", () => `-${options.gauge.center.valueFontSize(radius, arcSize)}px`) + .attr("x", () => `-${options.gauge.center.valueFontSize(radius, arcSize) + options.gauge.center.caretSize(radius, arcSize) / 2}px`) .attr( "y", - `${options.gauge.center.valueYPosition(radius, arcSize) + options.gauge.distanceBetweenNumbers + options.gauge.center.caretSize / 2}px` + `${options.gauge.center.valueYPosition(radius, arcSize) + options.gauge.distanceBetweenNumbers + options.gauge.center.caretSize(radius, arcSize) / 4}px` ) - .attr("width", `${options.gauge.center.caretSize}px`) - .attr("height", `${options.gauge.center.caretSize}px`) - .attr("viewBox", `0 0 ${options.gauge.center.caretSize} ${options.gauge.center.caretSize}`); + .attr("width", `${options.gauge.center.caretSize(radius, arcSize)}px`) + .attr("height", `${options.gauge.center.caretSize(radius, arcSize)}px`) + .attr("viewBox", `0 0 16 16`); DOMUtils.appendOrSelect(deltaArrow, "polygon.gauge-delta-arrow-polygon") .attr("points", () => delta > 0 ? "4 10 8 6 12 10" : "12 6 8 10 4 6") diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 1355138c1b..47ef6edfab 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -267,7 +267,7 @@ const pieChart: PieChartOptions = Tools.merge({}, chart, { */ function getGaugeFontSize(radius: number, arcSize: number, maxSize: number) { - const adjustedRadius = (radius * Math.PI / arcSize) / 200; + const adjustedRadius = (radius * Math.PI / arcSize) / 100; return Tools.interpolateAndClamp(adjustedRadius, maxSize); } @@ -279,7 +279,7 @@ const gaugeChart: GaugeChartOptions = Tools.merge({}, pieChart, { arcWidth: 16, distanceBetweenNumbers: 20, center: { - caretSize: 16, + caretSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 16), valueFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 58), percFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 23), deltaFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 23), From eae506237dc6aed7cbf3ca84939c49e30f575b56 Mon Sep 17 00:00:00 2001 From: Luca Mattiazzi Date: Tue, 5 May 2020 10:53:27 +0200 Subject: [PATCH 15/43] adapts number size with changing of the size of the chart itself --- packages/core/src/components/graphs/gauge.ts | 5 +++-- packages/core/src/configuration.ts | 18 +++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index c8913747ae..11dd50f3e3 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -178,6 +178,7 @@ export class Gauge extends Component { .attr("dx", () => `-${options.gauge.center.valueFontSize(radius, arcSize)}`) .attr("dy", () => `-${options.gauge.center.percFontSize(radius, arcSize)}`) .attr("y", options.gauge.center.valueYPosition(radius, arcSize)) + .attr("alignment-baseline", "middle") .text("%"); const gaugeDelta = DOMUtils.appendOrSelect(svg, "g.gauge-delta"); @@ -186,7 +187,7 @@ export class Gauge extends Component { .attr("x", () => `-${options.gauge.center.valueFontSize(radius, arcSize) + options.gauge.center.caretSize(radius, arcSize) / 2}px`) .attr( "y", - `${options.gauge.center.valueYPosition(radius, arcSize) + options.gauge.distanceBetweenNumbers + options.gauge.center.caretSize(radius, arcSize) / 4}px` + `${options.gauge.center.valueYPosition(radius, arcSize) + options.gauge.distanceBetweenNumbers(radius, arcSize) + options.gauge.center.caretSize(radius, arcSize) / 4}px` ) .attr("width", `${options.gauge.center.caretSize(radius, arcSize)}px`) .attr("height", `${options.gauge.center.caretSize(radius, arcSize)}px`) @@ -200,7 +201,7 @@ export class Gauge extends Component { .attr("text-anchor", "middle") .attr("dominant-baseline", "hanging") .style("font-size", () => `${options.gauge.center.deltaFontSize(radius, arcSize)}px`) - .attr("y", `${options.gauge.center.valueYPosition(radius, arcSize) + options.gauge.distanceBetweenNumbers}px`) + .attr("y", `${options.gauge.center.valueYPosition(radius, arcSize) + options.gauge.distanceBetweenNumbers(radius, arcSize)}px`) .text(() => `${(delta * 100).toFixed(2)}%`); diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 47ef6edfab..074d4f202b 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -266,7 +266,7 @@ const pieChart: PieChartOptions = Tools.merge({}, chart, { * options specific to gauge charts */ -function getGaugeFontSize(radius: number, arcSize: number, maxSize: number) { +function getGaugePartSize(radius: number, arcSize: number, maxSize: number) { const adjustedRadius = (radius * Math.PI / arcSize) / 100; return Tools.interpolateAndClamp(adjustedRadius, maxSize); } @@ -277,16 +277,16 @@ const gaugeChart: GaugeChartOptions = Tools.merge({}, pieChart, { }, gauge: { arcWidth: 16, - distanceBetweenNumbers: 20, + distanceBetweenNumbers: (radius, arcSize) => getGaugePartSize(radius, arcSize, radius / 12), center: { - caretSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 16), - valueFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 58), - percFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 23), - deltaFontSize: (radius, arcSize) => getGaugeFontSize(radius, arcSize, 23), - titleFontSize: radius => Tools.interpolateAndClamp((radius / 100), 15), + caretSize: (radius, arcSize) => getGaugePartSize(radius, arcSize, radius / 12), + valueFontSize: (radius, arcSize) => getGaugePartSize(radius, arcSize, radius / 4), + percFontSize: (radius, arcSize) => getGaugePartSize(radius, arcSize, radius / 8), + deltaFontSize: (radius, arcSize) => getGaugePartSize(radius, arcSize, radius / 8), + titleFontSize: radius => Tools.interpolateAndClamp((radius / 100), radius / 12), valueYPosition: (radius, arcSize) => { - const deltaYPosition = ((arcSize - 2 * Math.PI) / Math.PI) * getGaugeFontSize(radius, arcSize, 23); - const valueYPosition = ((arcSize - 2 * Math.PI) / Math.PI) * getGaugeFontSize(radius, arcSize, 58); + const deltaYPosition = ((arcSize - 2 * Math.PI) / Math.PI) * getGaugePartSize(radius, arcSize, radius / 8); + const valueYPosition = ((arcSize - 2 * Math.PI) / Math.PI) * getGaugePartSize(radius, arcSize, radius / 4); return (deltaYPosition + valueYPosition); }, numberFormatter: number => number.toFixed(2).toLocaleString() From 3f34172d2629767fb8f81417bf826eb177ad1764 Mon Sep 17 00:00:00 2001 From: Luca Mattiazzi Date: Tue, 5 May 2020 10:55:31 +0200 Subject: [PATCH 16/43] better handling of higher arcRatios --- packages/core/src/configuration.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 074d4f202b..52c4d8b998 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -267,7 +267,7 @@ const pieChart: PieChartOptions = Tools.merge({}, chart, { */ function getGaugePartSize(radius: number, arcSize: number, maxSize: number) { - const adjustedRadius = (radius * Math.PI / arcSize) / 100; + const adjustedRadius = (radius * Math.PI / arcSize) / 10; return Tools.interpolateAndClamp(adjustedRadius, maxSize); } From ab480f8f9fd825a0a0afbdd797ae3ddb790e469c Mon Sep 17 00:00:00 2001 From: "cesare.soldini" Date: Wed, 6 May 2020 12:01:03 +0200 Subject: [PATCH 17/43] Remove arcRatio, add gauge "type" --- packages/core/demo/data/gauge.ts | 4 ++-- packages/core/src/components/graphs/gauge.ts | 14 +++++++++++--- packages/core/src/interfaces/charts.ts | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/core/demo/data/gauge.ts b/packages/core/demo/data/gauge.ts index a26663c8bf..b4c42e16c1 100644 --- a/packages/core/demo/data/gauge.ts +++ b/packages/core/demo/data/gauge.ts @@ -9,7 +9,7 @@ export const gaugeOptionsSemi = { resizable: true, height: "250px", gauge: { - arcRatio: 0.5 + type: "semi" } }; @@ -18,6 +18,6 @@ export const gaugeOptionsCircular = { resizable: true, height: "250px", gauge: { - arcRatio: 1 + type: "full" } }; diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index 11dd50f3e3..a018492fd3 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -13,6 +13,11 @@ import { select } from "d3-selection"; import { arc } from "d3-shape"; import { interpolateNumber } from "d3-interpolate"; +const ARC_TYPES_RATIOS = { + semi: 0.5, + full: 1 +}; + export class Gauge extends Component { type = "gauge"; @@ -86,9 +91,12 @@ export class Gauge extends Component { getArcSize(): number { const options = this.model.getOptions(); - const { arcRatio = 1 } = options.gauge; - const clampedArcRatio = clamp(arcRatio, 0, 1); - return clampedArcRatio * Math.PI * 2; + const { type = "semi" } = options.gauge; + const arcRatio = ARC_TYPES_RATIOS[type]; + if (arcRatio === undefined) { + throw new Error("Gauge chart arc type not compatible"); + } + return arcRatio * Math.PI * 2; } getStartAngle(): number { diff --git a/packages/core/src/interfaces/charts.ts b/packages/core/src/interfaces/charts.ts index 6386d2b93e..4b4ea6d7da 100644 --- a/packages/core/src/interfaces/charts.ts +++ b/packages/core/src/interfaces/charts.ts @@ -187,7 +187,7 @@ export interface GaugeChartOptions extends PieChartOptions { valueYPosition?: Function; numberFormatter?: Function; }; - arcRatio?: number + type?: "semi" | "full" }; } From 3fbad51feda46456cd63b2347b5f4daae0bdee08 Mon Sep 17 00:00:00 2001 From: "cesare.soldini" Date: Wed, 6 May 2020 15:21:22 +0200 Subject: [PATCH 18/43] Fix sizing and centering of gauge chart --- packages/core/src/components/graphs/gauge.ts | 21 ++++++++++---------- packages/core/src/configuration.ts | 3 +++ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index a018492fd3..5d95af1d9c 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -139,30 +139,28 @@ export class Gauge extends Component { // Set the hover arc radius this.hoverArc = arc() .innerRadius(innerRadius) - .outerRadius(radius + options.pie.hoverArc.outerRadiusOffset) + .outerRadius(radius + options.gauge.hoverArc.outerRadiusOffset) .startAngle(startAngle) .endAngle(currentAngle); // Add background arc - DOMUtils.appendOrSelect(svg, "g.background") - .append("path") + DOMUtils.appendOrSelect(svg, "path.arc-background") .attr("d", this.backgroundArc) .attr("fill", "rgb(224,224,224)") .attr("role", Roles.GROUP); // Add data arc - DOMUtils.appendOrSelect(svg, "g.arc") - .append("path") + DOMUtils.appendOrSelect(svg, "path.arc-foreground") .data(datalist) .attr("d", this.arc) .classed("arc", true) .attr("fill", "rgb(88,134,247)"); - // Position Pie - const gaugeTranslateX = radius + options.pie.xOffset; - const gaugeTranslateY = radius + options.pie.yOffset; + // Position Arc + const gaugeTranslateX = radius + options.gauge.hoverArc.outerRadiusOffset; + const gaugeTranslateY = radius + options.gauge.hoverArc.outerRadiusOffset; svg.attr("transform", `translate(${gaugeTranslateX}, ${gaugeTranslateY})`); // Add the number shown in the center of the gauge and the delta @@ -312,11 +310,12 @@ export class Gauge extends Component { protected computeRadius() { const arcSize = this.getArcSize(); const options = this.model.getOptions(); - const multiplier = Math.min(Math.PI / arcSize, 1); const { width, height } = DOMUtils.getSVGElementSize(this.parent, { useAttrs: true }); - const radius: number = Math.min(width, height) * multiplier; + const radius = arcSize < 2 * Math.PI * (3 / 4) + ? Math.min(width / 2, height) + : Math.min(width / 2, height / 2); - return radius + options.pie.radiusOffset; + return radius - options.gauge.hoverArc.outerRadiusOffset; } } diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 52c4d8b998..00ae74ce0d 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -290,6 +290,9 @@ const gaugeChart: GaugeChartOptions = Tools.merge({}, pieChart, { return (deltaYPosition + valueYPosition); }, numberFormatter: number => number.toFixed(2).toLocaleString() + }, + hoverArc: { + outerRadiusOffset: 3 } } } as GaugeChartOptions); From 1e3529619146ae02d741bc73b38ff7f91f5c8939 Mon Sep 17 00:00:00 2001 From: "cesare.soldini" Date: Wed, 6 May 2020 15:21:43 +0200 Subject: [PATCH 19/43] Fix option typings for Gauge chart --- packages/core/src/interfaces/charts.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/core/src/interfaces/charts.ts b/packages/core/src/interfaces/charts.ts index 4b4ea6d7da..18540002b7 100644 --- a/packages/core/src/interfaces/charts.ts +++ b/packages/core/src/interfaces/charts.ts @@ -179,15 +179,21 @@ export interface PieChartOptions extends BaseChartOptions { */ export interface GaugeChartOptions extends PieChartOptions { gauge?: { - center?: { + arcWidth?: number; + distanceBetweenNumbers?: Function; + center: { + caretSize?: Function; valueFontSize?: Function; + percFontSize?: Function; deltaFontSize?: Function; titleFontSize?: Function; - deltaYPosition?: Function; valueYPosition?: Function; numberFormatter?: Function; }; - type?: "semi" | "full" + hoverArc?: { + outerRadiusOffset?: number; + }; + type?: "semi" | "full"; }; } From 0b7e6f148d040ab13f9a66aaf3cd8ddcf62dd5ce Mon Sep 17 00:00:00 2001 From: "cesare.soldini" Date: Wed, 6 May 2020 17:54:06 +0200 Subject: [PATCH 20/43] Reorganize all sizing and positioning calculations, Simplify data format --- packages/core/demo/data/gauge.ts | 5 +- packages/core/src/components/graphs/gauge.ts | 173 ++++++++----------- packages/core/src/configuration.ts | 20 +-- packages/core/src/interfaces/charts.ts | 11 +- 4 files changed, 73 insertions(+), 136 deletions(-) diff --git a/packages/core/demo/data/gauge.ts b/packages/core/demo/data/gauge.ts index b4c42e16c1..5803dcdc43 100644 --- a/packages/core/demo/data/gauge.ts +++ b/packages/core/demo/data/gauge.ts @@ -1,7 +1,6 @@ export const gaugeData = [ - { group: "Dataset", key: "current", value: 85 }, - { group: "Dataset", key: "old", value: 100 }, - { group: "Dataset", key: "total", value: 200 } + { group: "Dataset", key: "value", value: 42 }, + { group: "Dataset", key: "delta", value: -13.37 } ]; export const gaugeOptionsSemi = { diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index 5d95af1d9c..e4f543e804 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -38,65 +38,37 @@ export class Gauge extends Component { eventsFragment.addEventListener("legend-item-onmouseout", this.handleLegendMouseOut); } - getDataList() { + getValue(): number { const displayData = this.model.getDisplayData(); - const current = displayData.find(d => d.key === "current"); - const old = displayData.find(d => d.key === "old"); - const total = displayData.find(d => d.key === "total"); - return [ - { - data: { - group: "Dataset", - current: current ? current.value : 0, - total: total ? total.value : 0, - old: old ? old.value : 0, - value: current ? current.value : 0 - } - } - ]; + return displayData.find(d => d.key === "value").value; } - getCurrentRatio(): number { - const total = this.getTotal(); - const current = this.getCurrent(); - const ratio = total === 0 ? 0 : current / total; - return clamp(ratio, 0, 1); + getValueRatio(): number { + return this.getValue() / 100; } getDelta(): number { - const current = this.getCurrent(); - const old = this.getOld(); - const delta = current - old; - const ratio = old === 0 ? Infinity : delta / old; - return clamp(ratio, -1, Infinity); - } - - getTotal(): number { - const datalist = this.getDataList(); - const value = datalist[0].data.total || 0; - return value; - } - - getCurrent(): number { - const datalist = this.getDataList(); - const value = datalist[0].data.current || 0; - return value; - } - - getOld(): number { - const datalist = this.getDataList(); - const value = datalist[0].data.old || 0; - return value; + const displayData = this.model.getDisplayData(); + return displayData.find(d => d.key === "delta").value; } - getArcSize(): number { + getArcType() { const options = this.model.getOptions(); const { type = "semi" } = options.gauge; + return type; + } + + getArcRatio(): number { + const type = this.getArcType(); const arcRatio = ARC_TYPES_RATIOS[type]; if (arcRatio === undefined) { throw new Error("Gauge chart arc type not compatible"); } - return arcRatio * Math.PI * 2; + return arcRatio; + } + + getArcSize(): number { + return this.getArcRatio() * Math.PI * 2; } getStartAngle(): number { @@ -111,12 +83,13 @@ export class Gauge extends Component { const self = this; const svg = this.getContainerSVG(); const options = this.model.getOptions(); - const ratio = this.getCurrentRatio(); - const datalist = this.getDataList(); + const value = this.getValue(); + const valueRatio = this.getValueRatio(); const delta = this.getDelta(); const arcSize = this.getArcSize(); + const arcType = this.getArcType(); const startAngle = this.getStartAngle(); - const rotationAngle = ratio * arcSize; + const rotationAngle = valueRatio * arcSize; const currentAngle = startAngle + rotationAngle; const endAngle = startAngle + arcSize; @@ -124,6 +97,13 @@ export class Gauge extends Component { const radius = this.computeRadius(); const innerRadius = this.getInnerRadius(); + // Sizing and positions relative to the radius + const arrowSize = radius / 8; + const valueFontSize = radius / 2.5; + const deltaFontSize = radius / 8; + const distanceBetweenNumbers = 10; + const numbersYPosition = arcType === "semi" ? -(deltaFontSize + distanceBetweenNumbers) : 0; + this.backgroundArc = arc() .innerRadius(innerRadius) .outerRadius(radius) @@ -153,63 +133,62 @@ export class Gauge extends Component { // Add data arc DOMUtils.appendOrSelect(svg, "path.arc-foreground") - .data(datalist) .attr("d", this.arc) .classed("arc", true) .attr("fill", "rgb(88,134,247)"); // Position Arc - const gaugeTranslateX = radius + options.gauge.hoverArc.outerRadiusOffset; + const gaugeTranslateX = radius + options.gauge.hoverArc.outerRadiusOffset; // Leaves space for the hover animation const gaugeTranslateY = radius + options.gauge.hoverArc.outerRadiusOffset; svg.attr("transform", `translate(${gaugeTranslateX}, ${gaugeTranslateY})`); - // Add the number shown in the center of the gauge and the delta - // under it. + // Add the numbers at the center + const numbersG = DOMUtils.appendOrSelect(svg, "g.gauge-numbers") + .attr("transform", `translate(0, ${numbersYPosition})`); + + // Add the big number + const valueNumberG = DOMUtils.appendOrSelect(numbersG, "g.gauge-value-number"); - const gaugeText = DOMUtils - .appendOrSelect(svg, "text.gauge-value") + const valueNumber = DOMUtils.appendOrSelect(valueNumberG, "text.gauge-value-number") + .style("font-size", `${valueFontSize}px`) .attr("text-anchor", "middle") - .attr("alignment-baseline", "baseline"); - - DOMUtils.appendOrSelect(gaugeText, "tspan.gauge-value-number") - .style("font-size", () => `${options.gauge.center.valueFontSize(radius, arcSize)}px`) - .transition(this.services.transitions.getTransition("gauge-figure-enter-update", animate)) - .attr("y", options.gauge.center.valueYPosition(radius, arcSize)) - .tween("text", function() { - return self.centerNumberTween(select(this), ratio * 100); - }); + .text(`${options.gauge.numberFormatter(value)}`); - DOMUtils.appendOrSelect(gaugeText, "tspan.gauge-value-symbol") - .style("font-size", () => `${options.gauge.center.percFontSize(radius, arcSize)}px`) - .attr("dx", () => `-${options.gauge.center.valueFontSize(radius, arcSize)}`) - .attr("dy", () => `-${options.gauge.center.percFontSize(radius, arcSize)}`) - .attr("y", options.gauge.center.valueYPosition(radius, arcSize)) - .attr("alignment-baseline", "middle") + const { width: valueNumberWidth } = DOMUtils.getSVGElementSize(valueNumber, { useBBox: true }); + DOMUtils.appendOrSelect(valueNumberG, "text.gauge-value-symbol") + .style("font-size", `${valueFontSize / 2}px`) + .attr("x", valueNumberWidth / 2) .text("%"); - const gaugeDelta = DOMUtils.appendOrSelect(svg, "g.gauge-delta"); + console.log(DOMUtils.getSVGElementSize(valueNumber, { useBBox: true })) + setTimeout(() => console.log(DOMUtils.getSVGElementSize(valueNumber, { useBBox: true })), 1000) - const deltaArrow = DOMUtils.appendOrSelect(gaugeDelta, "svg.gauge-delta-arrow") - .attr("x", () => `-${options.gauge.center.valueFontSize(radius, arcSize) + options.gauge.center.caretSize(radius, arcSize) / 2}px`) - .attr( - "y", - `${options.gauge.center.valueYPosition(radius, arcSize) + options.gauge.distanceBetweenNumbers(radius, arcSize) + options.gauge.center.caretSize(radius, arcSize) / 4}px` - ) - .attr("width", `${options.gauge.center.caretSize(radius, arcSize)}px`) - .attr("height", `${options.gauge.center.caretSize(radius, arcSize)}px`) - .attr("viewBox", `0 0 16 16`); - - DOMUtils.appendOrSelect(deltaArrow, "polygon.gauge-delta-arrow-polygon") - .attr("points", () => delta > 0 ? "4 10 8 6 12 10" : "12 6 8 10 4 6") - .attr("fill", "rgb(224,224,224)"); + // Add the smaller number of the delta + const deltaNumberG = DOMUtils.appendOrSelect(numbersG, "g.gauge-delta") + .attr("transform", `translate(0, ${deltaFontSize + distanceBetweenNumbers})`); - DOMUtils.appendOrSelect(gaugeDelta, "text.gauge-delta-number") + const deltaNumber = DOMUtils.appendOrSelect(deltaNumberG, "text.gauge-delta-number") .attr("text-anchor", "middle") - .attr("dominant-baseline", "hanging") - .style("font-size", () => `${options.gauge.center.deltaFontSize(radius, arcSize)}px`) - .attr("y", `${options.gauge.center.valueYPosition(radius, arcSize) + options.gauge.distanceBetweenNumbers(radius, arcSize)}px`) - .text(() => `${(delta * 100).toFixed(2)}%`); + .style("font-size", `${deltaFontSize}px`) + .text(`${options.gauge.numberFormatter(delta)}%`); + + const { width: deltaNumberWidth } = DOMUtils.getSVGElementSize(deltaNumber, { useBBox: true }); + const deltaArrow = DOMUtils.appendOrSelect(deltaNumberG, "svg.gauge-delta-arrow") + .attr("x", -arrowSize - deltaNumberWidth / 2) + .attr("y", -arrowSize / 2 - deltaFontSize * 0.35) + .attr("width", arrowSize) + .attr("height", arrowSize) + .attr("viewBox", `0 0 16 16`); + const ARROW_UP = "4,10 8,6 12,10"; + const ARROW_DOWN = "12,6 8,10 4,6"; + DOMUtils.appendOrSelect(deltaArrow, "rect.gauge-delta-arrow-backdrop") // Needed to correctly size SVG in Firefox + .attr("width", `16`) + .attr("height", `16`) + .attr("fill", "none"); + DOMUtils.appendOrSelect(deltaArrow, "polygon.gauge-delta-arrow-polygon") + .attr("points", delta > 0 ? ARROW_UP : ARROW_DOWN) + .attr("fill", "currentColor"); // Add event listeners this.addEventListeners(); @@ -223,20 +202,6 @@ export class Gauge extends Component { return radius - options.gauge.arcWidth; } - centerNumberTween(d3Ref, value: number) { - const options = this.model.getOptions(); - // Remove commas from the current value string, and convert to an int - const currentValue = parseInt(d3Ref.text().replace(/[, ]+/g, ""), 10) || 0; - const i = interpolateNumber(currentValue, value); - - return t => { - const { numberFormatter } = options.gauge.center; - const number = i(t); - const formattedNumber = numberFormatter(number); - return d3Ref.text(formattedNumber); - }; - } - // Highlight elements that match the hovered legend item handleLegendOnHover = (event: CustomEvent) => { const { hoveredElement } = event.detail; @@ -308,11 +273,11 @@ export class Gauge extends Component { // Helper functions protected computeRadius() { - const arcSize = this.getArcSize(); + const arcType = this.getArcType(); const options = this.model.getOptions(); const { width, height } = DOMUtils.getSVGElementSize(this.parent, { useAttrs: true }); - const radius = arcSize < 2 * Math.PI * (3 / 4) + const radius = arcType === "semi" ? Math.min(width / 2, height) : Math.min(width / 2, height / 2); diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 00ae74ce0d..766bf7f455 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -266,31 +266,13 @@ const pieChart: PieChartOptions = Tools.merge({}, chart, { * options specific to gauge charts */ -function getGaugePartSize(radius: number, arcSize: number, maxSize: number) { - const adjustedRadius = (radius * Math.PI / arcSize) / 10; - return Tools.interpolateAndClamp(adjustedRadius, maxSize); -} - const gaugeChart: GaugeChartOptions = Tools.merge({}, pieChart, { legend: { enabled: false }, gauge: { arcWidth: 16, - distanceBetweenNumbers: (radius, arcSize) => getGaugePartSize(radius, arcSize, radius / 12), - center: { - caretSize: (radius, arcSize) => getGaugePartSize(radius, arcSize, radius / 12), - valueFontSize: (radius, arcSize) => getGaugePartSize(radius, arcSize, radius / 4), - percFontSize: (radius, arcSize) => getGaugePartSize(radius, arcSize, radius / 8), - deltaFontSize: (radius, arcSize) => getGaugePartSize(radius, arcSize, radius / 8), - titleFontSize: radius => Tools.interpolateAndClamp((radius / 100), radius / 12), - valueYPosition: (radius, arcSize) => { - const deltaYPosition = ((arcSize - 2 * Math.PI) / Math.PI) * getGaugePartSize(radius, arcSize, radius / 8); - const valueYPosition = ((arcSize - 2 * Math.PI) / Math.PI) * getGaugePartSize(radius, arcSize, radius / 4); - return (deltaYPosition + valueYPosition); - }, - numberFormatter: number => number.toFixed(2).toLocaleString() - }, + numberFormatter: number => number.toFixed(2).toLocaleString(), hoverArc: { outerRadiusOffset: 3 } diff --git a/packages/core/src/interfaces/charts.ts b/packages/core/src/interfaces/charts.ts index 18540002b7..0b0df12c48 100644 --- a/packages/core/src/interfaces/charts.ts +++ b/packages/core/src/interfaces/charts.ts @@ -180,16 +180,7 @@ export interface PieChartOptions extends BaseChartOptions { export interface GaugeChartOptions extends PieChartOptions { gauge?: { arcWidth?: number; - distanceBetweenNumbers?: Function; - center: { - caretSize?: Function; - valueFontSize?: Function; - percFontSize?: Function; - deltaFontSize?: Function; - titleFontSize?: Function; - valueYPosition?: Function; - numberFormatter?: Function; - }; + numberFormatter?: Function; hoverArc?: { outerRadiusOffset?: number; }; From df69bc3443ce61b1c7dc61de36adef5e6c3307b6 Mon Sep 17 00:00:00 2001 From: "cesare.soldini" Date: Wed, 6 May 2020 18:08:51 +0200 Subject: [PATCH 21/43] Make Gauge colors customizable from options --- packages/core/demo/data/gauge.ts | 1 + packages/core/src/components/graphs/gauge.ts | 14 ++++---------- packages/core/src/configuration.ts | 2 ++ packages/core/src/interfaces/charts.ts | 5 ++++- packages/core/src/interfaces/enums.ts | 5 +++++ 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/packages/core/demo/data/gauge.ts b/packages/core/demo/data/gauge.ts index 5803dcdc43..f5e15b2b65 100644 --- a/packages/core/demo/data/gauge.ts +++ b/packages/core/demo/data/gauge.ts @@ -7,6 +7,7 @@ export const gaugeOptionsSemi = { title: "Gauge semicircular", resizable: true, height: "250px", + width: "400px", gauge: { type: "semi" } diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index e4f543e804..13ab0a501b 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -1,17 +1,11 @@ // Internal Imports import { Component } from "../component"; import { DOMUtils } from "../../services"; -import { clamp, groupBy } from "lodash-es"; -import { - Roles, - TooltipTypes, - Events -} from "../../interfaces"; +import { Roles, TooltipTypes, Events, GaugeTypes } from "../../interfaces"; // D3 Imports import { select } from "d3-selection"; import { arc } from "d3-shape"; -import { interpolateNumber } from "d3-interpolate"; const ARC_TYPES_RATIOS = { semi: 0.5, @@ -52,7 +46,7 @@ export class Gauge extends Component { return displayData.find(d => d.key === "delta").value; } - getArcType() { + getArcType(): GaugeTypes { const options = this.model.getOptions(); const { type = "semi" } = options.gauge; return type; @@ -127,7 +121,7 @@ export class Gauge extends Component { DOMUtils.appendOrSelect(svg, "path.arc-background") .attr("d", this.backgroundArc) - .attr("fill", "rgb(224,224,224)") + .attr("fill", options.gauge.arcBackgroundColor) .attr("role", Roles.GROUP); // Add data arc @@ -135,7 +129,7 @@ export class Gauge extends Component { DOMUtils.appendOrSelect(svg, "path.arc-foreground") .attr("d", this.arc) .classed("arc", true) - .attr("fill", "rgb(88,134,247)"); + .attr("fill", options.gauge.arcForegroundColor); // Position Arc const gaugeTranslateX = radius + options.gauge.hoverArc.outerRadiusOffset; // Leaves space for the hover animation diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 766bf7f455..1798713e7d 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -272,6 +272,8 @@ const gaugeChart: GaugeChartOptions = Tools.merge({}, pieChart, { }, gauge: { arcWidth: 16, + arcBackgroundColor: `rgb(224,224,224)`, + arcForegroundColor: `rgb(88,134,247)`, numberFormatter: number => number.toFixed(2).toLocaleString(), hoverArc: { outerRadiusOffset: 3 diff --git a/packages/core/src/interfaces/charts.ts b/packages/core/src/interfaces/charts.ts index 0b0df12c48..cc8eb0f562 100644 --- a/packages/core/src/interfaces/charts.ts +++ b/packages/core/src/interfaces/charts.ts @@ -1,5 +1,6 @@ import { LegendOptions, TooltipOptions, GridOptions, AxesOptions } from "./index"; import { AxisTooltipOptions, BarTooltipOptions, BarOptions, StackedBarOptions } from "./components"; +import { GaugeTypes } from "./enums"; /** * Base chart options common to any chart @@ -180,11 +181,13 @@ export interface PieChartOptions extends BaseChartOptions { export interface GaugeChartOptions extends PieChartOptions { gauge?: { arcWidth?: number; + arcBackgroundColor?: string, + arcForegroundColor?: string, numberFormatter?: Function; hoverArc?: { outerRadiusOffset?: number; }; - type?: "semi" | "full"; + type?: GaugeTypes; }; } diff --git a/packages/core/src/interfaces/enums.ts b/packages/core/src/interfaces/enums.ts index 7416ca237d..28b704d91f 100644 --- a/packages/core/src/interfaces/enums.ts +++ b/packages/core/src/interfaces/enums.ts @@ -104,3 +104,8 @@ export enum CalloutDirections { LEFT = "left", RIGHT = "right" } + +export enum GaugeTypes { + SEMI = "semi", + FULL = "full" +} From fb45953898cb5f18b89fe91123ff810a17c9bd30 Mon Sep 17 00:00:00 2001 From: "cesare.soldini" Date: Wed, 6 May 2020 18:17:36 +0200 Subject: [PATCH 22/43] Gauge: Optical centering of the center number for the presence of the % small symbol --- packages/core/src/components/graphs/gauge.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index 13ab0a501b..a41390fdc0 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -141,7 +141,8 @@ export class Gauge extends Component { .attr("transform", `translate(0, ${numbersYPosition})`); // Add the big number - const valueNumberG = DOMUtils.appendOrSelect(numbersG, "g.gauge-value-number"); + const valueNumberG = DOMUtils.appendOrSelect(numbersG, "g.gauge-value-number") + .attr("transform", `translate(-10, 0)`); // Optical centering for the presence of the smaller % symbol const valueNumber = DOMUtils.appendOrSelect(valueNumberG, "text.gauge-value-number") .style("font-size", `${valueFontSize}px`) From cb9f0c7a5927abc8bb9405f33b391f04bad9ec83 Mon Sep 17 00:00:00 2001 From: "cesare.soldini" Date: Wed, 6 May 2020 18:17:56 +0200 Subject: [PATCH 23/43] Gauge: Add configuration option for arrow color --- packages/core/demo/data/gauge.ts | 6 ++++-- packages/core/src/components/graphs/gauge.ts | 2 +- packages/core/src/configuration.ts | 1 + packages/core/src/interfaces/charts.ts | 5 +++-- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/core/demo/data/gauge.ts b/packages/core/demo/data/gauge.ts index f5e15b2b65..c0ffd0c31b 100644 --- a/packages/core/demo/data/gauge.ts +++ b/packages/core/demo/data/gauge.ts @@ -9,7 +9,8 @@ export const gaugeOptionsSemi = { height: "250px", width: "400px", gauge: { - type: "semi" + type: "semi", + arrowColor: "tomato" } }; @@ -18,6 +19,7 @@ export const gaugeOptionsCircular = { resizable: true, height: "250px", gauge: { - type: "full" + type: "full", + arrowColor: "tomato" } }; diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index a41390fdc0..cfa5941d7c 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -183,7 +183,7 @@ export class Gauge extends Component { .attr("fill", "none"); DOMUtils.appendOrSelect(deltaArrow, "polygon.gauge-delta-arrow-polygon") .attr("points", delta > 0 ? ARROW_UP : ARROW_DOWN) - .attr("fill", "currentColor"); + .attr("fill", options.gauge.arrowColor); // Add event listeners this.addEventListeners(); diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 1798713e7d..4d3ef5d997 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -274,6 +274,7 @@ const gaugeChart: GaugeChartOptions = Tools.merge({}, pieChart, { arcWidth: 16, arcBackgroundColor: `rgb(224,224,224)`, arcForegroundColor: `rgb(88,134,247)`, + arrowColor: `currentColor`, numberFormatter: number => number.toFixed(2).toLocaleString(), hoverArc: { outerRadiusOffset: 3 diff --git a/packages/core/src/interfaces/charts.ts b/packages/core/src/interfaces/charts.ts index cc8eb0f562..91ec1b7c84 100644 --- a/packages/core/src/interfaces/charts.ts +++ b/packages/core/src/interfaces/charts.ts @@ -181,8 +181,9 @@ export interface PieChartOptions extends BaseChartOptions { export interface GaugeChartOptions extends PieChartOptions { gauge?: { arcWidth?: number; - arcBackgroundColor?: string, - arcForegroundColor?: string, + arcBackgroundColor?: string; + arcForegroundColor?: string; + arrowColor?: string; numberFormatter?: Function; hoverArc?: { outerRadiusOffset?: number; From a6e666de3f84ca936f17ee77dede6470787d6e47 Mon Sep 17 00:00:00 2001 From: "cesare.soldini" Date: Wed, 6 May 2020 18:26:43 +0200 Subject: [PATCH 24/43] Gauge type is now defaulted in configuration.ts --- packages/core/src/components/graphs/gauge.ts | 18 +++++++++--------- packages/core/src/configuration.ts | 4 +++- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index cfa5941d7c..59ba1ab6c6 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -48,7 +48,7 @@ export class Gauge extends Component { getArcType(): GaugeTypes { const options = this.model.getOptions(); - const { type = "semi" } = options.gauge; + const { type } = options.gauge; return type; } @@ -96,7 +96,7 @@ export class Gauge extends Component { const valueFontSize = radius / 2.5; const deltaFontSize = radius / 8; const distanceBetweenNumbers = 10; - const numbersYPosition = arcType === "semi" ? -(deltaFontSize + distanceBetweenNumbers) : 0; + const numbersYPosition = arcType === GaugeTypes.SEMI ? -(deltaFontSize + distanceBetweenNumbers) : 0; this.backgroundArc = arc() .innerRadius(innerRadius) @@ -155,8 +155,8 @@ export class Gauge extends Component { .attr("x", valueNumberWidth / 2) .text("%"); - console.log(DOMUtils.getSVGElementSize(valueNumber, { useBBox: true })) - setTimeout(() => console.log(DOMUtils.getSVGElementSize(valueNumber, { useBBox: true })), 1000) + console.log(DOMUtils.getSVGElementSize(valueNumber, { useBBox: true })); + setTimeout(() => console.log(DOMUtils.getSVGElementSize(valueNumber, { useBBox: true })), 1000); // Add the smaller number of the delta const deltaNumberG = DOMUtils.appendOrSelect(numbersG, "g.gauge-delta") @@ -216,14 +216,14 @@ export class Gauge extends Component { addEventListeners() { const self = this; this.parent.selectAll("path.arc") - .on("mouseover", function (datum) { + .on("mouseover", function(datum) { // Dispatch mouse event self.services.events.dispatchEvent(Events.Gauge.ARC_MOUSEOVER, { element: select(this), datum }); }) - .on("mousemove", function (datum) { + .on("mousemove", function(datum) { const hoveredElement = select(this); hoveredElement.classed("hovered", true) @@ -242,14 +242,14 @@ export class Gauge extends Component { type: TooltipTypes.DATAPOINT }); }) - .on("click", function (datum) { + .on("click", function(datum) { // Dispatch mouse event self.services.events.dispatchEvent(Events.Gauge.ARC_CLICK, { element: select(this), datum }); }) - .on("mouseout", function (datum) { + .on("mouseout", function(datum) { const hoveredElement = select(this); hoveredElement.classed("hovered", false) .transition(self.services.transitions.getTransition("gauge_slice_mouseover")) @@ -272,7 +272,7 @@ export class Gauge extends Component { const options = this.model.getOptions(); const { width, height } = DOMUtils.getSVGElementSize(this.parent, { useAttrs: true }); - const radius = arcType === "semi" + const radius = arcType === GaugeTypes.SEMI ? Math.min(width / 2, height) : Math.min(width / 2, height / 2); diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 4d3ef5d997..af842150af 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -19,7 +19,8 @@ import { BarTooltipOptions, LegendOptions, LegendPositions, - StackedBarOptions + StackedBarOptions, + GaugeTypes } from "./interfaces"; import enUSLocaleObject from "date-fns/locale/en-US/index"; @@ -271,6 +272,7 @@ const gaugeChart: GaugeChartOptions = Tools.merge({}, pieChart, { enabled: false }, gauge: { + type: GaugeTypes.SEMI, arcWidth: 16, arcBackgroundColor: `rgb(224,224,224)`, arcForegroundColor: `rgb(88,134,247)`, From dbc6d63c470ccd407d995cde3e848844f264d33b Mon Sep 17 00:00:00 2001 From: "cesare.soldini" Date: Wed, 6 May 2020 18:36:51 +0200 Subject: [PATCH 25/43] Fixed data format, removed tooltip service --- packages/core/demo/data/gauge.ts | 4 ++-- packages/core/src/charts/gauge.ts | 1 - packages/core/src/components/graphs/gauge.ts | 8 ++++---- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/core/demo/data/gauge.ts b/packages/core/demo/data/gauge.ts index c0ffd0c31b..7b51ce9c36 100644 --- a/packages/core/demo/data/gauge.ts +++ b/packages/core/demo/data/gauge.ts @@ -1,6 +1,6 @@ export const gaugeData = [ - { group: "Dataset", key: "value", value: 42 }, - { group: "Dataset", key: "delta", value: -13.37 } + { group: "value", value: 42 }, + { group: "delta", value: -13.37 } ]; export const gaugeOptionsSemi = { diff --git a/packages/core/src/charts/gauge.ts b/packages/core/src/charts/gauge.ts index c906a8481f..29df248d92 100644 --- a/packages/core/src/charts/gauge.ts +++ b/packages/core/src/charts/gauge.ts @@ -38,7 +38,6 @@ export class GaugeChart extends PieChart { ]; const components: any[] = this.getChartComponents(graphFrameComponents); - components.push(new TooltipPie(this.model, this.services)); return components; } } diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index 59ba1ab6c6..595e63c677 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -33,8 +33,8 @@ export class Gauge extends Component { } getValue(): number { - const displayData = this.model.getDisplayData(); - return displayData.find(d => d.key === "value").value; + const data = this.model.getData(); + return data.find(d => d.group === "value").value; } getValueRatio(): number { @@ -42,8 +42,8 @@ export class Gauge extends Component { } getDelta(): number { - const displayData = this.model.getDisplayData(); - return displayData.find(d => d.key === "delta").value; + const data = this.model.getData(); + return data.find(d => d.group === "delta").value; } getArcType(): GaugeTypes { From 80696c298ca040d57855fd02fe2d7e8fc0b40e55 Mon Sep 17 00:00:00 2001 From: "cesare.soldini" Date: Wed, 6 May 2020 18:50:06 +0200 Subject: [PATCH 26/43] Gauge: Clamp the arc at 100% --- packages/core/src/components/graphs/gauge.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index 595e63c677..bbaea6c71e 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -2,6 +2,7 @@ import { Component } from "../component"; import { DOMUtils } from "../../services"; import { Roles, TooltipTypes, Events, GaugeTypes } from "../../interfaces"; +import { Tools } from "../../tools"; // D3 Imports import { select } from "d3-selection"; @@ -38,7 +39,8 @@ export class Gauge extends Component { } getValueRatio(): number { - return this.getValue() / 100; + const value = Tools.clamp(this.getValue(), 0, 100); + return value / 100; } getDelta(): number { From dc9c922154696779e0d0ab2d50e86de4b66a0b49 Mon Sep 17 00:00:00 2001 From: Natasha DeCoste Date: Tue, 19 May 2020 09:56:30 -0400 Subject: [PATCH 27/43] Revert "Update CHANGELOG.md" This reverts commit cce62aa779b97e571d93b3811d5fe96f8cc92bb1. --- CHANGELOG.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8dc1fba206..4ddf64dad6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,26 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.30.24](https://github.com/IBM/carbon-charts/compare/v0.30.23...v0.30.24) (2020-05-15) + +**Note:** Version bump only for package @carbon/charts-monorepo + + + + + +## [0.30.23](https://github.com/IBM/carbon-charts/compare/v0.30.22...v0.30.23) (2020-05-13) + +**Note:** Version bump only for package @carbon/charts-monorepo + + + + + +## [0.30.22](https://github.com/IBM/carbon-charts/compare/v0.30.21...v0.30.22) (2020-05-13) + +**Note:** Version bump only for package @carbon/charts-monorepo + ## [0.30.21](https://github.com/IBM/carbon-charts/compare/v0.30.20...v0.30.21) (2020-05-11) **Note:** Version bump only for package @carbon/charts-monorepo From f80f87c8f8c9a44c8d30540115d0095e790d0f86 Mon Sep 17 00:00:00 2001 From: Natasha DeCoste Date: Wed, 20 May 2020 11:35:21 -0400 Subject: [PATCH 28/43] remove changelog diff --- CHANGELOG.md | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d39e59ebc..7f0eff5470 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,26 +5,6 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline ## [0.30.24](https://github.com/IBM/carbon-charts/compare/v0.30.23...v0.30.24) (2020-05-15) -**Note:** Version bump only for package @carbon/charts-monorepo - - - - - -## [0.30.23](https://github.com/IBM/carbon-charts/compare/v0.30.22...v0.30.23) (2020-05-13) - -**Note:** Version bump only for package @carbon/charts-monorepo - - - - - -## [0.30.22](https://github.com/IBM/carbon-charts/compare/v0.30.21...v0.30.22) (2020-05-13) - -**Note:** Version bump only for package @carbon/charts-monorepo - -## [0.30.21](https://github.com/IBM/carbon-charts/compare/v0.30.20...v0.30.21) (2020-05-11) - * **core:** replace carbon-components update to use es modules * **core:** README updates From 4a25051c9f2077304e4046201610a167c046212d Mon Sep 17 00:00:00 2001 From: Natasha DeCoste Date: Mon, 1 Jun 2020 10:28:10 -0400 Subject: [PATCH 29/43] update guage --- packages/core/CHANGELOG.md | 18 +- packages/core/demo/data/area.ts | 66 ++-- packages/core/demo/data/index.ts | 12 +- packages/core/src/charts/gauge.ts | 9 +- packages/core/src/components/graphs/area.ts | 39 ++- packages/core/src/components/graphs/gauge.ts | 136 +++++--- packages/core/src/components/graphs/line.ts | 2 +- packages/core/src/configuration.ts | 138 ++++---- packages/core/src/interfaces/charts.ts | 9 +- packages/core/src/interfaces/enums.ts | 3 +- packages/core/src/interfaces/events.ts | 2 +- packages/core/src/tools.ts | 31 +- packages/vue/CHANGELOG.md | 344 +------------------ packages/vue/src/ccv-area-chart.vue | 4 +- 14 files changed, 262 insertions(+), 551 deletions(-) diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index f3b88d85af..8801bd93d7 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -5,27 +5,17 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline # [0.32.0](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.24...v0.32.0) (2020-05-29) - ### Bug Fixes -* **core:** threshold - support non JS-date values ([a132497](https://github.com/carbon-design-system/carbon-charts/commit/a1324972fa5266151b490cb7eeed92a92da5b2c4)) -* **svelte:** copy svelte source to dist/src ([492a504](https://github.com/carbon-design-system/carbon-charts/commit/492a50470d2b64793bd2c67c4115bb2732bc44f7)) - - - - +- **core:** threshold - support non JS-date values ([a132497](https://github.com/carbon-design-system/carbon-charts/commit/a1324972fa5266151b490cb7eeed92a92da5b2c4)) +- **svelte:** copy svelte source to dist/src ([492a504](https://github.com/carbon-design-system/carbon-charts/commit/492a50470d2b64793bd2c67c4115bb2732bc44f7)) # [0.31.0](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.24...v0.31.0) (2020-05-29) - ### Bug Fixes -* **core:** threshold - support non JS-date values ([a132497](https://github.com/carbon-design-system/carbon-charts/commit/a1324972fa5266151b490cb7eeed92a92da5b2c4)) -* **svelte:** copy svelte source to dist/src ([492a504](https://github.com/carbon-design-system/carbon-charts/commit/492a50470d2b64793bd2c67c4115bb2732bc44f7)) - - - - +- **core:** threshold - support non JS-date values ([a132497](https://github.com/carbon-design-system/carbon-charts/commit/a1324972fa5266151b490cb7eeed92a92da5b2c4)) +- **svelte:** copy svelte source to dist/src ([492a504](https://github.com/carbon-design-system/carbon-charts/commit/492a50470d2b64793bd2c67c4115bb2732bc44f7)) ## [0.30.24](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.23...v0.30.24) (2020-05-15) diff --git a/packages/core/demo/data/area.ts b/packages/core/demo/data/area.ts index 9c55b2a468..951342bff5 100644 --- a/packages/core/demo/data/area.ts +++ b/packages/core/demo/data/area.ts @@ -1,19 +1,19 @@ export const areaTimeSeriesData = [ - { group: "Dataset 1", date: new Date(2019, 0, 1), value: 0 }, - { group: "Dataset 1", date: new Date(2019, 0, 6), value: 57312 }, - { group: "Dataset 1", date: new Date(2019, 0, 8), value: 21432 }, - { group: "Dataset 1", date: new Date(2019, 0, 15), value: 70323 }, - { group: "Dataset 1", date: new Date(2019, 0, 19), value: 21300 }, - { group: "Dataset 2", date: new Date(2019, 0, 1), value: 50000 }, - { group: "Dataset 2", date: new Date(2019, 0, 5), value: 15000 }, - { group: "Dataset 2", date: new Date(2019, 0, 8), value: 20000 }, - { group: "Dataset 2", date: new Date(2019, 0, 13), value: 39213 }, - { group: "Dataset 2", date: new Date(2019, 0, 19), value: 61213 }, - { group: "Dataset 3", date: new Date(2019, 0, 2), value: 10 }, - { group: "Dataset 3", date: new Date(2019, 0, 6), value: 37312 }, - { group: "Dataset 3", date: new Date(2019, 0, 8), value: 51432 }, - { group: "Dataset 3", date: new Date(2019, 0, 13), value: 40323 }, - { group: "Dataset 3", date: new Date(2019, 0, 19), value: 31300 } + { group: "Dataset 1", date: new Date(2019, 0, 1), value: 0 }, + { group: "Dataset 1", date: new Date(2019, 0, 6), value: 57312 }, + { group: "Dataset 1", date: new Date(2019, 0, 8), value: 21432 }, + { group: "Dataset 1", date: new Date(2019, 0, 15), value: 70323 }, + { group: "Dataset 1", date: new Date(2019, 0, 19), value: 21300 }, + { group: "Dataset 2", date: new Date(2019, 0, 1), value: 50000 }, + { group: "Dataset 2", date: new Date(2019, 0, 5), value: 15000 }, + { group: "Dataset 2", date: new Date(2019, 0, 8), value: 20000 }, + { group: "Dataset 2", date: new Date(2019, 0, 13), value: 39213 }, + { group: "Dataset 2", date: new Date(2019, 0, 19), value: 61213 }, + { group: "Dataset 3", date: new Date(2019, 0, 2), value: 10 }, + { group: "Dataset 3", date: new Date(2019, 0, 6), value: 37312 }, + { group: "Dataset 3", date: new Date(2019, 0, 8), value: 51432 }, + { group: "Dataset 3", date: new Date(2019, 0, 13), value: 40323 }, + { group: "Dataset 3", date: new Date(2019, 0, 19), value: 31300 }, ]; export const areaTimeSeriesOptions = { @@ -22,27 +22,27 @@ export const areaTimeSeriesOptions = { bottom: { title: "2019 Annual Sales Figures", mapsTo: "date", - scaleType: "time" + scaleType: "time", }, left: { mapsTo: "value", title: "Conversion rate", - scaleType: "linear" - } - } + scaleType: "linear", + }, + }, }; export const areaTimeSeriesCurvedData = [ - { group: "Dataset 1", date: new Date(2019, 0, 1), value: 0 }, - { group: "Dataset 1", date: new Date(2019, 0, 6), value: -37312 }, - { group: "Dataset 1", date: new Date(2019, 0, 8), value: -22392 }, - { group: "Dataset 1", date: new Date(2019, 0, 15), value: -52576 }, - { group: "Dataset 1", date: new Date(2019, 0, 19), value: 20135 }, - { group: "Dataset 2", date: new Date(2019, 0, 1), value: 47263 }, - { group: "Dataset 2", date: new Date(2019, 0, 5), value: 14178 }, - { group: "Dataset 2", date: new Date(2019, 0, 8), value: 23094 }, - { group: "Dataset 2", date: new Date(2019, 0, 13), value: 45281 }, - { group: "Dataset 2", date: new Date(2019, 0, 19), value: -63954 } + { group: "Dataset 1", date: new Date(2019, 0, 1), value: 0 }, + { group: "Dataset 1", date: new Date(2019, 0, 6), value: -37312 }, + { group: "Dataset 1", date: new Date(2019, 0, 8), value: -22392 }, + { group: "Dataset 1", date: new Date(2019, 0, 15), value: -52576 }, + { group: "Dataset 1", date: new Date(2019, 0, 19), value: 20135 }, + { group: "Dataset 2", date: new Date(2019, 0, 1), value: 47263 }, + { group: "Dataset 2", date: new Date(2019, 0, 5), value: 14178 }, + { group: "Dataset 2", date: new Date(2019, 0, 8), value: 23094 }, + { group: "Dataset 2", date: new Date(2019, 0, 13), value: 45281 }, + { group: "Dataset 2", date: new Date(2019, 0, 19), value: -63954 }, ]; export const areaTimeSeriesCurvedOptions = { @@ -51,12 +51,12 @@ export const areaTimeSeriesCurvedOptions = { bottom: { title: "2019 Annual Sales Figures", mapsTo: "date", - scaleType: "time" + scaleType: "time", }, left: { mapsTo: "value", - scaleType: "linear" - } + scaleType: "linear", + }, }, - curve: "curveNatural" + curve: "curveNatural", }; diff --git a/packages/core/demo/data/index.ts b/packages/core/demo/data/index.ts index d0b16f4142..f753278828 100644 --- a/packages/core/demo/data/index.ts +++ b/packages/core/demo/data/index.ts @@ -76,7 +76,7 @@ export const chartTypes = { GaugeChart: { vanilla: "GaugeChart", angular: "ibm-gauge-chart", - vue: "ccv-gauge-chart" + vue: "ccv-gauge-chart", }, DonutChart: { vanilla: "DonutChart", @@ -395,15 +395,15 @@ let allDemoGroups = [ options: gaugeDemos.gaugeOptionsSemi, data: gaugeDemos.gaugeData, chartType: chartTypes.GaugeChart, - isDemoExample: true + isDemoExample: true, }, { options: gaugeDemos.gaugeOptionsCircular, data: gaugeDemos.gaugeData, chartType: chartTypes.GaugeChart, - isDemoExample: true - } - ] + isDemoExample: true, + }, + ], }, { title: "Scatter", @@ -630,7 +630,7 @@ export const storybookDemoGroups = Tools.clone(allDemoGroups); // in the demo page we want to show only demos with isDemoExample = true export const demoGroups = Tools.clone(allDemoGroups) .map((demoGroup) => { - demoGroup.demos = demoGroup.demos.filter(demo => demo.isDemoExample); + demoGroup.demos = demoGroup.demos.filter((demo) => demo.isDemoExample); return demoGroup; }) .filter((demoGroup) => demoGroup.demos.length); // remove demoGroup if it's children are all with isDemoExample = false diff --git a/packages/core/src/charts/gauge.ts b/packages/core/src/charts/gauge.ts index 29df248d92..df482b446b 100644 --- a/packages/core/src/charts/gauge.ts +++ b/packages/core/src/charts/gauge.ts @@ -1,10 +1,7 @@ // Internal Imports import { PieChart } from "./pie"; import * as Configuration from "../configuration"; -import { - ChartConfig, - GaugeChartOptions, -} from "../interfaces/index"; +import { ChartConfig, GaugeChartOptions } from "../interfaces/index"; import { Tools } from "../tools"; // Components @@ -33,9 +30,7 @@ export class GaugeChart extends PieChart { getComponents() { // Specify what to render inside the graph-frame - const graphFrameComponents = [ - new Gauge(this.model, this.services) - ]; + const graphFrameComponents = [new Gauge(this.model, this.services)]; const components: any[] = this.getChartComponents(graphFrameComponents); return components; diff --git a/packages/core/src/components/graphs/area.ts b/packages/core/src/components/graphs/area.ts index 7b1bf9d6e6..cd94376aaf 100644 --- a/packages/core/src/components/graphs/area.ts +++ b/packages/core/src/components/graphs/area.ts @@ -10,7 +10,6 @@ export class Area extends Component { type = "area"; init() { - const eventsFragment = this.services.events; // Highlight correct area on legend item hovers @@ -31,48 +30,52 @@ export class Area extends Component { const { cartesianScales } = this.services; const orientation = cartesianScales.getOrientation(); - const areaGenerator = area() - .curve(this.services.curves.getD3Curve()); + const areaGenerator = area().curve(this.services.curves.getD3Curve()); if (orientation === CartesianOrientations.VERTICAL) { - areaGenerator.x((d, i) => cartesianScales.getDomainValue(d, i)) + areaGenerator + .x((d, i) => cartesianScales.getDomainValue(d, i)) .y0(cartesianScales.getRangeValue(0)) .y1((d, i) => cartesianScales.getRangeValue(d, i)); } else { - areaGenerator.x0(cartesianScales.getRangeValue(0)) + areaGenerator + .x0(cartesianScales.getRangeValue(0)) .x1((d, i) => cartesianScales.getRangeValue(d, i)) .y((d, i) => cartesianScales.getDomainValue(d, i)); } // Update the bound data on area groups const groupedData = this.model.getGroupedData(); - const areas = svg.selectAll("path.area") - .data(groupedData, group => group.name); + const areas = svg + .selectAll("path.area") + .data(groupedData, (group) => group.name); // Remove elements that need to be exited // We need exit at the top here to make sure that // Data filters are processed before entering new elements // Or updating existing ones - areas.exit() - .attr("opacity", 0) - .remove(); + areas.exit().attr("opacity", 0).remove(); const self = this; // Enter paths that need to be introduced - const enteringAreas = areas.enter() - .append("path") - .attr("opacity", 0); + const enteringAreas = areas.enter().append("path").attr("opacity", 0); // Apply styles and datum - enteringAreas.merge(areas) - .attr("fill", group => { - return this.model.getFillColor(group.name) + enteringAreas + .merge(areas) + .attr("fill", (group) => { + return this.model.getFillColor(group.name); }) - .transition(this.services.transitions.getTransition("area-update-enter", animate)) + .transition( + this.services.transitions.getTransition( + "area-update-enter", + animate + ) + ) .attr("opacity", Configuration.area.opacity.selected) .attr("class", "area") - .attr("d", group => { + .attr("d", (group) => { const { data } = group; return areaGenerator(data); }); diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index bbaea6c71e..f80bece34b 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -27,15 +27,21 @@ export class Gauge extends Component { const eventsFragment = this.services.events; // Highlight correct circle on legend item hovers - eventsFragment.addEventListener("legend-item-onhover", this.handleLegendOnHover); + eventsFragment.addEventListener( + "legend-item-onhover", + this.handleLegendOnHover + ); // Un-highlight circles on legend item mouseouts - eventsFragment.addEventListener("legend-item-onmouseout", this.handleLegendMouseOut); + eventsFragment.addEventListener( + "legend-item-onmouseout", + this.handleLegendMouseOut + ); } getValue(): number { const data = this.model.getData(); - return data.find(d => d.group === "value").value; + return data.find((d) => d.group === "value").value; } getValueRatio(): number { @@ -45,7 +51,7 @@ export class Gauge extends Component { getDelta(): number { const data = this.model.getData(); - return data.find(d => d.group === "delta").value; + return data.find((d) => d.group === "delta").value; } getArcType(): GaugeTypes { @@ -98,7 +104,10 @@ export class Gauge extends Component { const valueFontSize = radius / 2.5; const deltaFontSize = radius / 8; const distanceBetweenNumbers = 10; - const numbersYPosition = arcType === GaugeTypes.SEMI ? -(deltaFontSize + distanceBetweenNumbers) : 0; + const numbersYPosition = + arcType === GaugeTypes.SEMI + ? -(deltaFontSize + distanceBetweenNumbers) + : 0; this.backgroundArc = arc() .innerRadius(innerRadius) @@ -127,50 +136,74 @@ export class Gauge extends Component { .attr("role", Roles.GROUP); // Add data arc - DOMUtils.appendOrSelect(svg, "path.arc-foreground") .attr("d", this.arc) .classed("arc", true) .attr("fill", options.gauge.arcForegroundColor); // Position Arc - const gaugeTranslateX = radius + options.gauge.hoverArc.outerRadiusOffset; // Leaves space for the hover animation - const gaugeTranslateY = radius + options.gauge.hoverArc.outerRadiusOffset; - svg.attr("transform", `translate(${gaugeTranslateX}, ${gaugeTranslateY})`); + const gaugeTranslateX = + radius + options.gauge.hoverArc.outerRadiusOffset; // Leaves space for the hover animation + const gaugeTranslateY = + radius + options.gauge.hoverArc.outerRadiusOffset; + svg.attr( + "transform", + `translate(${gaugeTranslateX}, ${gaugeTranslateY})` + ); // Add the numbers at the center - const numbersG = DOMUtils.appendOrSelect(svg, "g.gauge-numbers") - .attr("transform", `translate(0, ${numbersYPosition})`); + const numbersG = DOMUtils.appendOrSelect(svg, "g.gauge-numbers").attr( + "transform", + `translate(0, ${numbersYPosition})` + ); // Add the big number - const valueNumberG = DOMUtils.appendOrSelect(numbersG, "g.gauge-value-number") - .attr("transform", `translate(-10, 0)`); // Optical centering for the presence of the smaller % symbol - - const valueNumber = DOMUtils.appendOrSelect(valueNumberG, "text.gauge-value-number") + const valueNumberG = DOMUtils.appendOrSelect( + numbersG, + "g.gauge-value-number" + ).attr("transform", `translate(-10, 0)`); // Optical centering for the presence of the smaller % symbol + + const valueNumber = DOMUtils.appendOrSelect( + valueNumberG, + "text.gauge-value-number" + ) .style("font-size", `${valueFontSize}px`) .attr("text-anchor", "middle") .text(`${options.gauge.numberFormatter(value)}`); - const { width: valueNumberWidth } = DOMUtils.getSVGElementSize(valueNumber, { useBBox: true }); + const { + width: valueNumberWidth + } = DOMUtils.getSVGElementSize(valueNumber, { useBBox: true }); DOMUtils.appendOrSelect(valueNumberG, "text.gauge-value-symbol") .style("font-size", `${valueFontSize / 2}px`) .attr("x", valueNumberWidth / 2) .text("%"); - console.log(DOMUtils.getSVGElementSize(valueNumber, { useBBox: true })); - setTimeout(() => console.log(DOMUtils.getSVGElementSize(valueNumber, { useBBox: true })), 1000); // Add the smaller number of the delta - const deltaNumberG = DOMUtils.appendOrSelect(numbersG, "g.gauge-delta") - .attr("transform", `translate(0, ${deltaFontSize + distanceBetweenNumbers})`); - - const deltaNumber = DOMUtils.appendOrSelect(deltaNumberG, "text.gauge-delta-number") + const deltaNumberG = DOMUtils.appendOrSelect( + numbersG, + "g.gauge-delta" + ).attr( + "transform", + `translate(0, ${deltaFontSize + distanceBetweenNumbers})` + ); + + const deltaNumber = DOMUtils.appendOrSelect( + deltaNumberG, + "text.gauge-delta-number" + ) .attr("text-anchor", "middle") .style("font-size", `${deltaFontSize}px`) .text(`${options.gauge.numberFormatter(delta)}%`); - const { width: deltaNumberWidth } = DOMUtils.getSVGElementSize(deltaNumber, { useBBox: true }); - const deltaArrow = DOMUtils.appendOrSelect(deltaNumberG, "svg.gauge-delta-arrow") + const { + width: deltaNumberWidth + } = DOMUtils.getSVGElementSize(deltaNumber, { useBBox: true }); + const deltaArrow = DOMUtils.appendOrSelect( + deltaNumberG, + "svg.gauge-delta-arrow" + ) .attr("x", -arrowSize - deltaNumberWidth / 2) .attr("y", -arrowSize / 2 - deltaFontSize * 0.35) .attr("width", arrowSize) @@ -191,7 +224,6 @@ export class Gauge extends Component { this.addEventListeners(); } - getInnerRadius() { // Compute the outer radius needed const radius = this.computeRadius(); @@ -203,21 +235,30 @@ export class Gauge extends Component { handleLegendOnHover = (event: CustomEvent) => { const { hoveredElement } = event.detail; - this.parent.selectAll("path.arc") - .transition(this.services.transitions.getTransition("legend-hover-bar")) - .attr("opacity", d => (d.data.label !== hoveredElement.datum()["key"]) ? 0.3 : 1); + this.parent + .selectAll("path.arc") + .transition( + this.services.transitions.getTransition("legend-hover-bar") + ) + .attr("opacity", (d) => + d.data.label !== hoveredElement.datum()["key"] ? 0.3 : 1 + ); } // Un-highlight all elements handleLegendMouseOut = (event: CustomEvent) => { - this.parent.selectAll("path.arc") - .transition(this.services.transitions.getTransition("legend-mouseout-bar")) + this.parent + .selectAll("path.arc") + .transition( + this.services.transitions.getTransition("legend-mouseout-bar") + ) .attr("opacity", 1); } addEventListeners() { const self = this; - this.parent.selectAll("path.arc") + this.parent + .selectAll("path.arc") .on("mouseover", function(datum) { // Dispatch mouse event self.services.events.dispatchEvent(Events.Gauge.ARC_MOUSEOVER, { @@ -228,8 +269,13 @@ export class Gauge extends Component { .on("mousemove", function(datum) { const hoveredElement = select(this); - hoveredElement.classed("hovered", true) - .transition(self.services.transitions.getTransition("pie_slice_mouseover")) + hoveredElement + .classed("hovered", true) + .transition( + self.services.transitions.getTransition( + "pie_slice_mouseover" + ) + ) .attr("d", self.hoverArc); // Dispatch mouse event @@ -253,8 +299,13 @@ export class Gauge extends Component { }) .on("mouseout", function(datum) { const hoveredElement = select(this); - hoveredElement.classed("hovered", false) - .transition(self.services.transitions.getTransition("gauge_slice_mouseover")) + hoveredElement + .classed("hovered", false) + .transition( + self.services.transitions.getTransition( + "gauge_slice_mouseover" + ) + ) .attr("d", self.arc); // Dispatch mouse event @@ -264,7 +315,9 @@ export class Gauge extends Component { }); // Hide tooltip - self.services.events.dispatchEvent(Events.Tooltip.HIDE, { hoveredElement }); + self.services.events.dispatchEvent(Events.Tooltip.HIDE, { + hoveredElement + }); }); } @@ -273,10 +326,13 @@ export class Gauge extends Component { const arcType = this.getArcType(); const options = this.model.getOptions(); - const { width, height } = DOMUtils.getSVGElementSize(this.parent, { useAttrs: true }); - const radius = arcType === GaugeTypes.SEMI - ? Math.min(width / 2, height) - : Math.min(width / 2, height / 2); + const { width, height } = DOMUtils.getSVGElementSize(this.parent, { + useAttrs: true + }); + const radius = + arcType === GaugeTypes.SEMI + ? Math.min(width / 2, height) + : Math.min(width / 2, height / 2); return radius - options.gauge.hoverArc.outerRadiusOffset; } diff --git a/packages/core/src/components/graphs/line.ts b/packages/core/src/components/graphs/line.ts index 0fcf597dfa..e76bd9dcc2 100644 --- a/packages/core/src/components/graphs/line.ts +++ b/packages/core/src/components/graphs/line.ts @@ -77,7 +77,7 @@ export class Line extends Component { // Apply styles and datum enteringLines .merge(lines) - .attr("stroke", group => { + .attr("stroke", (group) => { return this.model.getStrokeColor(group.name); }) // a11y diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index e8a94fdaaf..8b6b78886b 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -26,7 +26,6 @@ import { } from "./interfaces"; import enUSLocaleObject from "date-fns/locale/en-US/index"; - /* ***************************** * User configurable options * @@ -43,16 +42,16 @@ export const legend: LegendOptions = { items: { status: { ACTIVE: 1, - DISABLED: 0, + DISABLED: 0 }, horizontalSpace: 12, verticalSpace: 24, - textYOffset: 8, + textYOffset: 8 }, checkbox: { radius: 6.5, - spaceAfter: 4, - }, + spaceAfter: 4 + } }; /** @@ -60,11 +59,11 @@ export const legend: LegendOptions = { */ export const grid: GridOptions = { x: { - numberOfTicks: 5, + numberOfTicks: 5 }, y: { - numberOfTicks: 5, - }, + numberOfTicks: 5 + } }; /** @@ -73,12 +72,12 @@ export const grid: GridOptions = { export const baseTooltip: TooltipOptions = { datapoint: { horizontalOffset: 10, - enabled: true, + enabled: true }, title: { verticalOffset: 0.75, - width: 0.4, - }, + width: 0.4 + } }; export const axisChartTooltip: AxisTooltipOptions = Tools.merge( @@ -87,8 +86,8 @@ export const axisChartTooltip: AxisTooltipOptions = Tools.merge( { gridline: { enabled: true, - threshold: 0.02, - }, + threshold: 0.02 + } } as AxisTooltipOptions ); @@ -97,11 +96,11 @@ export const barChartTooltip: BarTooltipOptions = Tools.merge( axisChartTooltip, { datapoint: { - verticalOffset: 4, + verticalOffset: 4 }, gridline: { - enabled: false, - }, + enabled: false + } } as BarTooltipOptions ); @@ -110,17 +109,17 @@ export const barChartTooltip: BarTooltipOptions = Tools.merge( // and by TwoDimensionalAxes. const axes: AxesOptions = { top: { - includeZero: true, + includeZero: true }, bottom: { - includeZero: true, + includeZero: true }, left: { - includeZero: true, + includeZero: true }, right: { - includeZero: true, - }, + includeZero: true + } }; export const timeScale: TimeScaleOptions = { @@ -136,8 +135,8 @@ export const timeScale: TimeScaleOptions = { weekly: { primary: "eee, MMM d", secondary: "eee" }, monthly: { primary: "MMM yyyy", secondary: "MMM" }, quarterly: { primary: "QQQ ''yy", secondary: "QQQ" }, - yearly: { primary: "yyyy", secondary: "yyyy" }, - }, + yearly: { primary: "yyyy", secondary: "yyyy" } + } }; /** @@ -150,15 +149,15 @@ const chart: BaseChartOptions = { tooltip: baseTooltip, legend, style: { - prefix: "cc", + prefix: "cc" }, data: { groupMapsTo: "group", - loading: false, + loading: false }, color: { - scale: null, - }, + scale: null + } }; /** @@ -168,7 +167,7 @@ const axisChart: AxisChartOptions = Tools.merge({}, chart, { axes, timeScale, grid, - tooltip: axisChartTooltip, + tooltip: axisChartTooltip } as AxisChartOptions); /** @@ -176,12 +175,12 @@ const axisChart: AxisChartOptions = Tools.merge({}, chart, { */ const baseBarChart: BarChartOptions = Tools.merge({}, axisChart, { bars: { - maxWidth: 16, + maxWidth: 16 }, timeScale: Tools.merge(timeScale, { - addSpaceOnEdges: 1, + addSpaceOnEdges: 1 } as TimeScaleOptions), - tooltip: barChartTooltip, + tooltip: barChartTooltip } as BarChartOptions); /** @@ -207,8 +206,8 @@ const groupedBarChart: BarChartOptions = Tools.merge( */ const stackedBarChart: StackedBarChartOptions = Tools.merge({}, baseBarChart, { bars: Tools.merge({}, baseBarChart.bars, { - dividerSize: 1.5, - } as StackedBarOptions), + dividerSize: 1.5 + } as StackedBarOptions) } as BarChartOptions); /** @@ -218,8 +217,8 @@ const lineChart: LineChartOptions = Tools.merge({}, axisChart, { points: { // default point radius to 3 radius: 3, - filled: false, - }, + filled: false + } } as LineChartOptions); /** @@ -239,8 +238,8 @@ const scatterChart: ScatterChartOptions = Tools.merge({}, axisChart, { // default point radius to 4 radius: 4, fillOpacity: 0.3, - filled: true, - }, + filled: true + } } as ScatterChartOptions); /** @@ -256,11 +255,11 @@ const bubbleChart: BubbleChartOptions = Tools.merge({}, axisChart, { ); return [ (smallerChartDimension * 3) / 400, - (smallerChartDimension * 25) / 400, + (smallerChartDimension * 25) / 400 ]; }, - fillOpacity: 0.2, - }, + fillOpacity: 0.2 + } } as BubbleChartOptions); /** @@ -272,7 +271,7 @@ const pieChart: PieChartOptions = Tools.merge({}, chart, { innerRadius: 2, padAngle: 0.007, hoverArc: { - outerRadiusOffset: 3, + outerRadiusOffset: 3 }, xOffset: 30, yOffset: 20, @@ -282,12 +281,12 @@ const pieChart: PieChartOptions = Tools.merge({}, chart, { offsetX: 15, offsetY: 12, horizontalLineLength: 8, - textMargin: 2, + textMargin: 2 }, labels: { - formatter: null, - }, - }, + formatter: null + } + } } as PieChartOptions); /** @@ -304,7 +303,7 @@ const gaugeChart: GaugeChartOptions = Tools.merge({}, pieChart, { arcBackgroundColor: `rgb(224,224,224)`, arcForegroundColor: `rgb(88,134,247)`, arrowColor: `currentColor`, - numberFormatter: number => number.toFixed(2).toLocaleString(), + numberFormatter: (number) => number.toFixed(2).toLocaleString(), hoverArc: { outerRadiusOffset: 3 } @@ -321,9 +320,9 @@ const donutChart: DonutChartOptions = Tools.merge({}, pieChart, { Math.min((radius / 100) * 24, 24) + "px", titleFontSize: (radius) => Math.min((radius / 100) * 15, 15) + "px", titleYPosition: (radius) => Math.min((radius / 80) * 20, 20), - numberFormatter: (number) => Math.floor(number).toLocaleString(), - }, - }, + numberFormatter: (number) => Math.floor(number).toLocaleString() + } + } } as DonutChartOptions); /** @@ -333,26 +332,26 @@ const radarChart: RadarChartOptions = Tools.merge({}, chart, { radar: { axes: { angle: "key", - value: "value", + value: "value" }, opacity: { unselected: 0.1, - selected: 0.3, + selected: 0.3 }, xLabelPadding: 10, yLabelPadding: 8, yTicksNumber: 4, minRange: 10, xAxisRectHeight: 50, - dotsRadius: 5, + dotsRadius: 5 }, tooltip: { gridline: { - enabled: true, + enabled: true }, valueFormatter: (value) => - value !== null && value !== undefined ? value : "N/A", - }, + value !== null && value !== undefined ? value : "N/A" + } } as RadarChartOptions); export const options = { @@ -368,6 +367,7 @@ export const options = { pieChart, donutChart, radarChart, + gaugeChart }; /** @@ -376,8 +376,8 @@ export const options = { export const lines = { opacity: { unselected: 0.3, - selected: 1, - }, + selected: 1 + } }; /** @@ -386,8 +386,8 @@ export const lines = { export const area = { opacity: { unselected: 0, - selected: 0.3, - }, + selected: 0.3 + } }; /** @@ -395,34 +395,34 @@ export const area = { */ export const transitions = { default: { - duration: 300, + duration: 300 }, pie_slice_mouseover: { - duration: 100, + duration: 100 }, pie_chart_titles: { - duration: 375, + duration: 375 }, graph_element_mouseover_fill_update: { - duration: 100, + duration: 100 }, graph_element_mouseout_fill_update: { - duration: 100, - }, + duration: 100 + } }; export const axis = { ticks: { number: 7, - rotateIfSmallerThan: 30, + rotateIfSmallerThan: 30 }, - paddingRatio: 0.1, + paddingRatio: 0.1 }; export const spacers = { default: { - size: 24, - }, + size: 24 + } }; export const tickSpaceRatioVertical = 2.5; diff --git a/packages/core/src/interfaces/charts.ts b/packages/core/src/interfaces/charts.ts index 33098ac70b..f596e0a832 100644 --- a/packages/core/src/interfaces/charts.ts +++ b/packages/core/src/interfaces/charts.ts @@ -186,9 +186,11 @@ export interface AreaChartOptions extends AxisChartOptions { /** * options for the curve of the line */ - curve?: string | { - name: string; - }; + curve?: + | string + | { + name: string; + }; } /** @@ -235,7 +237,6 @@ export interface GaugeChartOptions extends PieChartOptions { }; } - /** * options specific to donut charts */ diff --git a/packages/core/src/interfaces/enums.ts b/packages/core/src/interfaces/enums.ts index d1e73526cf..dc80e9d04a 100644 --- a/packages/core/src/interfaces/enums.ts +++ b/packages/core/src/interfaces/enums.ts @@ -133,8 +133,7 @@ export enum DominantBaseline { HANGING = "hanging", } - export enum GaugeTypes { SEMI = "semi", - FULL = "full" + FULL = "full", } diff --git a/packages/core/src/interfaces/events.ts b/packages/core/src/interfaces/events.ts index da132a0f86..2c57a50545 100644 --- a/packages/core/src/interfaces/events.ts +++ b/packages/core/src/interfaces/events.ts @@ -40,7 +40,7 @@ export enum Gauge { ARC_MOUSEOVER = "gauge-arc-mouseover", ARC_MOUSEMOVE = "gauge-arc-mousemove", ARC_CLICK = "gauge-arc-click", - ARC_MOUSEOUT = "gauge-arc-mouseout" + ARC_MOUSEOUT = "gauge-arc-mouseout", } /** diff --git a/packages/core/src/tools.ts b/packages/core/src/tools.ts index 6de929b284..9a426feb53 100644 --- a/packages/core/src/tools.ts +++ b/packages/core/src/tools.ts @@ -213,26 +213,29 @@ export namespace Tools { } /** - * Linearly interpolates a value between minValue and maxValue, then - * clamps the result to the two limits. - * The first parameter is always the value to interpolate. When called - * with one additional parameter, minValue is set to 0, while the only - * parameter is used as maxValue. When called with 2 additional - * parameters, they are read as minValue and maxValue, respectively. - * @export - * @param {number} value - * @param {number} firstLimit - * @param {number} [secondLimit] - * @returns The interpolated value - */ - export function interpolateAndClamp(value: number, firstLimit: number, secondLimit?: number): number { + * Linearly interpolates a value between minValue and maxValue, then + * clamps the result to the two limits. + * The first parameter is always the value to interpolate. When called + * with one additional parameter, minValue is set to 0, while the only + * parameter is used as maxValue. When called with 2 additional + * parameters, they are read as minValue and maxValue, respectively. + * @export + * @param {number} value + * @param {number} firstLimit + * @param {number} [secondLimit] + * @returns The interpolated value + */ + export function interpolateAndClamp( + value: number, + firstLimit: number, + secondLimit?: number + ): number { const minValue = secondLimit === undefined ? 0 : firstLimit; const maxValue = secondLimit === undefined ? firstLimit : secondLimit; const interpolated = maxValue * value; return lodashClamp(interpolated, minValue, maxValue); } - /************************************** * Object/array related checks * *************************************/ diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index 68458e9136..d7cd4778a4 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -7,18 +7,10 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline **Note:** Version bump only for package @carbon/charts-vue - - - - # [0.31.0](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.24...v0.31.0) (2020-05-29) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.24](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.23...v0.30.24) (2020-05-15) **Note:** Version bump only for package @carbon/charts-vue @@ -27,279 +19,143 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.22](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.21...v0.30.22) (2020-05-13) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.21](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.20...v0.30.21) (2020-05-11) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.20](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.19...v0.30.20) (2020-05-08) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.19](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.18...v0.30.19) (2020-05-01) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.18](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.17...v0.30.18) (2020-04-24) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.17](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.16...v0.30.17) (2020-04-23) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.16](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.15...v0.30.16) (2020-04-23) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.15](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.14...v0.30.15) (2020-04-22) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.14](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.13...v0.30.14) (2020-04-21) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.13](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.12...v0.30.13) (2020-04-20) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.12](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.11...v0.30.12) (2020-04-17) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.11](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.10...v0.30.11) (2020-04-15) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.10](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.9...v0.30.10) (2020-04-09) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.9](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.8...v0.30.9) (2020-04-09) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.8](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.7...v0.30.8) (2020-04-03) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.7](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.6...v0.30.7) (2020-03-31) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.6](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.5...v0.30.6) (2020-03-30) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.5](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.4...v0.30.5) (2020-03-30) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.4](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.3...v0.30.4) (2020-03-27) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.3](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.2...v0.30.3) (2020-03-24) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.2](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.1...v0.30.2) (2020-03-16) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.30.1](https://github.com/carbon-design-system/carbon-charts/compare/v0.30.0...v0.30.1) (2020-03-13) **Note:** Version bump only for package @carbon/charts-vue - - - - # [0.30.0](https://github.com/carbon-design-system/carbon-charts/compare/v0.29.8...v0.30.0) (2020-03-11) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.29.8](https://github.com/carbon-design-system/carbon-charts/compare/v0.29.7...v0.29.8) (2020-03-03) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.29.7](https://github.com/carbon-design-system/carbon-charts/compare/v0.29.6...v0.29.7) (2020-02-28) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.29.6](https://github.com/carbon-design-system/carbon-charts/compare/v0.29.5...v0.29.6) (2020-02-25) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.29.5](https://github.com/carbon-design-system/carbon-charts/compare/v0.29.4...v0.29.5) (2020-02-21) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.29.4](https://github.com/carbon-design-system/carbon-charts/compare/v0.29.3...v0.29.4) (2020-02-20) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.29.3](https://github.com/carbon-design-system/carbon-charts/compare/v0.29.2...v0.29.3) (2020-02-20) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.29.2](https://github.com/carbon-design-system/carbon-charts/compare/v0.29.1...v0.29.2) (2020-02-18) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.29.1](https://github.com/carbon-design-system/carbon-charts/compare/v0.29.0...v0.29.1) (2020-02-10) **Note:** Version bump only for package @carbon/charts-vue - - - - # [0.29.0](https://github.com/carbon-design-system/carbon-charts/compare/v0.28.1...v0.29.0) (2020-02-07) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.28.1](https://github.com/carbon-design-system/carbon-charts/compare/v0.28.0...v0.28.1) (2020-01-30) **Note:** Version bump only for package @carbon/charts-vue - - - - # [0.28.0](https://github.com/carbon-design-system/carbon-charts/compare/v0.27.0...v0.28.0) (2020-01-21) ### Features -* **core:** add support for horizontal bar charts ([#415](https://github.com/carbon-design-system/carbon-charts/issues/415)) ([6a480f0](https://github.com/carbon-design-system/carbon-charts/commit/6a480f0)) +- **core:** add support for horizontal bar charts ([#415](https://github.com/carbon-design-system/carbon-charts/issues/415)) ([6a480f0](https://github.com/carbon-design-system/carbon-charts/commit/6a480f0)) # [0.27.0](https://github.com/carbon-design-system/carbon-charts/compare/v0.26.1...v0.27.0) (2020-01-20) @@ -309,119 +165,63 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline **Note:** Version bump only for package @carbon/charts-vue - - - - # [0.26.0](https://github.com/carbon-design-system/carbon-charts/compare/v0.25.0...v0.26.0) (2020-01-16) **Note:** Version bump only for package @carbon/charts-vue - - - - # [0.25.0](https://github.com/carbon-design-system/carbon-charts/compare/v0.24.5...v0.25.0) (2020-01-10) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.24.5](https://github.com/carbon-design-system/carbon-charts/compare/v0.24.4...v0.24.5) (2020-01-10) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.24.4](https://github.com/carbon-design-system/carbon-charts/compare/v0.24.3...v0.24.4) (2020-01-06) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.24.3](https://github.com/carbon-design-system/carbon-charts/compare/v0.24.2...v0.24.3) (2019-12-19) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.24.2](https://github.com/carbon-design-system/carbon-charts/compare/v0.24.1...v0.24.2) (2019-12-19) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.24.1](https://github.com/carbon-design-system/carbon-charts/compare/v0.24.0...v0.24.1) (2019-12-18) **Note:** Version bump only for package @carbon/charts-vue - - - - # [0.24.0](https://github.com/carbon-design-system/carbon-charts/compare/v0.23.0...v0.24.0) (2019-12-17) **Note:** Version bump only for package @carbon/charts-vue - - - - # [0.23.0](https://github.com/carbon-design-system/carbon-charts/compare/v0.22.4...v0.23.0) (2019-12-17) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.22.4](https://github.com/carbon-design-system/carbon-charts/compare/v0.22.3...v0.22.4) (2019-12-16) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.22.3](https://github.com/carbon-design-system/carbon-charts/compare/v0.22.2...v0.22.3) (2019-12-16) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.22.2](https://github.com/carbon-design-system/carbon-charts/compare/v0.22.1...v0.22.2) (2019-12-16) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.22.1](https://github.com/carbon-design-system/carbon-charts/compare/v0.22.0...v0.22.1) (2019-12-12) **Note:** Version bump only for package @carbon/charts-vue - - - - # [0.22.0](https://github.com/carbon-design-system/carbon-charts/compare/v0.21.0...v0.22.0) (2019-12-09) ### Features -* **core, angular, react, vue:** Update chart width & height through options ([f050c35](https://github.com/carbon-design-system/carbon-charts/commit/f050c35)) +- **core, angular, react, vue:** Update chart width & height through options ([f050c35](https://github.com/carbon-design-system/carbon-charts/commit/f050c35)) # [0.21.0](https://github.com/carbon-design-system/carbon-charts/compare/v0.20.1...v0.21.0) (2019-12-09) @@ -447,7 +247,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline ### Bug Fixes -* **core:** build optimizations ([fef77e5](https://github.com/carbon-design-system/carbon-charts/commit/fef77e5)) +- **core:** build optimizations ([fef77e5](https://github.com/carbon-design-system/carbon-charts/commit/fef77e5)) # [0.17.0](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.25...v0.17.0) (2019-11-29) @@ -461,7 +261,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline ### Bug Fixes -* **core, react, angular, vue:** default width & height to 100%, and call setOptions on option change ([db251b4](https://github.com/carbon-design-system/carbon-charts/commit/db251b4)) +- **core, react, angular, vue:** default width & height to 100%, and call setOptions on option change ([db251b4](https://github.com/carbon-design-system/carbon-charts/commit/db251b4)) ## [0.16.23](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.22...v0.16.23) (2019-10-25) @@ -471,274 +271,138 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.16.21](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.20...v0.16.21) (2019-10-24) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.16.20](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.19...v0.16.20) (2019-10-24) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.16.19](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.18...v0.16.19) (2019-10-24) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.16.18](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.17...v0.16.18) (2019-10-21) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.16.17](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.16...v0.16.17) (2019-10-10) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.16.16](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.15...v0.16.16) (2019-10-10) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.16.15](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.14...v0.16.15) (2019-10-09) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.16.14](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.13...v0.16.14) (2019-10-09) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.16.13](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.12...v0.16.13) (2019-10-09) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.16.12](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.11...v0.16.12) (2019-10-09) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.16.11](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.10...v0.16.11) (2019-10-09) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.16.10](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.9...v0.16.10) (2019-10-08) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.16.9](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.8...v0.16.9) (2019-10-07) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.16.8](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.7...v0.16.8) (2019-10-02) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.16.7](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.6...v0.16.7) (2019-09-30) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.16.6](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.5...v0.16.6) (2019-09-30) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.16.5](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.4...v0.16.5) (2019-09-30) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.16.4](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.3...v0.16.4) (2019-09-12) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.16.3](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.2...v0.16.3) (2019-09-11) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.16.2](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.1...v0.16.2) (2019-09-09) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.16.1](https://github.com/carbon-design-system/carbon-charts/compare/v0.16.0...v0.16.1) (2019-09-06) **Note:** Version bump only for package @carbon/charts-vue - - - - # [0.16.0](https://github.com/carbon-design-system/carbon-charts/compare/v0.15.8...v0.16.0) (2019-09-06) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.15.8](https://github.com/carbon-design-system/carbon-charts/compare/v0.15.7...v0.15.8) (2019-08-24) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.15.7](https://github.com/carbon-design-system/carbon-charts/compare/v0.15.6...v0.15.7) (2019-08-22) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.15.6](https://github.com/carbon-design-system/carbon-charts/compare/v0.15.5...v0.15.6) (2019-08-19) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.15.5](https://github.com/carbon-design-system/carbon-charts/compare/v0.15.4...v0.15.5) (2019-08-19) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.15.4](https://github.com/carbon-design-system/carbon-charts/compare/v0.15.3...v0.15.4) (2019-08-16) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.15.3](https://github.com/carbon-design-system/carbon-charts/compare/v0.15.2...v0.15.3) (2019-08-16) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.15.2](https://github.com/carbon-design-system/carbon-charts/compare/v0.15.1...v0.15.2) (2019-08-12) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.15.1](https://github.com/carbon-design-system/carbon-charts/compare/v0.15.0...v0.15.1) (2019-07-17) **Note:** Version bump only for package @carbon/charts-vue - - - - # [0.15.0](https://github.com/carbon-design-system/carbon-charts/compare/v0.14.1...v0.15.0) (2019-07-17) **Note:** Version bump only for package @carbon/charts-vue - - - - ## [0.14.1](https://github.com/carbon-design-system/carbon-charts/compare/v0.14.0...v0.14.1) (2019-07-11) **Note:** Version bump only for package @carbon/charts-vue - - - - # [0.14.0](https://github.com/carbon-design-system/carbon-charts/compare/v0.13.0...v0.14.0) (2019-07-10) **Note:** Version bump only for package @carbon/charts-vue - - - - # [0.13.0](https://github.com/carbon-design-system/carbon-charts/compare/v0.12.5...v0.13.0) (2019-07-08) **Note:** Version bump only for package @carbon/charts-vue diff --git a/packages/vue/src/ccv-area-chart.vue b/packages/vue/src/ccv-area-chart.vue index e600f5dbc9..971def50d7 100644 --- a/packages/vue/src/ccv-area-chart.vue +++ b/packages/vue/src/ccv-area-chart.vue @@ -12,8 +12,8 @@ export default { mounted() { this.coreChart = new AreaChart(this.$el, { data: this.data, - options: this.options + options: this.options, }); - } + }, }; From 266d7dc646b142a2a7b150bbbb512b8e1ae67bf6 Mon Sep 17 00:00:00 2001 From: Natasha DeCoste Date: Mon, 8 Jun 2020 13:47:07 -0400 Subject: [PATCH 30/43] formatting --- packages/core/src/components/graphs/gauge.ts | 29 +++++++++++--------- packages/core/src/configuration.ts | 6 ++-- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index f80bece34b..def6e7d4eb 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -56,7 +56,7 @@ export class Gauge extends Component { getArcType(): GaugeTypes { const options = this.model.getOptions(); - const { type } = options.gauge; + const type = Tools.getProperty(options, "gauge", "type"); return type; } @@ -82,7 +82,6 @@ export class Gauge extends Component { } render(animate = true) { - const self = this; const svg = this.getContainerSVG(); const options = this.model.getOptions(); const value = this.getValue(); @@ -121,10 +120,11 @@ export class Gauge extends Component { .startAngle(startAngle) .endAngle(currentAngle); + const outerRadiusOffset = Tools.getProperty(options, "gauge", "hoverArc", "outerRadiusOffset"); // Set the hover arc radius this.hoverArc = arc() .innerRadius(innerRadius) - .outerRadius(radius + options.gauge.hoverArc.outerRadiusOffset) + .outerRadius(radius + outerRadiusOffset ) .startAngle(startAngle) .endAngle(currentAngle); @@ -132,20 +132,20 @@ export class Gauge extends Component { DOMUtils.appendOrSelect(svg, "path.arc-background") .attr("d", this.backgroundArc) - .attr("fill", options.gauge.arcBackgroundColor) + .attr("fill", Tools.getProperty(options, "gauge", "arcBackgroundColor")) .attr("role", Roles.GROUP); // Add data arc DOMUtils.appendOrSelect(svg, "path.arc-foreground") .attr("d", this.arc) .classed("arc", true) - .attr("fill", options.gauge.arcForegroundColor); + .attr("fill", Tools.getProperty(options, "gauge", "arcForegroundColor")); // Position Arc const gaugeTranslateX = - radius + options.gauge.hoverArc.outerRadiusOffset; // Leaves space for the hover animation + radius + outerRadiusOffset; // Leaves space for the hover animation const gaugeTranslateY = - radius + options.gauge.hoverArc.outerRadiusOffset; + radius + outerRadiusOffset; svg.attr( "transform", `translate(${gaugeTranslateX}, ${gaugeTranslateY})` @@ -163,13 +163,14 @@ export class Gauge extends Component { "g.gauge-value-number" ).attr("transform", `translate(-10, 0)`); // Optical centering for the presence of the smaller % symbol + const numberFormatter = Tools.getProperty(options, "gauge", "numberFormatter"); const valueNumber = DOMUtils.appendOrSelect( valueNumberG, "text.gauge-value-number" ) .style("font-size", `${valueFontSize}px`) .attr("text-anchor", "middle") - .text(`${options.gauge.numberFormatter(value)}`); + .text(`${numberFormatter(value)}`); const { width: valueNumberWidth @@ -195,8 +196,9 @@ export class Gauge extends Component { ) .attr("text-anchor", "middle") .style("font-size", `${deltaFontSize}px`) - .text(`${options.gauge.numberFormatter(delta)}%`); + .text(`${numberFormatter(delta)}%`); + // Add the caret for the delta number const { width: deltaNumberWidth } = DOMUtils.getSVGElementSize(deltaNumber, { useBBox: true }); @@ -218,7 +220,7 @@ export class Gauge extends Component { .attr("fill", "none"); DOMUtils.appendOrSelect(deltaArrow, "polygon.gauge-delta-arrow-polygon") .attr("points", delta > 0 ? ARROW_UP : ARROW_DOWN) - .attr("fill", options.gauge.arrowColor); + .attr("fill", Tools.getProperty(options, "gauge", "arrowColor")); // Add event listeners this.addEventListeners(); @@ -227,8 +229,8 @@ export class Gauge extends Component { getInnerRadius() { // Compute the outer radius needed const radius = this.computeRadius(); - const options = this.model.getOptions(); - return radius - options.gauge.arcWidth; + const arcWidth = Tools.getProperty(this.model.getOptions(), "gauge", "arcWidth"); + return radius - arcWidth; } // Highlight elements that match the hovered legend item @@ -325,6 +327,7 @@ export class Gauge extends Component { protected computeRadius() { const arcType = this.getArcType(); const options = this.model.getOptions(); + const outerRadiusOffset = Tools.getProperty(options, "gauge", "hoverArc", "outerRadiusOffset"); const { width, height } = DOMUtils.getSVGElementSize(this.parent, { useAttrs: true @@ -334,6 +337,6 @@ export class Gauge extends Component { ? Math.min(width / 2, height) : Math.min(width / 2, height / 2); - return radius - options.gauge.hoverArc.outerRadiusOffset; + return radius - outerRadiusOffset; } } diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 8b6b78886b..c5994e5a7e 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -300,9 +300,9 @@ const gaugeChart: GaugeChartOptions = Tools.merge({}, pieChart, { gauge: { type: GaugeTypes.SEMI, arcWidth: 16, - arcBackgroundColor: `rgb(224,224,224)`, - arcForegroundColor: `rgb(88,134,247)`, - arrowColor: `currentColor`, + arcBackgroundColor: "rgb(224,224,224)", + arcForegroundColor: "rgb(88,134,247)", + arrowColor: "currentColor", numberFormatter: (number) => number.toFixed(2).toLocaleString(), hoverArc: { outerRadiusOffset: 3 From fa5e496b81a50ea11e1f14fa81dc7f3dff1ccd32 Mon Sep 17 00:00:00 2001 From: Natasha DeCoste Date: Mon, 8 Jun 2020 15:21:30 -0400 Subject: [PATCH 31/43] review changes --- packages/core/src/components/graphs/gauge.ts | 20 +++++----------- packages/core/src/tools.ts | 24 -------------------- 2 files changed, 6 insertions(+), 38 deletions(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index def6e7d4eb..6ddf333c22 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -8,11 +8,6 @@ import { Tools } from "../../tools"; import { select } from "d3-selection"; import { arc } from "d3-shape"; -const ARC_TYPES_RATIOS = { - semi: 0.5, - full: 1 -}; - export class Gauge extends Component { type = "gauge"; @@ -54,15 +49,10 @@ export class Gauge extends Component { return data.find((d) => d.group === "delta").value; } - getArcType(): GaugeTypes { + getArcRatio(): number { const options = this.model.getOptions(); const type = Tools.getProperty(options, "gauge", "type"); - return type; - } - - getArcRatio(): number { - const type = this.getArcType(); - const arcRatio = ARC_TYPES_RATIOS[type]; + const arcRatio = type === GaugeTypes.FULL ? 1 : 0.5; if (arcRatio === undefined) { throw new Error("Gauge chart arc type not compatible"); } @@ -88,7 +78,7 @@ export class Gauge extends Component { const valueRatio = this.getValueRatio(); const delta = this.getDelta(); const arcSize = this.getArcSize(); - const arcType = this.getArcType(); + const arcType = Tools.getProperty(options, "gauge", "arcType"); const startAngle = this.getStartAngle(); const rotationAngle = valueRatio * arcSize; const currentAngle = startAngle + rotationAngle; @@ -212,8 +202,10 @@ export class Gauge extends Component { .attr("height", arrowSize) .attr("viewBox", `0 0 16 16`); + // arrow paths for delta const ARROW_UP = "4,10 8,6 12,10"; const ARROW_DOWN = "12,6 8,10 4,6"; + DOMUtils.appendOrSelect(deltaArrow, "rect.gauge-delta-arrow-backdrop") // Needed to correctly size SVG in Firefox .attr("width", `16`) .attr("height", `16`) @@ -325,8 +317,8 @@ export class Gauge extends Component { // Helper functions protected computeRadius() { - const arcType = this.getArcType(); const options = this.model.getOptions(); + const arcType = Tools.getProperty(options, "gauge", "arcType"); const outerRadiusOffset = Tools.getProperty(options, "gauge", "hoverArc", "outerRadiusOffset"); const { width, height } = DOMUtils.getSVGElementSize(this.parent, { diff --git a/packages/core/src/tools.ts b/packages/core/src/tools.ts index 9a426feb53..45ad4c7cbc 100644 --- a/packages/core/src/tools.ts +++ b/packages/core/src/tools.ts @@ -212,30 +212,6 @@ export namespace Tools { : percentage; } - /** - * Linearly interpolates a value between minValue and maxValue, then - * clamps the result to the two limits. - * The first parameter is always the value to interpolate. When called - * with one additional parameter, minValue is set to 0, while the only - * parameter is used as maxValue. When called with 2 additional - * parameters, they are read as minValue and maxValue, respectively. - * @export - * @param {number} value - * @param {number} firstLimit - * @param {number} [secondLimit] - * @returns The interpolated value - */ - export function interpolateAndClamp( - value: number, - firstLimit: number, - secondLimit?: number - ): number { - const minValue = secondLimit === undefined ? 0 : firstLimit; - const maxValue = secondLimit === undefined ? firstLimit : secondLimit; - const interpolated = maxValue * value; - return lodashClamp(interpolated, minValue, maxValue); - } - /************************************** * Object/array related checks * *************************************/ From 10a7ed8072c33820f6682289bafd2b99970ed36e Mon Sep 17 00:00:00 2001 From: Natasha DeCoste Date: Tue, 9 Jun 2020 12:50:33 -0400 Subject: [PATCH 32/43] add status, arrow direction, theme & remove spacer --- packages/core/demo/data/gauge.ts | 6 +- packages/core/src/chart.ts | 42 +++---- packages/core/src/charts/gauge.ts | 6 +- packages/core/src/components/graphs/gauge.ts | 112 ++++++------------- packages/core/src/configuration.ts | 12 +- packages/core/src/interfaces/charts.ts | 35 +++--- packages/core/src/interfaces/enums.ts | 47 +++++--- packages/core/src/styles/graphs/_gauge.scss | 19 ++++ packages/core/src/styles/graphs/index.scss | 1 + 9 files changed, 133 insertions(+), 147 deletions(-) create mode 100644 packages/core/src/styles/graphs/_gauge.scss diff --git a/packages/core/demo/data/gauge.ts b/packages/core/demo/data/gauge.ts index 7b51ce9c36..a76c19f104 100644 --- a/packages/core/demo/data/gauge.ts +++ b/packages/core/demo/data/gauge.ts @@ -10,7 +10,7 @@ export const gaugeOptionsSemi = { width: "400px", gauge: { type: "semi", - arrowColor: "tomato" + status: "danger" } }; @@ -19,7 +19,7 @@ export const gaugeOptionsCircular = { resizable: true, height: "250px", gauge: { - type: "full", - arrowColor: "tomato" + status: "warning", + type: "full" } }; diff --git a/packages/core/src/chart.ts b/packages/core/src/chart.ts index 7daf4ea48b..692c3c377e 100644 --- a/packages/core/src/chart.ts +++ b/packages/core/src/chart.ts @@ -5,7 +5,7 @@ import { LayoutGrowth, LayoutDirection, LegendOrientations, - Events as ChartEvents, + Events as ChartEvents } from "./interfaces"; // Misc @@ -16,7 +16,7 @@ import { Legend, LayoutComponent, Tooltip, - Spacer, + Spacer } from "./components"; import { Tools } from "./tools"; @@ -28,7 +28,7 @@ export class Chart { services: any = { domUtils: DOMUtils, events: Events, - transitions: Transitions, + transitions: Transitions }; model: ChartModel = new ChartModel(this.services); @@ -119,8 +119,8 @@ export class Chart { components: [new Title(this.model, this.services)], growth: { x: LayoutGrowth.PREFERRED, - y: LayoutGrowth.FIXED, - }, + y: LayoutGrowth.FIXED + } }; const legendComponent = { @@ -128,8 +128,8 @@ export class Chart { components: [new Legend(this.model, this.services)], growth: { x: LayoutGrowth.PREFERRED, - y: LayoutGrowth.FIXED, - }, + y: LayoutGrowth.FIXED + } }; const graphFrameComponent = { @@ -137,8 +137,8 @@ export class Chart { components: graphFrameComponents, growth: { x: LayoutGrowth.STRETCH, - y: LayoutGrowth.FIXED, - }, + y: LayoutGrowth.FIXED + } }; const isLegendEnabled = @@ -176,8 +176,8 @@ export class Chart { components: [new Spacer(this.model, this.services)], growth: { x: LayoutGrowth.PREFERRED, - y: LayoutGrowth.FIXED, - }, + y: LayoutGrowth.FIXED + } }; const fullFrameComponent = { @@ -188,18 +188,18 @@ export class Chart { this.services, [ ...(isLegendEnabled ? [legendComponent] : []), - legendSpacerComponent, - graphFrameComponent, + ...(isLegendEnabled ? [legendSpacerComponent] : []), + graphFrameComponent ], { - direction: fullFrameComponentDirection, + direction: fullFrameComponentDirection } - ), + ) ], growth: { x: LayoutGrowth.STRETCH, - y: LayoutGrowth.FIXED, - }, + y: LayoutGrowth.FIXED + } }; // Add chart title if it exists @@ -212,8 +212,8 @@ export class Chart { components: [new Spacer(this.model, this.services)], growth: { x: LayoutGrowth.PREFERRED, - y: LayoutGrowth.FIXED, - }, + y: LayoutGrowth.FIXED + } }; topLevelLayoutComponents.push(titleSpacerComponent); @@ -226,9 +226,9 @@ export class Chart { this.services, topLevelLayoutComponents, { - direction: LayoutDirection.COLUMN, + direction: LayoutDirection.COLUMN } - ), + ) ]; } } diff --git a/packages/core/src/charts/gauge.ts b/packages/core/src/charts/gauge.ts index df482b446b..7990b9d337 100644 --- a/packages/core/src/charts/gauge.ts +++ b/packages/core/src/charts/gauge.ts @@ -1,5 +1,5 @@ // Internal Imports -import { PieChart } from "./pie"; +import { Chart } from "../chart"; import * as Configuration from "../configuration"; import { ChartConfig, GaugeChartOptions } from "../interfaces/index"; import { Tools } from "../tools"; @@ -11,9 +11,9 @@ import { TooltipPie } from "../components/index"; -export class GaugeChart extends PieChart { +export class GaugeChart extends Chart { constructor(holder: Element, chartConfigs: ChartConfig) { - super(holder, chartConfigs, true); + super(holder, chartConfigs); // Merge the default options for this chart // With the user provided options diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index 6ddf333c22..287311a087 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -1,13 +1,17 @@ // Internal Imports import { Component } from "../component"; import { DOMUtils } from "../../services"; -import { Roles, TooltipTypes, Events, GaugeTypes } from "../../interfaces"; +import { Roles, TooltipTypes, Events, GaugeTypes, Statuses, ArrowDirections } from "../../interfaces"; import { Tools } from "../../tools"; // D3 Imports import { select } from "d3-selection"; import { arc } from "d3-shape"; +// arrow paths for delta +const ARROW_UP = "4,10 8,6 12,10"; +const ARROW_DOWN = "12,6 8,10 4,6"; + export class Gauge extends Component { type = "gauge"; @@ -15,23 +19,10 @@ export class Gauge extends Component { // So that addEventListeners() // Can access them arc: any; - hoverArc: any; backgroundArc: any; init() { const eventsFragment = this.services.events; - - // Highlight correct circle on legend item hovers - eventsFragment.addEventListener( - "legend-item-onhover", - this.handleLegendOnHover - ); - - // Un-highlight circles on legend item mouseouts - eventsFragment.addEventListener( - "legend-item-onmouseout", - this.handleLegendMouseOut - ); } getValue(): number { @@ -72,6 +63,7 @@ export class Gauge extends Component { } render(animate = true) { + const self = this; const svg = this.getContainerSVG(); const options = this.model.getOptions(); const value = this.getValue(); @@ -110,35 +102,21 @@ export class Gauge extends Component { .startAngle(startAngle) .endAngle(currentAngle); - const outerRadiusOffset = Tools.getProperty(options, "gauge", "hoverArc", "outerRadiusOffset"); - // Set the hover arc radius - this.hoverArc = arc() - .innerRadius(innerRadius) - .outerRadius(radius + outerRadiusOffset ) - .startAngle(startAngle) - .endAngle(currentAngle); - - // Add background arc - + // draw the container DOMUtils.appendOrSelect(svg, "path.arc-background") .attr("d", this.backgroundArc) - .attr("fill", Tools.getProperty(options, "gauge", "arcBackgroundColor")) .attr("role", Roles.GROUP); // Add data arc DOMUtils.appendOrSelect(svg, "path.arc-foreground") .attr("d", this.arc) .classed("arc", true) - .attr("fill", Tools.getProperty(options, "gauge", "arcForegroundColor")); + .attr("fill", Tools.getProperty(options, "gauge", "fillColor")); // Position Arc - const gaugeTranslateX = - radius + outerRadiusOffset; // Leaves space for the hover animation - const gaugeTranslateY = - radius + outerRadiusOffset; svg.attr( "transform", - `translate(${gaugeTranslateX}, ${gaugeTranslateY})` + `translate(${radius}, ${radius})` ); // Add the numbers at the center @@ -202,22 +180,38 @@ export class Gauge extends Component { .attr("height", arrowSize) .attr("viewBox", `0 0 16 16`); - // arrow paths for delta - const ARROW_UP = "4,10 8,6 12,10"; - const ARROW_DOWN = "12,6 8,10 4,6"; + + const status = Tools.getProperty(options, "gauge", "status"); DOMUtils.appendOrSelect(deltaArrow, "rect.gauge-delta-arrow-backdrop") // Needed to correctly size SVG in Firefox .attr("width", `16`) .attr("height", `16`) .attr("fill", "none"); - DOMUtils.appendOrSelect(deltaArrow, "polygon.gauge-delta-arrow-polygon") - .attr("points", delta > 0 ? ARROW_UP : ARROW_DOWN) - .attr("fill", Tools.getProperty(options, "gauge", "arrowColor")); + // draw the arrow with status + DOMUtils.appendOrSelect(deltaArrow, "polygon.gauge-delta-arrow-polygon") + .classed(`status--${status}`, status != null ) + .attr("fill", () => status == null ? "currentColor" : null ) + .attr("points", self.getArrow(delta)); // Add event listeners this.addEventListeners(); } + // use provided arrow direction or default to using the delta + getArrow(delta): string { + const options = this.model.getOptions(); + const arrowDirection = Tools.getProperty(options, "gauge", "arrowDirection"); + + switch (arrowDirection) { + case ArrowDirections.UP: + return ARROW_UP; + case ArrowDirections.DOWN: + return ARROW_DOWN; + default: + return delta > 0 ? ARROW_UP : ARROW_DOWN; + } + } + getInnerRadius() { // Compute the outer radius needed const radius = this.computeRadius(); @@ -225,30 +219,6 @@ export class Gauge extends Component { return radius - arcWidth; } - // Highlight elements that match the hovered legend item - handleLegendOnHover = (event: CustomEvent) => { - const { hoveredElement } = event.detail; - - this.parent - .selectAll("path.arc") - .transition( - this.services.transitions.getTransition("legend-hover-bar") - ) - .attr("opacity", (d) => - d.data.label !== hoveredElement.datum()["key"] ? 0.3 : 1 - ); - } - - // Un-highlight all elements - handleLegendMouseOut = (event: CustomEvent) => { - this.parent - .selectAll("path.arc") - .transition( - this.services.transitions.getTransition("legend-mouseout-bar") - ) - .attr("opacity", 1); - } - addEventListeners() { const self = this; this.parent @@ -263,15 +233,6 @@ export class Gauge extends Component { .on("mousemove", function(datum) { const hoveredElement = select(this); - hoveredElement - .classed("hovered", true) - .transition( - self.services.transitions.getTransition( - "pie_slice_mouseover" - ) - ) - .attr("d", self.hoverArc); - // Dispatch mouse event self.services.events.dispatchEvent(Events.Gauge.ARC_MOUSEMOVE, { element: hoveredElement, @@ -293,14 +254,6 @@ export class Gauge extends Component { }) .on("mouseout", function(datum) { const hoveredElement = select(this); - hoveredElement - .classed("hovered", false) - .transition( - self.services.transitions.getTransition( - "gauge_slice_mouseover" - ) - ) - .attr("d", self.arc); // Dispatch mouse event self.services.events.dispatchEvent(Events.Gauge.ARC_MOUSEOUT, { @@ -319,7 +272,6 @@ export class Gauge extends Component { protected computeRadius() { const options = this.model.getOptions(); const arcType = Tools.getProperty(options, "gauge", "arcType"); - const outerRadiusOffset = Tools.getProperty(options, "gauge", "hoverArc", "outerRadiusOffset"); const { width, height } = DOMUtils.getSVGElementSize(this.parent, { useAttrs: true @@ -329,6 +281,6 @@ export class Gauge extends Component { ? Math.min(width / 2, height) : Math.min(width / 2, height / 2); - return radius - outerRadiusOffset; + return radius; } } diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index c5994e5a7e..b33911c61c 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -293,20 +293,16 @@ const pieChart: PieChartOptions = Tools.merge({}, chart, { * options specific to gauge charts */ -const gaugeChart: GaugeChartOptions = Tools.merge({}, pieChart, { +const gaugeChart: GaugeChartOptions = Tools.merge({}, chart, { legend: { enabled: false }, gauge: { type: GaugeTypes.SEMI, arcWidth: 16, - arcBackgroundColor: "rgb(224,224,224)", - arcForegroundColor: "rgb(88,134,247)", - arrowColor: "currentColor", - numberFormatter: (number) => number.toFixed(2).toLocaleString(), - hoverArc: { - outerRadiusOffset: 3 - } + fillColor: "rgb(88,134,247)", + status: null, + numberFormatter: (number) => (number.toFixed(2) % 1 !== 0) ? number.toFixed(2).toLocaleString() : number.toFixed().toLocaleString() } } as GaugeChartOptions); diff --git a/packages/core/src/interfaces/charts.ts b/packages/core/src/interfaces/charts.ts index 15c6539175..2a4acffd99 100644 --- a/packages/core/src/interfaces/charts.ts +++ b/packages/core/src/interfaces/charts.ts @@ -1,15 +1,19 @@ -import { GaugeTypes } from "./enums"; +import { + GaugeTypes, + Statuses, + ArrowDirections +} from "./enums"; import { LegendOptions, TooltipOptions, GridOptions, - AxesOptions, + AxesOptions } from "./index"; import { AxisTooltipOptions, BarTooltipOptions, BarOptions, - StackedBarOptions, + StackedBarOptions } from "./components"; /** @@ -177,10 +181,10 @@ export interface LineChartOptions extends ScatterChartOptions { * options for the curve of the line */ curve?: - | string - | { - name: string; - }; + | string + | { + name: string; + }; } /** @@ -191,10 +195,10 @@ export interface AreaChartOptions extends AxisChartOptions { * options for the curve of the line */ curve?: - | string - | { - name: string; - }; + | string + | { + name: string; + }; } /** @@ -230,13 +234,10 @@ export interface PieChartOptions extends BaseChartOptions { export interface GaugeChartOptions extends PieChartOptions { gauge?: { arcWidth?: number; - arcBackgroundColor?: string; - arcForegroundColor?: string; - arrowColor?: string; + fillColor?: string; + status?: Statuses; + arrowDirection?: ArrowDirections; numberFormatter?: Function; - hoverArc?: { - outerRadiusOffset?: number; - }; type?: GaugeTypes; }; } diff --git a/packages/core/src/interfaces/enums.ts b/packages/core/src/interfaces/enums.ts index dc80e9d04a..420bffa9f8 100644 --- a/packages/core/src/interfaces/enums.ts +++ b/packages/core/src/interfaces/enums.ts @@ -8,7 +8,7 @@ export enum ChartTheme { DEFAULT = "default", G100 = "g100", G90 = "g90", - G10 = "g10", + G10 = "g10" } /** @@ -18,7 +18,7 @@ export enum AxisPositions { LEFT = "left", RIGHT = "right", TOP = "top", - BOTTOM = "bottom", + BOTTOM = "bottom" } /** @@ -29,7 +29,7 @@ export enum AxisPositions { */ export enum CartesianOrientations { VERTICAL = "vertical", - HORIZONTAL = "horizontal", + HORIZONTAL = "horizontal" } /** @@ -39,7 +39,7 @@ export enum ScaleTypes { TIME = "time", LINEAR = "linear", LOG = "log", - LABELS = "labels", + LABELS = "labels" } /** @@ -48,7 +48,7 @@ export enum ScaleTypes { export enum TooltipPosition { MOUSE = "mouse", TOP = "top", - BOTTOM = "bottom", + BOTTOM = "bottom" } /** @@ -57,7 +57,7 @@ export enum TooltipPosition { export enum TooltipTypes { DATAPOINT = "datapoint", GRIDLINE = "gridline", - TITLE = "title", + TITLE = "title" } /** @@ -67,7 +67,7 @@ export enum LegendPositions { RIGHT = "right", LEFT = "left", TOP = "top", - BOTTOM = "bottom", + BOTTOM = "bottom" } /** @@ -75,7 +75,7 @@ export enum LegendPositions { */ export enum LegendOrientations { HORIZONTAL = "horizontal", - VERTICAL = "vertical", + VERTICAL = "vertical" } /** @@ -85,7 +85,7 @@ export enum LayoutDirection { ROW = "row", COLUMN = "column", ROW_REVERSE = "row-reverse", - COLUMN_REVERSE = "column-reverse", + COLUMN_REVERSE = "column-reverse" } /** @@ -94,7 +94,7 @@ export enum LayoutDirection { export enum LayoutGrowth { FIXED = "fixed", PREFERRED = "preferred", - STRETCH = "stretch", + STRETCH = "stretch" } /** @@ -102,7 +102,7 @@ export enum LayoutGrowth { */ export enum CalloutDirections { LEFT = "left", - RIGHT = "right", + RIGHT = "right" } /** @@ -112,7 +112,7 @@ export enum Skeletons { GRID = "grid", VERT_OR_HORIZ = "vertOrHoriz", PIE = "pie", - DONUT = "donut", + DONUT = "donut" } /** @@ -121,7 +121,7 @@ export enum Skeletons { export enum TextAnchor { START = "start", MIDDLE = "middle", - END = "end", + END = "end" } /** @@ -130,10 +130,27 @@ export enum TextAnchor { export enum DominantBaseline { BASELINE = "baseline", MIDDLE = "middle", - HANGING = "hanging", + HANGING = "hanging" } export enum GaugeTypes { SEMI = "semi", - FULL = "full", + FULL = "full" +} + +/** + * enum of all possible callout directions + */ +export enum ArrowDirections { + UP = "up", + DOWN = "down" +} + +/** + * enum of carbon statuses + */ +export enum Statuses { + SUCCESS = "success", + WARNING = "warning", + DANGER = "danger" } diff --git a/packages/core/src/styles/graphs/_gauge.scss b/packages/core/src/styles/graphs/_gauge.scss new file mode 100644 index 0000000000..670df43d9d --- /dev/null +++ b/packages/core/src/styles/graphs/_gauge.scss @@ -0,0 +1,19 @@ +.#{$prefix}--#{$charts-prefix}--gauge { + path.arc-background { + fill: $ui-01; + } + + .gauge-delta-arrow-polygon { + &.status--danger { + fill: $support-01; + } + + &.status--warning { + fill: $support-03; + } + + &.status--success { + fill: $support-02; + } + } +} diff --git a/packages/core/src/styles/graphs/index.scss b/packages/core/src/styles/graphs/index.scss index d3d721507f..07ccce5d7d 100644 --- a/packages/core/src/styles/graphs/index.scss +++ b/packages/core/src/styles/graphs/index.scss @@ -3,3 +3,4 @@ @import "./line"; @import "./scatter"; @import "./radar"; +@import "./gauge"; From e5b8aad25af8291bd46dd31b3faa7ed629066e2a Mon Sep 17 00:00:00 2001 From: Natasha DeCoste Date: Tue, 9 Jun 2020 13:34:34 -0400 Subject: [PATCH 33/43] fix guage to work without delta --- packages/core/src/components/graphs/gauge.ts | 85 ++++++++++++-------- 1 file changed, 50 insertions(+), 35 deletions(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index 287311a087..a8ae2c6f5f 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -37,7 +37,8 @@ export class Gauge extends Component { getDelta(): number { const data = this.model.getData(); - return data.find((d) => d.group === "delta").value; + const delta = data.find((d) => d.group === "delta"); + return delta ? delta.value : null; } getArcRatio(): number { @@ -62,6 +63,22 @@ export class Gauge extends Component { return -arcSize / 2; } + // use provided arrow direction or default to using the delta + getArrow(delta): string { + const options = this.model.getOptions(); + const arrowDirection = Tools.getProperty(options, "gauge", "arrowDirection"); + + switch (arrowDirection) { + case ArrowDirections.UP: + return ARROW_UP; + case ArrowDirections.DOWN: + return ARROW_DOWN; + default: + return delta > 0 ? ARROW_UP : ARROW_DOWN; + } + } + + render(animate = true) { const self = this; const svg = this.getContainerSVG(); @@ -143,14 +160,14 @@ export class Gauge extends Component { const { width: valueNumberWidth } = DOMUtils.getSVGElementSize(valueNumber, { useBBox: true }); + DOMUtils.appendOrSelect(valueNumberG, "text.gauge-value-symbol") .style("font-size", `${valueFontSize / 2}px`) .attr("x", valueNumberWidth / 2) .text("%"); - // Add the smaller number of the delta - const deltaNumberG = DOMUtils.appendOrSelect( + const deltaGroup = DOMUtils.appendOrSelect( numbersG, "g.gauge-delta" ).attr( @@ -158,58 +175,56 @@ export class Gauge extends Component { `translate(0, ${deltaFontSize + distanceBetweenNumbers})` ); - const deltaNumber = DOMUtils.appendOrSelect( - deltaNumberG, - "text.gauge-delta-number" - ) + console.log(delta); + const deltaNumber = deltaGroup.selectAll("text.gauge-delta-number") + .data(delta != null ? [delta] : []); + + deltaNumber + .enter() + .append("text") + .merge(deltaNumber) + .attr("class", "gauge-delta-number") .attr("text-anchor", "middle") .style("font-size", `${deltaFontSize}px`) - .text(`${numberFormatter(delta)}%`); + .text(d => `${numberFormatter(d)}%`); // Add the caret for the delta number const { width: deltaNumberWidth - } = DOMUtils.getSVGElementSize(deltaNumber, { useBBox: true }); - const deltaArrow = DOMUtils.appendOrSelect( - deltaNumberG, - "svg.gauge-delta-arrow" - ) + } = DOMUtils.getSVGElementSize(DOMUtils.appendOrSelect(svg, "g.gauge-delta"), { useBBox: true }); + + const deltaArrow = deltaGroup.selectAll("svg.gauge-delta-arrow") + .data(delta != null ? [delta] : []); + + deltaArrow + .enter() + .append("svg") + .merge(deltaArrow) + .attr("class", "gauge-delta-arrow") .attr("x", -arrowSize - deltaNumberWidth / 2) .attr("y", -arrowSize / 2 - deltaFontSize * 0.35) .attr("width", arrowSize) .attr("height", arrowSize) .attr("viewBox", `0 0 16 16`); - - const status = Tools.getProperty(options, "gauge", "status"); - - DOMUtils.appendOrSelect(deltaArrow, "rect.gauge-delta-arrow-backdrop") // Needed to correctly size SVG in Firefox + // Needed to correctly size SVG in Firefox + DOMUtils.appendOrSelect(deltaArrow, "rect.gauge-delta-arrow-backdrop") .attr("width", `16`) .attr("height", `16`) .attr("fill", "none"); - // draw the arrow with status + // Draw the arrow with status + const status = Tools.getProperty(options, "gauge", "status"); DOMUtils.appendOrSelect(deltaArrow, "polygon.gauge-delta-arrow-polygon") - .classed(`status--${status}`, status != null ) - .attr("fill", () => status == null ? "currentColor" : null ) + .classed(`status--${status}`, status != null) + .attr("fill", () => status == null ? "currentColor" : null) .attr("points", self.getArrow(delta)); - // Add event listeners - this.addEventListeners(); - } - // use provided arrow direction or default to using the delta - getArrow(delta): string { - const options = this.model.getOptions(); - const arrowDirection = Tools.getProperty(options, "gauge", "arrowDirection"); + deltaArrow.exit().remove(); + deltaNumber.exit().remove(); - switch (arrowDirection) { - case ArrowDirections.UP: - return ARROW_UP; - case ArrowDirections.DOWN: - return ARROW_DOWN; - default: - return delta > 0 ? ARROW_UP : ARROW_DOWN; - } + // Add event listeners + this.addEventListeners(); } getInnerRadius() { From f05e3a65a45fe8c7ff9b286e20adeb73c1849224 Mon Sep 17 00:00:00 2001 From: Natasha DeCoste Date: Tue, 9 Jun 2020 14:05:58 -0400 Subject: [PATCH 34/43] add enter/merge/exit for value and delta --- packages/core/src/components/graphs/gauge.ts | 35 ++++++++++++++------ packages/core/src/configuration.ts | 3 +- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index a8ae2c6f5f..5c589f28a5 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -124,11 +124,22 @@ export class Gauge extends Component { .attr("d", this.backgroundArc) .attr("role", Roles.GROUP); + // Add data arc - DOMUtils.appendOrSelect(svg, "path.arc-foreground") + const arcValue = svg.selectAll("path.arc-foreground") + .data([value]); + + arcValue + .enter() + .append("path") + .attr("class", "arc-foreground") + .merge(arcValue) .attr("d", this.arc) - .classed("arc", true) - .attr("fill", Tools.getProperty(options, "gauge", "fillColor")); + .attr("fill", Tools.getProperty(options, "gauge", "fillColor")) + // a11y + .attr("role", Roles.GRAPHICS_SYMBOL) + .attr("aria-roledescription", "value") + .attr("aria-label", d => d.value); // Position Arc svg.attr( @@ -149,17 +160,21 @@ export class Gauge extends Component { ).attr("transform", `translate(-10, 0)`); // Optical centering for the presence of the smaller % symbol const numberFormatter = Tools.getProperty(options, "gauge", "numberFormatter"); - const valueNumber = DOMUtils.appendOrSelect( - valueNumberG, - "text.gauge-value-number" - ) + const valueNumber = valueNumberG.selectAll("text.gauge-value-number") + .data([value]); + + valueNumber + .enter() + .append("text") + .attr("class", "gauge-value-number") + .merge(valueNumber) .style("font-size", `${valueFontSize}px`) .attr("text-anchor", "middle") - .text(`${numberFormatter(value)}`); + .text(d => `${numberFormatter(d)}`); const { width: valueNumberWidth - } = DOMUtils.getSVGElementSize(valueNumber, { useBBox: true }); + } = DOMUtils.getSVGElementSize(DOMUtils.appendOrSelect(svg, "text.gauge-value-number"), { useBBox: true }); DOMUtils.appendOrSelect(valueNumberG, "text.gauge-value-symbol") .style("font-size", `${valueFontSize / 2}px`) @@ -175,7 +190,6 @@ export class Gauge extends Component { `translate(0, ${deltaFontSize + distanceBetweenNumbers})` ); - console.log(delta); const deltaNumber = deltaGroup.selectAll("text.gauge-delta-number") .data(delta != null ? [delta] : []); @@ -222,6 +236,7 @@ export class Gauge extends Component { deltaArrow.exit().remove(); deltaNumber.exit().remove(); + arcValue.exit().remove(); // Add event listeners this.addEventListeners(); diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index b33911c61c..0edd7abf17 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -25,6 +25,7 @@ import { GaugeTypes } from "./interfaces"; import enUSLocaleObject from "date-fns/locale/en-US/index"; +import * as colorPalettes from "./services/colorPalettes"; /* ***************************** @@ -300,7 +301,7 @@ const gaugeChart: GaugeChartOptions = Tools.merge({}, chart, { gauge: { type: GaugeTypes.SEMI, arcWidth: 16, - fillColor: "rgb(88,134,247)", + fillColor: colorPalettes.DEFAULT[1], status: null, numberFormatter: (number) => (number.toFixed(2) % 1 !== 0) ? number.toFixed(2).toLocaleString() : number.toFixed().toLocaleString() } From 804a7418e95a1162cb16d16a45827df616bbeb6c Mon Sep 17 00:00:00 2001 From: natashadecoste Date: Tue, 9 Jun 2020 14:48:26 -0400 Subject: [PATCH 35/43] Update packages/core/src/components/graphs/gauge.ts Co-authored-by: Eliad Moosavi --- packages/core/src/components/graphs/gauge.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index 5c589f28a5..474f0e56d3 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -170,7 +170,7 @@ export class Gauge extends Component { .merge(valueNumber) .style("font-size", `${valueFontSize}px`) .attr("text-anchor", "middle") - .text(d => `${numberFormatter(d)}`); + .text(d => numberFormatter(d)); const { width: valueNumberWidth From fad76cdca0cf5769f894f9602e13dbca6e77b665 Mon Sep 17 00:00:00 2001 From: natashadecoste Date: Wed, 10 Jun 2020 15:32:29 -0400 Subject: [PATCH 36/43] Update packages/core/src/configuration.ts Co-authored-by: Donisius Wigie <45505172+Donisius@users.noreply.github.com> --- packages/core/src/configuration.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 0edd7abf17..9f73557edd 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -293,7 +293,6 @@ const pieChart: PieChartOptions = Tools.merge({}, chart, { /** * options specific to gauge charts */ - const gaugeChart: GaugeChartOptions = Tools.merge({}, chart, { legend: { enabled: false From bec664cbf0887ac65e03748dbea3523d28d98861 Mon Sep 17 00:00:00 2001 From: Natasha DeCoste Date: Fri, 12 Jun 2020 18:59:47 -0400 Subject: [PATCH 37/43] review changes --- packages/core/demo/data/gauge.ts | 28 +++- packages/core/demo/data/index.ts | 6 + packages/core/src/components/graphs/gauge.ts | 144 ++++++++++++------- packages/core/src/configuration.ts | 6 +- packages/core/src/interfaces/charts.ts | 5 +- 5 files changed, 131 insertions(+), 58 deletions(-) diff --git a/packages/core/demo/data/gauge.ts b/packages/core/demo/data/gauge.ts index a76c19f104..a26749d2ae 100644 --- a/packages/core/demo/data/gauge.ts +++ b/packages/core/demo/data/gauge.ts @@ -3,19 +3,25 @@ export const gaugeData = [ { group: "delta", value: -13.37 } ]; +export const gaugeDataNoDelta = [ + { group: "value", value: 67 } +]; + +// guage no custom color export const gaugeOptionsSemi = { - title: "Gauge semicircular", + title: "Gauge semicircular -- danger status", resizable: true, height: "250px", - width: "400px", + width: "100%", gauge: { type: "semi", status: "danger" } }; +// guage with custom color export const gaugeOptionsCircular = { - title: "Gauge circular", + title: "Gauge circular -- warning status", resizable: true, height: "250px", gauge: { @@ -23,3 +29,19 @@ export const gaugeOptionsCircular = { type: "full" } }; + + +// guage with custom color +export const gaugeOptionsCircularNoDelta = { + title: "Gauge circular without delta", + resizable: true, + height: "250px", + gauge: { + type: "full" + }, + color: { + scale: { + "value": "#891EE8" + } + } +}; diff --git a/packages/core/demo/data/index.ts b/packages/core/demo/data/index.ts index 47171bc775..39229adc89 100644 --- a/packages/core/demo/data/index.ts +++ b/packages/core/demo/data/index.ts @@ -432,6 +432,12 @@ let allDemoGroups = [ data: gaugeDemos.gaugeData, chartType: chartTypes.GaugeChart, isDemoExample: true + }, + { + options: gaugeDemos.gaugeOptionsCircularNoDelta, + data: gaugeDemos.gaugeDataNoDelta, + chartType: chartTypes.GaugeChart, + isDemoExample: true } ] }, diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index 474f0e56d3..563a4702b5 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -9,8 +9,8 @@ import { select } from "d3-selection"; import { arc } from "d3-shape"; // arrow paths for delta -const ARROW_UP = "4,10 8,6 12,10"; -const ARROW_DOWN = "12,6 8,10 4,6"; +const ARROW_UP_PATH_STRING = "4,10 8,6 12,10"; +const ARROW_DOWN_PATH_STRING = "12,6 8,10 4,6"; export class Gauge extends Component { type = "gauge"; @@ -27,7 +27,8 @@ export class Gauge extends Component { getValue(): number { const data = this.model.getData(); - return data.find((d) => d.group === "value").value; + const value = data.find((d) => d.group === "value")?.value ?? null; + return value; } getValueRatio(): number { @@ -37,17 +38,14 @@ export class Gauge extends Component { getDelta(): number { const data = this.model.getData(); - const delta = data.find((d) => d.group === "delta"); - return delta ? delta.value : null; + const delta = data.find((d) => d.group === "delta")?.value ?? null; + return delta; } getArcRatio(): number { const options = this.model.getOptions(); const type = Tools.getProperty(options, "gauge", "type"); const arcRatio = type === GaugeTypes.FULL ? 1 : 0.5; - if (arcRatio === undefined) { - throw new Error("Gauge chart arc type not compatible"); - } return arcRatio; } @@ -70,11 +68,11 @@ export class Gauge extends Component { switch (arrowDirection) { case ArrowDirections.UP: - return ARROW_UP; + return ARROW_UP_PATH_STRING; case ArrowDirections.DOWN: - return ARROW_DOWN; + return ARROW_DOWN_PATH_STRING; default: - return delta > 0 ? ARROW_UP : ARROW_DOWN; + return delta > 0 ? ARROW_UP_PATH_STRING : ARROW_DOWN_PATH_STRING; } } @@ -83,11 +81,13 @@ export class Gauge extends Component { const self = this; const svg = this.getContainerSVG(); const options = this.model.getOptions(); + const { groupMapsTo } = options.data; + const value = this.getValue(); const valueRatio = this.getValueRatio(); - const delta = this.getDelta(); const arcSize = this.getArcSize(); - const arcType = Tools.getProperty(options, "gauge", "arcType"); + + // angles for drawing the gauge const startAngle = this.getStartAngle(); const rotationAngle = valueRatio * arcSize; const currentAngle = startAngle + rotationAngle; @@ -97,16 +97,7 @@ export class Gauge extends Component { const radius = this.computeRadius(); const innerRadius = this.getInnerRadius(); - // Sizing and positions relative to the radius - const arrowSize = radius / 8; - const valueFontSize = radius / 2.5; - const deltaFontSize = radius / 8; - const distanceBetweenNumbers = 10; - const numbersYPosition = - arcType === GaugeTypes.SEMI - ? -(deltaFontSize + distanceBetweenNumbers) - : 0; - + // draw the container and arc this.backgroundArc = arc() .innerRadius(innerRadius) .outerRadius(radius) @@ -124,7 +115,6 @@ export class Gauge extends Component { .attr("d", this.backgroundArc) .attr("role", Roles.GROUP); - // Add data arc const arcValue = svg.selectAll("path.arc-foreground") .data([value]); @@ -135,7 +125,7 @@ export class Gauge extends Component { .attr("class", "arc-foreground") .merge(arcValue) .attr("d", this.arc) - .attr("fill", Tools.getProperty(options, "gauge", "fillColor")) + .attr("fill", d => self.model.getFillColor(d[groupMapsTo])) // a11y .attr("role", Roles.GRAPHICS_SYMBOL) .attr("aria-roledescription", "value") @@ -147,20 +137,54 @@ export class Gauge extends Component { `translate(${radius}, ${radius})` ); + // draw the value and delta to the center + this.drawValueNumber(); + this.drawDelta(); + + arcValue.exit().remove(); + + // Add event listeners + this.addEventListeners(); + } + + /** + * draws the value number associated with the Gauge component in the center + */ + drawValueNumber() { + const svg = this.getContainerSVG(); + const options = this.model.getOptions(); + + const arcType = Tools.getProperty(options, "gauge", "type"); + const value = this.getValue(); + const delta = this.getDelta(); + + // Sizing and positions relative to the radius + const radius = this.computeRadius(); + + const valueFontSize = Tools.getProperty(options, "gauge", "valueFontSize"); + // if there is a delta, use the size to center the numbers, otherwise center the valueNumber + const deltaFontSize = Tools.getProperty(options, "gauge", "deltaFontSize"); + + // circular gauge without delta should have valueNumber centered + let numbersYPosition = 0; + if (arcType === GaugeTypes.FULL && !delta) { + numbersYPosition = deltaFontSize(radius); + } + // Add the numbers at the center - const numbersG = DOMUtils.appendOrSelect(svg, "g.gauge-numbers").attr( + const numbersGroup = DOMUtils.appendOrSelect(svg, "g.gauge-numbers").attr( "transform", `translate(0, ${numbersYPosition})` ); // Add the big number - const valueNumberG = DOMUtils.appendOrSelect( - numbersG, + const valueNumberGroup = DOMUtils.appendOrSelect( + numbersGroup, "g.gauge-value-number" - ).attr("transform", `translate(-10, 0)`); // Optical centering for the presence of the smaller % symbol + ).attr("transform", "translate(-10, 0)"); // Optical centering for the presence of the smaller % symbol const numberFormatter = Tools.getProperty(options, "gauge", "numberFormatter"); - const valueNumber = valueNumberG.selectAll("text.gauge-value-number") + const valueNumber = valueNumberGroup.selectAll("text.gauge-value-number") .data([value]); valueNumber @@ -168,26 +192,46 @@ export class Gauge extends Component { .append("text") .attr("class", "gauge-value-number") .merge(valueNumber) - .style("font-size", `${valueFontSize}px`) + .style("font-size", `${valueFontSize(radius)}px`) .attr("text-anchor", "middle") .text(d => numberFormatter(d)); + // add the percentage symbol beside the valueNumber const { width: valueNumberWidth } = DOMUtils.getSVGElementSize(DOMUtils.appendOrSelect(svg, "text.gauge-value-number"), { useBBox: true }); - DOMUtils.appendOrSelect(valueNumberG, "text.gauge-value-symbol") - .style("font-size", `${valueFontSize / 2}px`) + DOMUtils.appendOrSelect(valueNumberGroup, "text.gauge-value-symbol") + .style("font-size", `${valueFontSize(radius) / 2}px`) .attr("x", valueNumberWidth / 2) .text("%"); + } + + /** + * adds the delta number for the gauge + */ + drawDelta() { + const self = this; + const svg = this.getContainerSVG(); + const options = this.model.getOptions(); + const delta = this.getDelta(); + + // Sizing and positions relative to the radius + const radius = this.computeRadius(); + const deltaFontSize = delta ? Tools.getProperty(options, "gauge", "deltaFontSize") : () => 0; + const numberFormatter = Tools.getProperty(options, "gauge", "numberFormatter"); + const arrowSize = Tools.getProperty(options, "gauge", "arrowSize"); + const numberKerning = Tools.getProperty(options, "gauge", "numberKerning"); + + const numbersGroup = DOMUtils.appendOrSelect(svg, "g.gauge-numbers"); // Add the smaller number of the delta const deltaGroup = DOMUtils.appendOrSelect( - numbersG, + numbersGroup, "g.gauge-delta" ).attr( "transform", - `translate(0, ${deltaFontSize + distanceBetweenNumbers})` + `translate(0, ${deltaFontSize(radius) + numberKerning})` ); const deltaNumber = deltaGroup.selectAll("text.gauge-delta-number") @@ -199,7 +243,7 @@ export class Gauge extends Component { .merge(deltaNumber) .attr("class", "gauge-delta-number") .attr("text-anchor", "middle") - .style("font-size", `${deltaFontSize}px`) + .style("font-size", `${deltaFontSize(radius)}px`) .text(d => `${numberFormatter(d)}%`); // Add the caret for the delta number @@ -215,16 +259,16 @@ export class Gauge extends Component { .append("svg") .merge(deltaArrow) .attr("class", "gauge-delta-arrow") - .attr("x", -arrowSize - deltaNumberWidth / 2) - .attr("y", -arrowSize / 2 - deltaFontSize * 0.35) - .attr("width", arrowSize) - .attr("height", arrowSize) - .attr("viewBox", `0 0 16 16`); + .attr("x", -arrowSize(radius) - deltaNumberWidth / 2) + .attr("y", -arrowSize(radius) / 2 - deltaFontSize(radius) * 0.35) + .attr("width", arrowSize(radius)) + .attr("height", arrowSize(radius)) + .attr("viewBox", "0 0 16 16"); // Needed to correctly size SVG in Firefox DOMUtils.appendOrSelect(deltaArrow, "rect.gauge-delta-arrow-backdrop") - .attr("width", `16`) - .attr("height", `16`) + .attr("width", "16") + .attr("height", "16") .attr("fill", "none"); // Draw the arrow with status @@ -236,10 +280,6 @@ export class Gauge extends Component { deltaArrow.exit().remove(); deltaNumber.exit().remove(); - arcValue.exit().remove(); - - // Add event listeners - this.addEventListeners(); } getInnerRadius() { @@ -253,14 +293,14 @@ export class Gauge extends Component { const self = this; this.parent .selectAll("path.arc") - .on("mouseover", function(datum) { + .on("mouseover", function (datum) { // Dispatch mouse event self.services.events.dispatchEvent(Events.Gauge.ARC_MOUSEOVER, { element: select(this), datum }); }) - .on("mousemove", function(datum) { + .on("mousemove", function (datum) { const hoveredElement = select(this); // Dispatch mouse event @@ -275,14 +315,14 @@ export class Gauge extends Component { type: TooltipTypes.DATAPOINT }); }) - .on("click", function(datum) { + .on("click", function (datum) { // Dispatch mouse event self.services.events.dispatchEvent(Events.Gauge.ARC_CLICK, { element: select(this), datum }); }) - .on("mouseout", function(datum) { + .on("mouseout", function (datum) { const hoveredElement = select(this); // Dispatch mouse event @@ -301,7 +341,7 @@ export class Gauge extends Component { // Helper functions protected computeRadius() { const options = this.model.getOptions(); - const arcType = Tools.getProperty(options, "gauge", "arcType"); + const arcType = Tools.getProperty(options, "gauge", "type"); const { width, height } = DOMUtils.getSVGElementSize(this.parent, { useAttrs: true diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 09695a217a..349994f7a5 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -25,7 +25,6 @@ import { GaugeTypes } from "./interfaces"; import enUSLocaleObject from "date-fns/locale/en-US/index"; -import * as colorPalettes from "./services/colorPalettes"; /* ***************************** @@ -305,8 +304,11 @@ const gaugeChart: GaugeChartOptions = Tools.merge({}, chart, { gauge: { type: GaugeTypes.SEMI, arcWidth: 16, - fillColor: colorPalettes.DEFAULT[1], status: null, + numberKerning: 10, + valueFontSize: (radius) => radius / 2.5, + deltaFontSize: (radius) => radius / 8, + arrowSize: (radius) => radius / 8, numberFormatter: (number) => (number.toFixed(2) % 1 !== 0) ? number.toFixed(2).toLocaleString() : number.toFixed().toLocaleString() } } as GaugeChartOptions); diff --git a/packages/core/src/interfaces/charts.ts b/packages/core/src/interfaces/charts.ts index dad81afb5d..7d00dc4eef 100644 --- a/packages/core/src/interfaces/charts.ts +++ b/packages/core/src/interfaces/charts.ts @@ -248,10 +248,13 @@ export interface PieChartOptions extends BaseChartOptions { export interface GaugeChartOptions extends PieChartOptions { gauge?: { arcWidth?: number; - fillColor?: string; status?: Statuses; arrowDirection?: ArrowDirections; numberFormatter?: Function; + valueFontSize?: Function; + deltaFontSize?: Function; + arrowSize?: Function; + numberKerning?: number; type?: GaugeTypes; }; } From c6695350d9ea34e74bab7a6cf55404f3bf2ee57c Mon Sep 17 00:00:00 2001 From: natashadecoste Date: Wed, 17 Jun 2020 09:47:22 -0400 Subject: [PATCH 38/43] Update packages/core/src/components/graphs/gauge.ts Co-authored-by: Donisius Wigie <45505172+Donisius@users.noreply.github.com> --- packages/core/src/components/graphs/gauge.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index 563a4702b5..7804788cad 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -15,9 +15,7 @@ const ARROW_DOWN_PATH_STRING = "12,6 8,10 4,6"; export class Gauge extends Component { type = "gauge"; - // We need to store our arcs - // So that addEventListeners() - // Can access them + // We need to store our arcs so that addEventListeners() can access them arc: any; backgroundArc: any; From e0af40a529e7f928beb7508d962070cf2b402298 Mon Sep 17 00:00:00 2001 From: Natasha DeCoste Date: Wed, 17 Jun 2020 10:03:24 -0400 Subject: [PATCH 39/43] review comments + prettier --- packages/core/demo/data/gauge.ts | 7 +- packages/core/src/components/graphs/gauge.ts | 113 +++++++++++++------ 2 files changed, 80 insertions(+), 40 deletions(-) diff --git a/packages/core/demo/data/gauge.ts b/packages/core/demo/data/gauge.ts index a26749d2ae..a293aebaba 100644 --- a/packages/core/demo/data/gauge.ts +++ b/packages/core/demo/data/gauge.ts @@ -3,9 +3,7 @@ export const gaugeData = [ { group: "delta", value: -13.37 } ]; -export const gaugeDataNoDelta = [ - { group: "value", value: 67 } -]; +export const gaugeDataNoDelta = [{ group: "value", value: 67 }]; // guage no custom color export const gaugeOptionsSemi = { @@ -30,7 +28,6 @@ export const gaugeOptionsCircular = { } }; - // guage with custom color export const gaugeOptionsCircularNoDelta = { title: "Gauge circular without delta", @@ -41,7 +38,7 @@ export const gaugeOptionsCircularNoDelta = { }, color: { scale: { - "value": "#891EE8" + value: "#891EE8" } } }; diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index 7804788cad..17235a888a 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -1,7 +1,14 @@ // Internal Imports import { Component } from "../component"; import { DOMUtils } from "../../services"; -import { Roles, TooltipTypes, Events, GaugeTypes, Statuses, ArrowDirections } from "../../interfaces"; +import { + Roles, + TooltipTypes, + Events, + GaugeTypes, + Statuses, + ArrowDirections +} from "../../interfaces"; import { Tools } from "../../tools"; // D3 Imports @@ -62,7 +69,11 @@ export class Gauge extends Component { // use provided arrow direction or default to using the delta getArrow(delta): string { const options = this.model.getOptions(); - const arrowDirection = Tools.getProperty(options, "gauge", "arrowDirection"); + const arrowDirection = Tools.getProperty( + options, + "gauge", + "arrowDirection" + ); switch (arrowDirection) { case ArrowDirections.UP: @@ -70,11 +81,12 @@ export class Gauge extends Component { case ArrowDirections.DOWN: return ARROW_DOWN_PATH_STRING; default: - return delta > 0 ? ARROW_UP_PATH_STRING : ARROW_DOWN_PATH_STRING; + return delta > 0 + ? ARROW_UP_PATH_STRING + : ARROW_DOWN_PATH_STRING; } } - render(animate = true) { const self = this; const svg = this.getContainerSVG(); @@ -114,8 +126,7 @@ export class Gauge extends Component { .attr("role", Roles.GROUP); // Add data arc - const arcValue = svg.selectAll("path.arc-foreground") - .data([value]); + const arcValue = svg.selectAll("path.arc-foreground").data([value]); arcValue .enter() @@ -123,17 +134,14 @@ export class Gauge extends Component { .attr("class", "arc-foreground") .merge(arcValue) .attr("d", this.arc) - .attr("fill", d => self.model.getFillColor(d[groupMapsTo])) + .attr("fill", (d) => self.model.getFillColor(d[groupMapsTo])) // a11y .attr("role", Roles.GRAPHICS_SYMBOL) .attr("aria-roledescription", "value") - .attr("aria-label", d => d.value); + .attr("aria-label", (d) => d.value); // Position Arc - svg.attr( - "transform", - `translate(${radius}, ${radius})` - ); + svg.attr("transform", `translate(${radius}, ${radius})`); // draw the value and delta to the center this.drawValueNumber(); @@ -159,21 +167,29 @@ export class Gauge extends Component { // Sizing and positions relative to the radius const radius = this.computeRadius(); - const valueFontSize = Tools.getProperty(options, "gauge", "valueFontSize"); + const valueFontSize = Tools.getProperty( + options, + "gauge", + "valueFontSize" + ); // if there is a delta, use the size to center the numbers, otherwise center the valueNumber - const deltaFontSize = Tools.getProperty(options, "gauge", "deltaFontSize"); + const deltaFontSize = Tools.getProperty( + options, + "gauge", + "deltaFontSize" + ); // circular gauge without delta should have valueNumber centered let numbersYPosition = 0; if (arcType === GaugeTypes.FULL && !delta) { - numbersYPosition = deltaFontSize(radius); + numbersYPosition = deltaFontSize(radius); } // Add the numbers at the center - const numbersGroup = DOMUtils.appendOrSelect(svg, "g.gauge-numbers").attr( - "transform", - `translate(0, ${numbersYPosition})` - ); + const numbersGroup = DOMUtils.appendOrSelect( + svg, + "g.gauge-numbers" + ).attr("transform", `translate(0, ${numbersYPosition})`); // Add the big number const valueNumberGroup = DOMUtils.appendOrSelect( @@ -181,8 +197,13 @@ export class Gauge extends Component { "g.gauge-value-number" ).attr("transform", "translate(-10, 0)"); // Optical centering for the presence of the smaller % symbol - const numberFormatter = Tools.getProperty(options, "gauge", "numberFormatter"); - const valueNumber = valueNumberGroup.selectAll("text.gauge-value-number") + const numberFormatter = Tools.getProperty( + options, + "gauge", + "numberFormatter" + ); + const valueNumber = valueNumberGroup + .selectAll("text.gauge-value-number") .data([value]); valueNumber @@ -192,12 +213,15 @@ export class Gauge extends Component { .merge(valueNumber) .style("font-size", `${valueFontSize(radius)}px`) .attr("text-anchor", "middle") - .text(d => numberFormatter(d)); + .text((d) => numberFormatter(d)); // add the percentage symbol beside the valueNumber const { width: valueNumberWidth - } = DOMUtils.getSVGElementSize(DOMUtils.appendOrSelect(svg, "text.gauge-value-number"), { useBBox: true }); + } = DOMUtils.getSVGElementSize( + DOMUtils.appendOrSelect(svg, "text.gauge-value-number"), + { useBBox: true } + ); DOMUtils.appendOrSelect(valueNumberGroup, "text.gauge-value-symbol") .style("font-size", `${valueFontSize(radius) / 2}px`) @@ -216,10 +240,20 @@ export class Gauge extends Component { // Sizing and positions relative to the radius const radius = this.computeRadius(); - const deltaFontSize = delta ? Tools.getProperty(options, "gauge", "deltaFontSize") : () => 0; - const numberFormatter = Tools.getProperty(options, "gauge", "numberFormatter"); + const deltaFontSize = delta + ? Tools.getProperty(options, "gauge", "deltaFontSize") + : () => 0; + const numberFormatter = Tools.getProperty( + options, + "gauge", + "numberFormatter" + ); const arrowSize = Tools.getProperty(options, "gauge", "arrowSize"); - const numberKerning = Tools.getProperty(options, "gauge", "numberKerning"); + const numberKerning = Tools.getProperty( + options, + "gauge", + "numberKerning" + ); const numbersGroup = DOMUtils.appendOrSelect(svg, "g.gauge-numbers"); @@ -232,8 +266,9 @@ export class Gauge extends Component { `translate(0, ${deltaFontSize(radius) + numberKerning})` ); - const deltaNumber = deltaGroup.selectAll("text.gauge-delta-number") - .data(delta != null ? [delta] : []); + const deltaNumber = deltaGroup + .selectAll("text.gauge-delta-number") + .data(delta !== null ? [delta] : []); deltaNumber .enter() @@ -242,15 +277,19 @@ export class Gauge extends Component { .attr("class", "gauge-delta-number") .attr("text-anchor", "middle") .style("font-size", `${deltaFontSize(radius)}px`) - .text(d => `${numberFormatter(d)}%`); + .text((d) => `${numberFormatter(d)}%`); // Add the caret for the delta number const { width: deltaNumberWidth - } = DOMUtils.getSVGElementSize(DOMUtils.appendOrSelect(svg, "g.gauge-delta"), { useBBox: true }); + } = DOMUtils.getSVGElementSize( + DOMUtils.appendOrSelect(svg, "g.gauge-delta"), + { useBBox: true } + ); - const deltaArrow = deltaGroup.selectAll("svg.gauge-delta-arrow") - .data(delta != null ? [delta] : []); + const deltaArrow = deltaGroup + .selectAll("svg.gauge-delta-arrow") + .data(delta !== null ? [delta] : []); deltaArrow .enter() @@ -272,8 +311,8 @@ export class Gauge extends Component { // Draw the arrow with status const status = Tools.getProperty(options, "gauge", "status"); DOMUtils.appendOrSelect(deltaArrow, "polygon.gauge-delta-arrow-polygon") - .classed(`status--${status}`, status != null) - .attr("fill", () => status == null ? "currentColor" : null) + .classed(`status--${status}`, status !== null) + .attr("fill", () => (status == null ? "currentColor" : null)) .attr("points", self.getArrow(delta)); deltaArrow.exit().remove(); @@ -283,7 +322,11 @@ export class Gauge extends Component { getInnerRadius() { // Compute the outer radius needed const radius = this.computeRadius(); - const arcWidth = Tools.getProperty(this.model.getOptions(), "gauge", "arcWidth"); + const arcWidth = Tools.getProperty( + this.model.getOptions(), + "gauge", + "arcWidth" + ); return radius - arcWidth; } From 53ee90179786a31a472d90193e3c3862bcedd083 Mon Sep 17 00:00:00 2001 From: Natasha DeCoste Date: Fri, 19 Jun 2020 10:44:41 -0400 Subject: [PATCH 40/43] review changes --- packages/core/src/components/graphs/gauge.ts | 38 ++++++++++---------- packages/core/src/configuration.ts | 9 +++-- packages/core/src/interfaces/charts.ts | 11 +++--- packages/core/src/styles/graphs/_gauge.scss | 2 +- 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index 17235a888a..43c88b0483 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -3,10 +3,8 @@ import { Component } from "../component"; import { DOMUtils } from "../../services"; import { Roles, - TooltipTypes, Events, GaugeTypes, - Statuses, ArrowDirections } from "../../interfaces"; import { Tools } from "../../tools"; @@ -72,6 +70,7 @@ export class Gauge extends Component { const arrowDirection = Tools.getProperty( options, "gauge", + "deltaArrow", "arrowDirection" ); @@ -179,10 +178,19 @@ export class Gauge extends Component { "deltaFontSize" ); + const numberSpacing = Tools.getProperty( + options, + "gauge", + "numberSpacing" + ); + // circular gauge without delta should have valueNumber centered let numbersYPosition = 0; if (arcType === GaugeTypes.FULL && !delta) { numbersYPosition = deltaFontSize(radius); + } else if (arcType === GaugeTypes.SEMI && delta) { + // semi circular gauge we want the numbers aligned to the chart container + numbersYPosition = -(deltaFontSize(radius) + numberSpacing); } // Add the numbers at the center @@ -248,11 +256,12 @@ export class Gauge extends Component { "gauge", "numberFormatter" ); - const arrowSize = Tools.getProperty(options, "gauge", "arrowSize"); - const numberKerning = Tools.getProperty( + + const arrowSize = Tools.getProperty(options, "gauge", "deltaArrow", "arrowSize"); + const numberSpacing = Tools.getProperty( options, "gauge", - "numberKerning" + "numberSpacing" ); const numbersGroup = DOMUtils.appendOrSelect(svg, "g.gauge-numbers"); @@ -263,7 +272,7 @@ export class Gauge extends Component { "g.gauge-delta" ).attr( "transform", - `translate(0, ${deltaFontSize(radius) + numberKerning})` + `translate(0, ${deltaFontSize(radius) + numberSpacing})` ); const deltaNumber = deltaGroup @@ -287,9 +296,11 @@ export class Gauge extends Component { { useBBox: true } ); + // check if delta arrow is disabled + const arrowEnabled = Tools.getProperty(options, "gauge", "deltaArrow", "enabled"); const deltaArrow = deltaGroup .selectAll("svg.gauge-delta-arrow") - .data(delta !== null ? [delta] : []); + .data(delta !== null && arrowEnabled ? [delta] : []); deltaArrow .enter() @@ -310,7 +321,7 @@ export class Gauge extends Component { // Draw the arrow with status const status = Tools.getProperty(options, "gauge", "status"); - DOMUtils.appendOrSelect(deltaArrow, "polygon.gauge-delta-arrow-polygon") + DOMUtils.appendOrSelect(deltaArrow, "polygon.gauge-delta-arrow") .classed(`status--${status}`, status !== null) .attr("fill", () => (status == null ? "currentColor" : null)) .attr("points", self.getArrow(delta)); @@ -349,12 +360,6 @@ export class Gauge extends Component { element: hoveredElement, datum }); - - // Show tooltip - self.services.events.dispatchEvent(Events.Tooltip.SHOW, { - hoveredElement, - type: TooltipTypes.DATAPOINT - }); }) .on("click", function (datum) { // Dispatch mouse event @@ -371,11 +376,6 @@ export class Gauge extends Component { element: hoveredElement, datum }); - - // Hide tooltip - self.services.events.dispatchEvent(Events.Tooltip.HIDE, { - hoveredElement - }); }); } diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 349994f7a5..dbac5564c2 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -304,11 +304,14 @@ const gaugeChart: GaugeChartOptions = Tools.merge({}, chart, { gauge: { type: GaugeTypes.SEMI, arcWidth: 16, + deltaArrow: { + arrowSize: (radius) => radius / 8, + enabled: true + }, status: null, - numberKerning: 10, - valueFontSize: (radius) => radius / 2.5, + numberSpacing: 10, deltaFontSize: (radius) => radius / 8, - arrowSize: (radius) => radius / 8, + valueFontSize: (radius) => radius / 2.5, numberFormatter: (number) => (number.toFixed(2) % 1 !== 0) ? number.toFixed(2).toLocaleString() : number.toFixed().toLocaleString() } } as GaugeChartOptions); diff --git a/packages/core/src/interfaces/charts.ts b/packages/core/src/interfaces/charts.ts index 9856d93c97..3e73a62961 100644 --- a/packages/core/src/interfaces/charts.ts +++ b/packages/core/src/interfaces/charts.ts @@ -250,13 +250,16 @@ export interface PieChartOptions extends BaseChartOptions { export interface GaugeChartOptions extends PieChartOptions { gauge?: { arcWidth?: number; + deltaArrow?: { + arrowDirection?: ArrowDirections; + arrowSize?: Function; + enabled: Boolean; + } status?: Statuses; - arrowDirection?: ArrowDirections; + deltaFontSize?: Function; + numberSpacing?: number; numberFormatter?: Function; valueFontSize?: Function; - deltaFontSize?: Function; - arrowSize?: Function; - numberKerning?: number; type?: GaugeTypes; }; } diff --git a/packages/core/src/styles/graphs/_gauge.scss b/packages/core/src/styles/graphs/_gauge.scss index 670df43d9d..a920e8230f 100644 --- a/packages/core/src/styles/graphs/_gauge.scss +++ b/packages/core/src/styles/graphs/_gauge.scss @@ -3,7 +3,7 @@ fill: $ui-01; } - .gauge-delta-arrow-polygon { + .gauge-delta-arrow { &.status--danger { fill: $support-01; } From dea988e24b97ec59c029b0158113e2cba235c7dc Mon Sep 17 00:00:00 2001 From: Natasha DeCoste Date: Fri, 19 Jun 2020 13:42:56 -0400 Subject: [PATCH 41/43] update config names --- packages/core/src/components/graphs/gauge.ts | 4 ++-- packages/core/src/configuration.ts | 2 +- packages/core/src/interfaces/charts.ts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index 43c88b0483..cc9ef7bfdc 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -71,7 +71,7 @@ export class Gauge extends Component { options, "gauge", "deltaArrow", - "arrowDirection" + "direction" ); switch (arrowDirection) { @@ -257,7 +257,7 @@ export class Gauge extends Component { "numberFormatter" ); - const arrowSize = Tools.getProperty(options, "gauge", "deltaArrow", "arrowSize"); + const arrowSize = Tools.getProperty(options, "gauge", "deltaArrow", "size"); const numberSpacing = Tools.getProperty( options, "gauge", diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index dbac5564c2..81007bb716 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -305,7 +305,7 @@ const gaugeChart: GaugeChartOptions = Tools.merge({}, chart, { type: GaugeTypes.SEMI, arcWidth: 16, deltaArrow: { - arrowSize: (radius) => radius / 8, + size: (radius) => radius / 8, enabled: true }, status: null, diff --git a/packages/core/src/interfaces/charts.ts b/packages/core/src/interfaces/charts.ts index 3e73a62961..b884985b64 100644 --- a/packages/core/src/interfaces/charts.ts +++ b/packages/core/src/interfaces/charts.ts @@ -251,8 +251,8 @@ export interface GaugeChartOptions extends PieChartOptions { gauge?: { arcWidth?: number; deltaArrow?: { - arrowDirection?: ArrowDirections; - arrowSize?: Function; + direction?: ArrowDirections; + size?: Function; enabled: Boolean; } status?: Statuses; From 298712601e9bc02c470025dc878a1e232075d2da Mon Sep 17 00:00:00 2001 From: Natasha DeCoste Date: Tue, 23 Jun 2020 10:49:03 -0400 Subject: [PATCH 42/43] feat(gauge chart): add gauge chart to carbon-charts re #554 --- packages/core/src/components/graphs/gauge.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index cc9ef7bfdc..a1a812e18a 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -292,7 +292,7 @@ export class Gauge extends Component { const { width: deltaNumberWidth } = DOMUtils.getSVGElementSize( - DOMUtils.appendOrSelect(svg, "g.gauge-delta"), + DOMUtils.appendOrSelect(svg, ".gauge-delta-number"), { useBBox: true } ); From 5d53c40e00731073967806910687d6674362d6e2 Mon Sep 17 00:00:00 2001 From: Natasha DeCoste Date: Tue, 23 Jun 2020 10:49:19 -0400 Subject: [PATCH 43/43] review changes --- packages/core/src/components/graphs/gauge.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/components/graphs/gauge.ts b/packages/core/src/components/graphs/gauge.ts index a1a812e18a..ae64bb4758 100644 --- a/packages/core/src/components/graphs/gauge.ts +++ b/packages/core/src/components/graphs/gauge.ts @@ -323,7 +323,7 @@ export class Gauge extends Component { const status = Tools.getProperty(options, "gauge", "status"); DOMUtils.appendOrSelect(deltaArrow, "polygon.gauge-delta-arrow") .classed(`status--${status}`, status !== null) - .attr("fill", () => (status == null ? "currentColor" : null)) + .attr("fill", () => (status === null ? "currentColor" : null)) .attr("points", self.getArrow(delta)); deltaArrow.exit().remove();