UNPKG

@allurereport/web-allure2

Version:

The static files for Allure Classic Report

203 lines (176 loc) 5.57 kB
import { max } from "d3-array"; import { scaleLinear, scalePoint } from "d3-scale"; import { scaleOrdinal } from "d3-scale"; import { schemeCategory10 } from "d3-scale-chromatic"; import { area, line, stack } from "d3-shape"; import BaseChartView from "@/components/graph-base/BaseChartView.js"; import TooltipView from "@/components/tooltip/TooltipView.js"; import translate from "@/helpers/t.js"; import "./styles.scss"; import trendTooltip from "./trend-tooltip.hbs"; class TrendChartView extends BaseChartView { PAD_BOTTOM = 50; initialize(options) { this.x = scalePoint(); this.y = scaleLinear(); this.tooltip = new TooltipView({ position: "top" }); this.keys = options.keys || this.model.keys(); this.stack = stack() .keys(this.keys) .value((d, key) => d.data[key] || 0); this.color = options.colors || scaleOrdinal(schemeCategory10); options.notStacked && this.stack.offset(() => {}); this.yTickFormat = options.yTickFormat || ((d) => d); } onAttach() { const data = this.model.toJSON(); if (data && data.length > 1) { this.doShow(data); } else { this.$el.html(`<div class="widget__noitems">${translate("chart.trend.empty")}</div>`); } super.onAttach(); } doShow(data) { this.setupViewport(); this.x.range([0, this.width]); this.y.range([this.height, 0]); this.x.domain(data.map((d) => d.id)); this.y.domain([0, max(data, (d) => d.total)]).nice(); const trendStack = this.stack(data); this.makeBottomAxis({ scale: this.x, tickFormat: (d, i) => data[i].name, }); this.makeLeftAxis({ scale: this.y, tickFormat: this.yTickFormat, }); if (document.dir === "rtl") { this.svg.selectAll(".chart__axis_x").selectAll("text").style("text-anchor", "start"); } else { this.svg.selectAll(".chart__axis_x").selectAll("text").style("text-anchor", "end"); } this.svg .selectAll(".chart__axis_x") .selectAll("text") .attr("dx", "-.8em") .attr("dy", "-.6em") .attr("transform", "rotate(-90)"); this.options.hideAreas || this.showAreas(trendStack); this.options.hideLines || this.showLines(trendStack); this.options.hidePoints || this.showPoints(trendStack); this.showSlices(data); } showAreas(trendStack) { const trendArea = area() .x((d) => this.x(d.data.id)) .y0((d) => this.y(d[0])) .y1((d) => this.y(d[1])); this.plot .selectAll(".trend__area") .data(trendStack) .enter() .append("path") .attr("class", "trend__area") .attr("d", trendArea) .style("fill", (d) => this.color(d.key)) .style("opacity", 0.85); } showLines(trendStack) { const trendLine = line() .x((d) => this.x(d.data.id)) .y((d) => this.y(d[1])); this.plot .selectAll(".trend__line") .data(trendStack) .enter() .append("path") .attr("class", ".trend__line") .attr("d", trendLine) .style("stroke-width", 2) .style("stroke", (d) => this.color(d.key)); } showPoints(trendStack) { const points = this.plot .selectAll(".trend_points") .data(trendStack) .enter() .append("g") .attr("class", ".trend_point") .style("fill", (d) => this.color(d.key)); points .selectAll(".trend_point") .data((d) => d) .enter() .append("circle") .attr("r", 2) .attr("cx", (d) => this.x(d.data.id)) .attr("cy", (d) => this.y(d[1])) .attr("class", "trend_point"); } showSlices(data) { this.plot.selectAll(".slice").data(data).enter().append("g").attr("class", "slice"); this.plot .selectAll(".slice") .filter((d) => d.reportUrl) .append("a") .attr("class", "edge") .filter((d) => d.reportUrl) .attr("xlink:href", (d) => d.reportUrl); this.plot .selectAll(".slice") .filter((d) => !d.reportUrl) .append("g") .attr("class", "edge"); this.plot .selectAll(".edge") .append("line") .attr("id", (d) => d.id) .attr("x1", (d) => this.x(d.id)) .attr("y1", (d) => this.y(d.total)) .attr("x2", (d) => this.x(d.id)) .attr("y2", this.y(0)) .attr("stroke", "white") .attr("stroke-width", 1) .attr("class", "report-line"); this.plot .selectAll(".edge") .append("rect") .style("opacity", 0.0) .attr("class", "report-edge") .attr("x", (d, i) => (i > 0 ? this.x(d.id) - this.x.step() / 2 : 0)) .attr("y", 0) .attr("height", this.height) .attr("width", (d, i) => (i === 0 || this.x(d.id) === this.width ? this.x.step() / 2 : this.x.step())) .on("mouseover", (event, d) => { const anchor = this.plot .append("circle") .attr("class", "anchor") .attr("cx", `${this.x(d.id)}`) .attr("cy", `${this.y(d.total / 2)}`); this.showTooltip(d, anchor.node()); }) .on("mouseout", () => { this.plot.selectAll(".anchor").remove(); this.hideTooltip(); }); } getTooltipContent(selectedData) { const tooltipData = { ...selectedData, data: this.keys .map((key) => { return { key, num: this.yTickFormat(selectedData.data[key]), color: this.color(key), }; }) .filter((item) => !!item.num) .reverse(), }; return trendTooltip(tooltipData); } } export default TrendChartView;